@@ -4930,25 +4930,10 @@ const _closeTagOf = (n) => {
49304930const _startOf = (n) => (n < 0 ? _attrNameStarts[-n] : _nodeStarts[n]);
49314931/** @type {(n: HtmlNodeRef) => number} where a node or attribute ends */
49324932const _endOf = (n) => (n < 0 ? _attrEnd(-n) : _nodeEnds[n]);
4933- /** @type {(n: HtmlNodeRef) => number} where a tag or attribute name starts (0 for a parser-inserted tag) */
4934- const _nameStartOf = (n) => {
4935- if (n < 0) return _attrNameStarts[-n];
4936- return _nodeNameEnds[n] === 0 ? 0 : _nodeStarts[n] + 1;
4937- };
49384933/** @type {(n: HtmlNodeRef) => number} where a tag or attribute name ends (0 for a parser-inserted tag) */
49394934const _nameEndOf = (n) => (n < 0 ? _attrNameEnds[-n] : _nodeNameEnds[n]);
4940- /** @type {(a: HtmlAttributeRef) => number} where an attribute's value starts (-1 without one) */
4941- const _valueStartOf = (a) => (a < 0 ? _attrValueStarts[-a] : -1);
4942- /** @type {(a: HtmlAttributeRef) => number} where an attribute's value ends (-1 without one) */
4943- const _valueEndOf = (a) =>
4944- a < 0 && _attrValueStarts[-a] !== -1 ? _attrValueEnds[-a] : -1;
49454935/** @type {(n: HtmlNodeRef) => number} where an element's opening tag ends */
49464936const _contentStartOf = (n) => _nodeTagEnds[n];
4947- /** @type {(n: HtmlNodeRef) => number} under `skip.text`, where a raw-text element's body ends (`tagEnd` when empty) */
4948- const _contentEndOf = (n) =>
4949- (_S._nodeFlags[n] & FLAG_HAS_TEMPLATE) !== 0
4950- ? _nodeTagEnds[n]
4951- : _nodeContentEnds[n];
49524937
49534938/** @type {(n: HtmlNodeRef) => number} how many attributes an element has */
49544939const _attributeCountOf = (n) => _nodeAttrCounts[n];
@@ -4960,9 +4945,6 @@ const _attributeAt = (i, n) => _nodeAttrStarts[n] + i;
49604945const _findAttribute = (name, n) =>
49614946 _findAttr(_nodeAttrStarts[n], _nodeAttrCounts[n], name);
49624947
4963- /** @type {(a: number) => string} an attribute's value as written, by its path id */
4964- const _attrRawValue = (a) => _attrValueOf(-a);
4965-
49664948/** @type {(i: number) => string} an attribute's name */
49674949const _attrNameOf = (i) => _attrNames[i];
49684950
@@ -5579,7 +5561,7 @@ const internLowerName = (table, input, start, end) => {
55795561 table.noted[memoSlot] = 1;
55805562 table.sourceBacked.push(memoSlot);
55815563 }
5582- return (memo[memoSlot] = _asciiLowerCase (input.slice(start, end)));
5564+ return (memo[memoSlot] = asciiLowercase (input.slice(start, end)));
55835565};
55845566
55855567// Every tag name the tree builder compares against (the sets above already
@@ -8389,7 +8371,7 @@ const handleDoctypeToken = (
83898371 tok.name =
83908372 nameStart === -1
83918373 ? ""
8392- : _asciiLowerCase (doctypePart(input, nameStart, nameEnd));
8374+ : asciiLowercase (doctypePart(input, nameStart, nameEnd));
83938375 tok.publicId =
83948376 publicStart === -1 ? null : doctypePart(input, publicStart, publicEnd);
83958377 tok.systemId =
@@ -9977,14 +9959,12 @@ const _minifyStyleAttribute = (raw) => {
99779959};
99789960
99799961/**
9980- * Trim ASCII whitespace, which is all these grammars skip — `String#trim` also
9981- * eats NBSP and the other Unicode spaces, which they read as ordinary
9982- * characters (a leading NBSP makes an integer unparsable, and is a class token
9983- * of its own).
9962+ * Infra's strip leading and trailing ASCII whitespace: `String#trim` also eats
9963+ * NBSP and the other Unicode spaces, which HTML's grammars read as characters.
99849964 * @param {string} value the value
99859965 * @returns {string} the trimmed value
99869966 */
9987- const _asciiTrim = (value) => {
9967+ const stripAsciiWhitespace = (value) => {
99889968 let start = 0;
99899969 let end = value.length;
99909970 while (start < end && isAsciiWhitespace(value.charCodeAt(start))) start++;
@@ -10000,7 +9980,7 @@ const _asciiTrim = (value) => {
100009980 * @returns {string} the normalized list
100019981 */
100029982const _normalizeViewport = (raw) =>
10003- _asciiTrim (raw)
9983+ stripAsciiWhitespace (raw)
100049984 .replace(/[\t\n\f\r ]*([,;=])[\t\n\f\r ]*/g, "$1")
100059985 .replace(/[\t\n\f\r ]+/g, " ");
100069986
@@ -10055,8 +10035,10 @@ const _minimalAttributeValue = (value) => {
1005510035const _isRedundantAttribute = (markers, defaults, tagName, name, value) => {
1005610036 // Looked up by what the value says, not how it was spelled — guarded on the
1005710037 // `&` so a value carrying no reference pays nothing.
10058- const lowered = _asciiLowerCase(
10059- _asciiTrim(value.includes("&") ? decodeEntities(value, true) : value)
10038+ const lowered = asciiLowercase(
10039+ stripAsciiWhitespace(
10040+ value.includes("&") ? decodeEntities(value, true) : value
10041+ )
1006010042 );
1006110043 // `<script type>`: only a spelling that names JavaScript, which is what the
1006210044 // element already runs. `module` and the empty spelling say something.
@@ -10093,9 +10075,11 @@ const _isRemovableEmptyAttribute = (elementName, name, value) => {
1009310075 if (on === undefined || (on !== null && !on.has(elementName))) return false;
1009410076 // Read decoded: a reference is how a value is spelled, not what it says, and
1009510077 // the tokenizer hands the element the same empty either way. Guarded on the
10096- // `&`, and `_asciiTrim ` returns the input when there is nothing to trim.
10078+ // `&`, and `stripAsciiWhitespace ` returns the input when there is nothing to trim.
1009710079 return (
10098- _asciiTrim(value.includes("&") ? decodeEntities(value, true) : value) === ""
10080+ stripAsciiWhitespace(
10081+ value.includes("&") ? decodeEntities(value, true) : value
10082+ ) === ""
1009910083 );
1010010084};
1010110085
@@ -10137,8 +10121,8 @@ const _isCssStyleElement = (path, element) => {
1013710121 // Read the way `_scriptType` reads its own: the value the spec matches is
1013810122 // the one the parser read, so a reference is decoded first.
1013910123 const raw = attribute.value;
10140- const value = _asciiLowerCase (
10141- _asciiTrim (raw.includes("&") ? decodeEntities(raw, true) : raw)
10124+ const value = asciiLowercase (
10125+ stripAsciiWhitespace (raw.includes("&") ? decodeEntities(raw, true) : raw)
1014210126 );
1014310127 return value === "" || value === "text/css";
1014410128 }
@@ -10704,7 +10688,7 @@ const _attributeDataUrl = (tagName, name, value) => {
1070410688 if (elements === undefined || (elements !== null && !elements.has(tagName))) {
1070510689 return null;
1070610690 }
10707- const url = _asciiTrim (value);
10691+ const url = stripAsciiWhitespace (value);
1070810692 // The URL parser drops every tab and newline, so a payload holding one is
1070910693 // not the text the browser reads.
1071010694 if ((url.charCodeAt(0) | 0x20) !== 0x64 || /[\t\n\r]/.test(url)) return null;
@@ -10835,7 +10819,9 @@ const _normalizeTokenList = (raw, isSet, sort) => {
1083510819 }
1083610820 if (!dirty && tokenStart === -1 && length !== 0) dirty = true;
1083710821 if (!dirty && count === 0) return raw;
10838- const collapsed = dirty ? _asciiTrim(raw).replace(/[\t\n\f\r ]+/g, " ") : raw;
10822+ const collapsed = dirty
10823+ ? stripAsciiWhitespace(raw).replace(/[\t\n\f\r ]+/g, " ")
10824+ : raw;
1083910825 if (dirty && !collapsed.includes(" ")) return collapsed;
1084010826 if (!isSet) return collapsed;
1084110827 // Cutting the list into tokens is the allocation this runs often enough to
@@ -10941,7 +10927,7 @@ const _sortedTokenList = (collapsed) => {
1094110927const _normalizeCommaList = (raw) =>
1094210928 raw
1094310929 .split(",")
10944- .map((item) => _asciiTrim (item))
10930+ .map((item) => stripAsciiWhitespace (item))
1094510931 .join(",");
1094610932
1094710933/**
@@ -10955,7 +10941,7 @@ const _normalizeCommaList = (raw) =>
1095510941 * @returns {string} the normalized integer
1095610942 */
1095710943const _normalizeInteger = (raw, signed) => {
10958- const value = _asciiTrim (raw);
10944+ const value = stripAsciiWhitespace (raw);
1095910945 if (!(signed ? /^[+-]?\d+$/ : /^\d+$/).test(value)) return raw;
1096010946 const negative = value.charCodeAt(0) === 0x2d;
1096110947 const digits = value.replace(/^[+-]/, "").replace(/^0+(?=\d)/, "");
@@ -10993,7 +10979,7 @@ const _rewriteAttributeValue = (element, name, raw, viewport, enumeratedOn) => {
1099310979 // Case-insensitively, and nothing else: an enumerated attribute names a
1099410980 // keyword, so `type="time "` is not `time` — it is the value no keyword
1099510981 // matches, which puts the input in its default state.
10996- const lowered = _asciiLowerCase (raw);
10982+ const lowered = asciiLowercase (raw);
1099710983 // A value the spec does not enumerate is left exactly as written:
1099810984 // `target` names a browsing context, and `type` on a custom element
1099910985 // means what it says.
@@ -11029,7 +11015,7 @@ const _rewriteAttributeValue = (element, name, raw, viewport, enumeratedOn) => {
1102911015 ? URL_ATTRIBUTES.get(name)
1103011016 : undefined;
1103111017 if (urlOn !== undefined && (urlOn === null || urlOn.has(element))) {
11032- return _asciiTrim (raw);
11018+ return stripAsciiWhitespace (raw);
1103311019 }
1103411020 const integerOn = _transforms.normalizeNumericAttributes
1103511021 ? INTEGER_ATTRIBUTES.get(name)
@@ -11054,8 +11040,10 @@ const _isViewportMeta = (path) => {
1105411040 if (attribute.name === "name") {
1105511041 const value = attribute.value;
1105611042 return (
11057- _asciiLowerCase(
11058- _asciiTrim(value.includes("&") ? decodeEntities(value, true) : value)
11043+ asciiLowercase(
11044+ stripAsciiWhitespace(
11045+ value.includes("&") ? decodeEntities(value, true) : value
11046+ )
1105911047 ) === "viewport"
1106011048 );
1106111049 }
@@ -11088,7 +11076,7 @@ const _normalizeSrcset = (raw) => {
1108811076 let descriptor = raw.slice(end, nextStart);
1108911077 const comma = descriptor.indexOf(",");
1109011078 if (comma !== -1) descriptor = descriptor.slice(0, comma);
11091- descriptor = _asciiTrim (descriptor).replace(/[\t\n\f\r ]+/g, " ");
11079+ descriptor = stripAsciiWhitespace (descriptor).replace(/[\t\n\f\r ]+/g, " ");
1109211080 // A descriptor-less URL runs to the next whitespace, so without one it
1109311081 // would swallow the separating comma and the URL behind it.
1109411082 if (i !== 0) out += previousBare ? ", " : ",";
@@ -11099,13 +11087,13 @@ const _normalizeSrcset = (raw) => {
1109911087};
1110011088
1110111089/**
11102- * ASCII-lowercase a name or a keyword value , which is all HTML folds — a Unicode
11103- * `toLowerCase` maps characters the parser leaves alone (U+212A onto `k`).
11104- * Returns the input untouched when there is nothing to fold (the common case) .
11090+ * Infra's ASCII lowercase , which is all HTML folds: `toLowerCase` also maps
11091+ * characters the parser leaves alone (U+212A onto `k`). Returns the input
11092+ * itself when there is nothing to fold.
1110511093 * @param {string} value source name or value
1110611094 * @returns {string} the value as the parser would match it
1110711095 */
11108- const _asciiLowerCase = (value) => {
11096+ const asciiLowercase = (value) => {
1110911097 for (let i = 0; i < value.length; i++) {
1111011098 const c = value.charCodeAt(i);
1111111099 if (c >= 0x41 && c <= 0x5a) {
@@ -11410,7 +11398,7 @@ const _minifyOpenTag = (path, open) => {
1141011398 if (!folds) return open;
1141111399 }
1141211400 const sourceName = open.slice(1, nameEnd);
11413- const elementName = html ? _asciiLowerCase (sourceName) : sourceName;
11401+ const elementName = html ? asciiLowercase (sourceName) : sourceName;
1141411402 let out = `<${elementName}`;
1141511403 const isViewportMeta =
1141611404 html && _nodeStrings[node] === "meta" && _isViewportMeta(path);
@@ -11638,7 +11626,7 @@ const _minifyOpenTag = (path, open) => {
1163811626 _transforms.collapseBooleanAttributes &&
1163911627 (_transforms.collapseBooleanAttributes === "all" ||
1164011628 (presence.length === attributeName.length &&
11641- _asciiLowerCase (presence) === attributeName)) &&
11629+ asciiLowercase (presence) === attributeName)) &&
1164211630 _isBooleanAttribute(elementName, attributeName)))
1164311631 ) {
1164411632 out += ` ${attributeName}`;
@@ -11685,7 +11673,7 @@ const _minifyOpenTag = (path, open) => {
1168511673 : rawValue
1168611674 : null;
1168711675
11688- if (handler !== null && _asciiTrim (handler) !== "") {
11676+ if (handler !== null && stripAsciiWhitespace (handler) !== "") {
1168911677 const delimiter = sourceDelimiter;
1169011678 // A foreign `/>` reads back whether this value ends unquoted, which a
1169111679 // deferred answer is not there to decide: the source's quoting stands.
@@ -12086,7 +12074,7 @@ const _elementCloseTag = (path, name, open, innerEmpty, minify) => {
1208612074 ) {
1208712075 return `</${name}>`;
1208812076 }
12089- return `</${_asciiLowerCase (_closeTagOf(path.node).slice(2, -1)).trim() || name}>`;
12077+ return `</${asciiLowercase (_closeTagOf(path.node).slice(2, -1)).trim() || name}>`;
1209012078 }
1209112079 const sourceClose = _closeTagOf(path.node);
1209212080 return sourceClose === "" ? `</${name}>` : sourceClose;
@@ -12392,7 +12380,7 @@ const _isHiddenInput = (path, node) => {
1239212380 for (let i = 0, n = _attributeCountOf(node); i < n; i++) {
1239312381 const a = _attributeAt(i, node);
1239412382 if (_attrNameOf(a) === "type") {
12395- return _asciiLowerCase (_attrValueOf(a)) === "hidden";
12383+ return asciiLowercase (_attrValueOf(a)) === "hidden";
1239612384 }
1239712385 }
1239812386 return false;
@@ -12590,7 +12578,7 @@ const _digest = (root) => {
1259012578 let pendingText = "";
1259112579 let pendingDepth = 0;
1259212580 const flushText = () => {
12593- const text = _asciiTrim (pendingText);
12581+ const text = stripAsciiWhitespace (pendingText);
1259412582 pendingText = "";
1259512583 if (text !== "") out.push(`${pendingDepth}\u0001t\u0001${text}`);
1259612584 };
@@ -12672,7 +12660,7 @@ const _digest = (root) => {
1267212660 html &&
1267312661 a.value.length === a.name.length &&
1267412662 _isBooleanAttribute(elementName, a.name) &&
12675- _asciiLowerCase (a.value) === a.name
12663+ asciiLowercase (a.value) === a.name
1267612664 ? ""
1267712665 : decodeEntities(a.value, true)
1267812666 }`
@@ -14379,25 +14367,16 @@ module.exports.QUOTE_NONE = QUOTE_NONE;
1437914367module.exports.QUOTE_SINGLE = QUOTE_SINGLE;
1438014368module.exports.SVG_TYPE = SVG_TYPE;
1438114369module.exports._S = _S;
14382- module.exports._attrRawValue = _attrRawValue;
1438314370module.exports._attributeCountOf = _attributeCountOf;
1438414371module.exports._attributeList = _attributeList;
14385- module.exports._contentEndOf = _contentEndOf;
14386- module.exports._contentStartOf = _contentStartOf;
1438714372module.exports._dataOf = _dataOf;
14388- module.exports._endOf = _endOf;
14389- module.exports._nameEndOf = _nameEndOf;
14390- module.exports._nameStartOf = _nameStartOf;
14391- module.exports._startOf = _startOf;
14392- module.exports._valueEndOf = _valueEndOf;
14393- module.exports._valueStartOf = _valueStartOf;
1439414373module.exports._firstChild = _firstChild;
1439514374module.exports._tagNameOf = _tagNameOf;
1439614375module.exports._namespaceOf = _namespaceOf;
1439714376module.exports._nextSibling = _nextSibling;
1439814377module.exports._parentOf = _parentOf;
14399- module.exports._asciiLowerCase = _asciiLowerCase ;
14400- module.exports._asciiTrim = _asciiTrim ;
14378+ module.exports.asciiLowercase = asciiLowercase ;
14379+ module.exports.stripAsciiWhitespace = stripAsciiWhitespace ;
1440114380module.exports._attributePrints = _attributePrints;
1440214381module.exports._canOmitEndTag = _canOmitEndTag;
1440314382module.exports._canOmitStartTag = _canOmitStartTag;
@@ -14430,8 +14409,6 @@ module.exports._synthesizeOpenTag = _synthesizeOpenTag;
1443014409module.exports._takeRenderedSheet = _takeRenderedSheet;
1443114410module.exports._rendersNow = _rendersNow;
1443214411module.exports._sheetDecides = _sheetDecides;
14433- module.exports._SHEET_LEADING_AT_RULE_REGEXP = _SHEET_LEADING_AT_RULE_REGEXP;
14434- module.exports._mergeableStyleAfter = _mergeableStyleAfter;
1443514412module.exports._onlyTextChild = _onlyTextChild;
1443614413module.exports._sheetClosing = _sheetClosing;
1443714414module.exports._styleRunText = _styleRunText;
0 commit comments