Skip to content

Commit

Permalink
feat: rewrite in TS, start using named exports
Browse files Browse the repository at this point in the history
BREAKING CHANGE: previously: "import isOpening from ..." - now "import { isOpening } from ..."
  • Loading branch information
revelt committed Dec 31, 2020
1 parent 6a8cf5a commit 7842225
Show file tree
Hide file tree
Showing 37 changed files with 2,734 additions and 2,626 deletions.
3 changes: 2 additions & 1 deletion packages/is-html-tag-opening/.npmignore
@@ -1,4 +1,4 @@
# .... generated using www.npmjs.com/package/lect ....
# generated using codsen.com/os/lect
#
#
# __ ______ ______ ______
Expand All @@ -23,3 +23,4 @@ test
.prettierignore
rollup.config.js
testStats.md
tsconfig.json
2 changes: 1 addition & 1 deletion packages/is-html-tag-opening/README.md
Expand Up @@ -34,7 +34,7 @@ npm i is-html-tag-opening

```js
import { strict as assert } from "assert";
import isOpening from "dist/is-html-tag-opening.esm";
import { isOpening } from "dist/is-html-tag-opening.esm";

const text = `<span>a < b<span>`;

Expand Down
@@ -1 +1 @@
{"total":{"lines":{"total":60,"covered":55,"skipped":0,"pct":91.67},"statements":{"total":60,"covered":55,"skipped":0,"pct":91.67},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"branches":{"total":105,"covered":96,"skipped":0,"pct":91.43}}}
{"total":{"lines":{"total":58,"covered":53,"skipped":0,"pct":91.38},"statements":{"total":58,"covered":53,"skipped":0,"pct":91.38},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"branches":{"total":105,"covered":96,"skipped":0,"pct":91.43}}}
161 changes: 73 additions & 88 deletions packages/is-html-tag-opening/dist/is-html-tag-opening.cjs.js
Expand Up @@ -9,121 +9,98 @@

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
var stringMatchLeftRight = require('string-match-left-right');
var stringLeftRight = require('string-left-right');

function _typeof(obj) {
"@babel/helpers - typeof";

if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}

return _typeof(obj);
}

function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}

return obj;
}

function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}

return keys;
}

function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};

if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}

return target;
}
var _objectSpread__default = /*#__PURE__*/_interopDefaultLegacy(_objectSpread);

var defaultOpts = {
allowCustomTagNames: false,
skipOpeningBracket: false
};
var BACKSLASH = "\\";
var knownHtmlTags = ["a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "doctype",
"dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "h1", "h1 - h6", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "math", "menu", "menuitem", "meta", "meter", "nav", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "slot", "small", "source", "span", "strike", "strong", "style", "sub", "summary", "sup", "svg", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xml"];
var knownHtmlTags = ["a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "doctype", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "h1", "h1 - h6", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "math", "menu", "menuitem", "meta", "meter", "nav", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "slot", "small", "source", "span", "strike", "strong", "style", "sub", "summary", "sup", "svg", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xml"];

function isNotLetter(char) {
return char === undefined || char.toUpperCase() === char.toLowerCase() && !/\d/.test(char) && char !== "=";
}

function extraRequirements(str, idx) {
return str[idx] === "<" ||
str[stringLeftRight.left(str, idx)] === "<";
// either it's opening bracket
return str[idx] === "<" || // or there's one opening bracket to the left
str[stringLeftRight.left(str, idx)] === "<"; // TODO: consider adding clauses for br/> -
// slash-closing follows, but no opening
}

function isOpening(str) {
var idx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var originalOpts = arguments.length > 2 ? arguments[2] : undefined;
var version = "1.10.1";

function isOpening(str, idx, originalOpts) {
if (idx === void 0) {
idx = 0;
}

// -----------------------------------------------------------------------------

if (typeof str !== "string") {
throw new Error("is-html-tag-opening: [THROW_ID_01] the first input argument should have been a string but it was given as \"".concat(_typeof(str), "\", value being ").concat(JSON.stringify(str, null, 4)));
throw new Error("is-html-tag-opening: [THROW_ID_01] the first input argument should have been a string but it was given as \"" + typeof str + "\", value being " + JSON.stringify(str, null, 4));
}

if (!Number.isInteger(idx) || idx < 0) {
throw new Error("is-html-tag-opening: [THROW_ID_02] the second input argument should have been a natural number string index but it was given as \"".concat(_typeof(idx), "\", value being ").concat(JSON.stringify(idx, null, 4)));
throw new Error("is-html-tag-opening: [THROW_ID_02] the second input argument should have been a natural number string index but it was given as \"" + typeof idx + "\", value being " + JSON.stringify(idx, null, 4));
}
var opts = _objectSpread2(_objectSpread2({}, defaultOpts), originalOpts);
var whitespaceChunk = "[\\\\ \\t\\r\\n/]*";
var generalChar = "._a-z0-9\xB7\xC0-\xD6\xD8-\xF6\xF8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\uFFFF";
var r1 = new RegExp("^<".concat(opts.skipOpeningBracket ? "?" : "").concat(whitespaceChunk, "\\w+").concat(whitespaceChunk, "\\/?").concat(whitespaceChunk, ">"), "g");
var r5 = new RegExp("^<".concat(opts.skipOpeningBracket ? "?" : "").concat(whitespaceChunk, "[").concat(generalChar, "]+[-").concat(generalChar, "]*").concat(whitespaceChunk, ">"), "g");
var r2 = new RegExp("^<".concat(opts.skipOpeningBracket ? "?" : "", "\\s*\\w+\\s+\\w+(?:-\\w+)?\\s*=\\s*['\"\\w]"), "g");
var r6 = new RegExp("^<".concat(opts.skipOpeningBracket ? "?" : "", "\\s*\\w+\\s+[").concat(generalChar, "]+[-").concat(generalChar, "]*(?:-\\w+)?\\s*=\\s*['\"\\w]"));
var r3 = new RegExp("^<".concat(opts.skipOpeningBracket ? "?" : "", "\\s*\\/?\\s*\\w+\\s*\\/?\\s*>"), "g");
var r7 = new RegExp("^<".concat(opts.skipOpeningBracket ? "?" : "", "\\s*\\/?\\s*[").concat(generalChar, "]+[-").concat(generalChar, "]*\\s*\\/?\\s*>"), "g");
var r4 = new RegExp("^<".concat(opts.skipOpeningBracket ? "?" : "").concat(whitespaceChunk, "\\w+(?:\\s*\\w+)?\\s*\\w+=['\"]"), "g");
var r8 = new RegExp("^<".concat(opts.skipOpeningBracket ? "?" : "").concat(whitespaceChunk, "[").concat(generalChar, "]+[-").concat(generalChar, "]*\\s+(?:\\s*\\w+)?\\s*\\w+=['\"]"), "g");
var r9 = new RegExp("^<".concat(opts.skipOpeningBracket ? "?\\/?" : "", "(").concat(whitespaceChunk, "[").concat(generalChar, "]+)+").concat(whitespaceChunk, "[\\\\/=>]"), "");

var opts = _objectSpread__default['default'](_objectSpread__default['default']({}, defaultOpts), originalOpts); // -----------------------------------------------------------------------------
var whitespaceChunk = "[\\\\ \\t\\r\\n/]*"; // generalChar does not include the dash, -

var generalChar = "._a-z0-9\xB7\xC0-\xD6\xD8-\xF6\xF8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\uFFFF"; // =======
// r1. tag without attributes
// for example <br>, <br/>

var r1 = new RegExp("^<" + (opts.skipOpeningBracket ? "?" : "") + whitespaceChunk + "\\w+" + whitespaceChunk + "\\/?" + whitespaceChunk + ">", "g"); // its custom-html tag version:

var r5 = new RegExp("^<" + (opts.skipOpeningBracket ? "?" : "") + whitespaceChunk + "[" + generalChar + "]+[-" + generalChar + "]*" + whitespaceChunk + ">", "g"); // to anybody who wonders, the \u2070-\uFFFF covers all the surrogates
// of which emoji can be assembled. This is a very rough match, aiming to
// catch as much as possible, not the validation-level match.
// If you put bunch of opening surrogates in a sequence, for example,
// this program would still match them positively. It's to catch all emoji,
// including future, new-fangled emoji.
// =======
// r2. tag with one healthy attribute (no closing slash or whatever follow afterwards is matched)

var r2 = new RegExp("^<" + (opts.skipOpeningBracket ? "?" : "") + "\\s*\\w+\\s+\\w+(?:-\\w+)?\\s*=\\s*['\"\\w]", "g"); // its custom-html tag version:

var r6 = new RegExp("^<" + (opts.skipOpeningBracket ? "?" : "") + "\\s*\\w+\\s+[" + generalChar + "]+[-" + generalChar + "]*(?:-\\w+)?\\s*=\\s*['\"\\w]"); // =======
// r3. closing/self-closing tags

var r3 = new RegExp("^<" + (opts.skipOpeningBracket ? "?" : "") + "\\s*\\/?\\s*\\w+\\s*\\/?\\s*>", "g"); // its custom-html tag version:

var r7 = new RegExp("^<" + (opts.skipOpeningBracket ? "?" : "") + "\\s*\\/?\\s*[" + generalChar + "]+[-" + generalChar + "]*\\s*\\/?\\s*>", "g"); // =======
// r4. opening tag with attributes,

var r4 = new RegExp("^<" + (opts.skipOpeningBracket ? "?" : "") + whitespaceChunk + "\\w+(?:\\s*\\w+)?\\s*\\w+=['\"]", "g"); // its custom-html tag version:

var r8 = new RegExp("^<" + (opts.skipOpeningBracket ? "?" : "") + whitespaceChunk + "[" + generalChar + "]+[-" + generalChar + "]*\\s+(?:\\s*\\w+)?\\s*\\w+=['\"]", "g"); // =======
// lesser requirements when opening bracket precedes index "idx"

var r9 = new RegExp("^<" + (opts.skipOpeningBracket ? "?\\/?" : "") + "(" + whitespaceChunk + "[" + generalChar + "]+)+" + whitespaceChunk + "[\\\\/=>]", ""); // =======

var whatToTest = idx ? str.slice(idx) : str;
var qualified = false;
var passed = false;
var passed = false; // if the result is still falsey, we match against the known HTML tag names list

var matchingOptions = {
cb: isNotLetter,
i: true,
trimCharsBeforeMatching: ["/", BACKSLASH, "!", " ", "\t", "\n", "\r"]
};
}; // -----------------------------------------------------------------------------

if (opts.allowCustomTagNames) {

if ((opts.skipOpeningBracket && (str[idx - 1] === "<" || str[idx - 1] === "/" && str[stringLeftRight.left(str, stringLeftRight.left(str, idx))] === "<") || whatToTest[0] === "<" && whatToTest[1] && whatToTest[1].trim()) && (r9.test(whatToTest) || /^<\w+$/.test(whatToTest))) {
passed = true;
} else if (r5.test(whatToTest) && extraRequirements(str, idx)) {
Expand All @@ -136,6 +113,7 @@ function isOpening(str) {
passed = true;
}
} else {

if ((opts.skipOpeningBracket && (str[idx - 1] === "<" || str[idx - 1] === "/" && str[stringLeftRight.left(str, stringLeftRight.left(str, idx))] === "<") || whatToTest[0] === "<" && whatToTest[1] && whatToTest[1].trim()) && r9.test(whatToTest)) {
qualified = true;
} else if (r1.test(whatToTest) && extraRequirements(str, idx)) {
Expand All @@ -147,14 +125,18 @@ function isOpening(str) {
} else if (r4.test(whatToTest)) {
qualified = true;
}

if (qualified && stringMatchLeftRight.matchRightIncl(str, idx, knownHtmlTags, {
cb: function cb(char) {
if (char === undefined) {

if (str[idx] === "<" && str[idx + 1] && str[idx + 1].trim() || str[idx - 1] === "<") {
passed = true;
}

return true;
}

return char.toUpperCase() === char.toLowerCase() && !/\d/.test(char) && char !== "=";
},
i: true,
Expand All @@ -163,11 +145,14 @@ function isOpening(str) {
passed = true;
}
}

if (!passed && str[idx] === "<" && str[idx + 1] && str[idx + 1].trim() && stringMatchLeftRight.matchRight(str, idx, knownHtmlTags, matchingOptions)) {
passed = true;
}
} //
var res = typeof str === "string" && idx < str.length && passed;
return res;
}

module.exports = isOpening;
exports.defaults = defaultOpts;
exports.isOpening = isOpening;
exports.version = version;

0 comments on commit 7842225

Please sign in to comment.