From 285c0928055a548257f7a680b79fa26746920f41 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Sat, 3 Aug 2024 19:12:54 +0200 Subject: [PATCH 1/5] improve performance --- packages/css-tokenizer/CHANGELOG.md | 1 + packages/css-tokenizer/dist/index.cjs | 2 +- packages/css-tokenizer/dist/index.d.ts | 9 +- packages/css-tokenizer/dist/index.mjs | 2 +- .../four-code-points-would-start-cdo.ts | 2 +- .../three-code-points-would-start-cdc.ts | 2 +- ...-code-points-would-start-ident-sequence.ts | 10 +- .../three-code-points-would-start-number.ts | 14 +- ...e-code-points-would-start-unicode-range.ts | 10 +- .../two-code-points-are-valid-escape.ts | 4 +- .../checks/two-code-points-start-comment.ts | 4 +- .../css-tokenizer/src/code-points/ranges.ts | 42 ++-- packages/css-tokenizer/src/consume/bad-url.ts | 5 +- packages/css-tokenizer/src/consume/comment.ts | 6 +- .../src/consume/escaped-code-point.ts | 9 +- .../css-tokenizer/src/consume/hash-token.ts | 5 +- .../src/consume/ident-like-token.ts | 8 +- .../src/consume/ident-sequence.ts | 7 +- packages/css-tokenizer/src/consume/number.ts | 18 +- .../src/consume/numeric-token.ts | 4 +- .../css-tokenizer/src/consume/string-token.ts | 14 +- .../src/consume/unicode-range-token.ts | 21 +- .../css-tokenizer/src/consume/url-token.ts | 21 +- .../src/consume/whitespace-token.ts | 2 +- .../src/interfaces/code-point-reader.ts | 4 +- packages/css-tokenizer/src/reader.ts | 36 +-- packages/css-tokenizer/src/tokenizer.ts | 6 +- packages/css-tokenizer/test/test-reader.mjs | 225 ------------------ packages/css-tokenizer/test/test.mjs | 3 - packages/css-tokenizer/test/token/basic.mjs | 2 +- 30 files changed, 128 insertions(+), 370 deletions(-) delete mode 100644 packages/css-tokenizer/test/test-reader.mjs diff --git a/packages/css-tokenizer/CHANGELOG.md b/packages/css-tokenizer/CHANGELOG.md index 92bba806e..840a9980b 100644 --- a/packages/css-tokenizer/CHANGELOG.md +++ b/packages/css-tokenizer/CHANGELOG.md @@ -3,6 +3,7 @@ ### Unreleased (major) - Updated: Support for Node v18+ (major). +- Improve performance. ### 2.4.1 diff --git a/packages/css-tokenizer/dist/index.cjs b/packages/css-tokenizer/dist/index.cjs index 1a95fd10b..0f57e3a05 100644 --- a/packages/css-tokenizer/dist/index.cjs +++ b/packages/css-tokenizer/dist/index.cjs @@ -1 +1 @@ -"use strict";class ParseError extends Error{sourceStart;sourceEnd;parserState;constructor(e,o,n,r){super(e),this.name="ParseError",this.sourceStart=o,this.sourceEnd=n,this.parserState=r}}class ParseErrorWithToken extends ParseError{token;constructor(e,o,n,r,t){super(e,o,n,r),this.token=t}}const e={UnexpectedNewLineInString:"Unexpected newline while consuming a string token.",UnexpectedEOFInString:"Unexpected EOF while consuming a string token.",UnexpectedEOFInComment:"Unexpected EOF while consuming a comment.",UnexpectedEOFInURL:"Unexpected EOF while consuming a url token.",UnexpectedEOFInEscapedCodePoint:"Unexpected EOF while consuming an escaped code point.",UnexpectedCharacterInURL:"Unexpected character while consuming a url token.",InvalidEscapeSequenceInURL:"Invalid escape sequence while consuming a url token.",InvalidEscapeSequenceAfterBackslash:'Invalid escape sequence after "\\"'};class Reader{cursor=0;source="";codePointSource=[];representationIndices=[-1];length=0;representationStart=0;representationEnd=-1;constructor(e){this.source=e;{let o=-1,n="";for(n of e)o+=n.length,this.codePointSource.push(n.codePointAt(0)),this.representationIndices.push(o)}this.length=this.codePointSource.length}advanceCodePoint(e=1){this.cursor=this.cursor+e,this.representationEnd=this.representationIndices[this.cursor]}readCodePoint(e=1){const o=this.codePointSource[this.cursor];return void 0!==o&&(this.cursor=this.cursor+e,this.representationEnd=this.representationIndices[this.cursor],o)}unreadCodePoint(e=1){this.cursor=this.cursor-e,this.representationEnd=this.representationIndices[this.cursor]}resetRepresentation(){this.representationStart=this.representationIndices[this.cursor]+1,this.representationEnd=-1}}const o="undefined"!=typeof globalThis&&"structuredClone"in globalThis;const n=39,r=42,t=8,i=13,s=9,c=58,a=44,u=64,d=127,p=33,T=12,P=46,S=62,k=45,C=31,l=69,f=101,x=123,m=40,h=91,E=60,y=10,v=11,g=95,I=1114111,U=0,O=35,D=37,R=43,w=34,L=65533,A=92,W=125,N=41,F=93,q=59,b=14,H=47,B=32,V=117,z=85,K=114,M=82,$=108,J=76,_=63,j=48,Q=70;function checkIfFourCodePointsWouldStartCDO(e){return e.codePointSource[e.cursor]===E&&e.codePointSource[e.cursor+1]===p&&e.codePointSource[e.cursor+2]===k&&e.codePointSource[e.cursor+3]===k}function isDigitCodePoint(e){return e>=48&&e<=57}function isUppercaseLetterCodePoint(e){return e>=65&&e<=90}function isLowercaseLetterCodePoint(e){return e>=97&&e<=122}function isHexDigitCodePoint(e){return isDigitCodePoint(e)||e>=97&&e<=102||e>=65&&e<=70}function isLetterCodePoint(e){return isLowercaseLetterCodePoint(e)||isUppercaseLetterCodePoint(e)}function isIdentStartCodePoint(e){return isLetterCodePoint(e)||isNonASCII_IdentCodePoint(e)||e===g}function isIdentCodePoint(e){return isIdentStartCodePoint(e)||isDigitCodePoint(e)||e===k}function isNonASCII_IdentCodePoint(e){return 183===e||8204===e||8205===e||8255===e||8256===e||8204===e||(192<=e&&e<=214||216<=e&&e<=246||248<=e&&e<=893||895<=e&&e<=8191||8304<=e&&e<=8591||11264<=e&&e<=12271||12289<=e&&e<=55295||63744<=e&&e<=64975||65008<=e&&e<=65533||e>=65536)}function isNewLine(e){return e===y||e===i||e===T}function isWhitespace(e){return e===B||e===y||e===s||e===i||e===T}function checkIfTwoCodePointsAreAValidEscape(e){return e.codePointSource[e.cursor]===A&&!isNewLine(e.codePointSource[e.cursor+1])}function checkIfThreeCodePointsWouldStartAnIdentSequence(e,o){return o.codePointSource[o.cursor]===k?o.codePointSource[o.cursor+1]===k||(!!isIdentStartCodePoint(o.codePointSource[o.cursor+1])||o.codePointSource[o.cursor+1]===A&&!isNewLine(o.codePointSource[o.cursor+2])):!!isIdentStartCodePoint(o.codePointSource[o.cursor])||checkIfTwoCodePointsAreAValidEscape(o)}function checkIfThreeCodePointsWouldStartANumber(e){return e.codePointSource[e.cursor]===R||e.codePointSource[e.cursor]===k?!!isDigitCodePoint(e.codePointSource[e.cursor+1])||e.codePointSource[e.cursor+1]===P&&isDigitCodePoint(e.codePointSource[e.cursor+2]):e.codePointSource[e.cursor]===P?isDigitCodePoint(e.codePointSource[e.cursor+1]):isDigitCodePoint(e.codePointSource[e.cursor])}function checkIfTwoCodePointsStartAComment(e){return e.codePointSource[e.cursor]===H&&e.codePointSource[e.cursor+1]===r}function checkIfThreeCodePointsWouldStartCDC(e){return e.codePointSource[e.cursor]===k&&e.codePointSource[e.cursor+1]===k&&e.codePointSource[e.cursor+2]===S}var G,X,Y;function consumeComment(o,n){for(n.advanceCodePoint(2);;){const t=n.readCodePoint();if(!1===t){const r=[exports.TokenType.Comment,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,void 0];return o.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInComment,n.representationStart,n.representationEnd,["4.3.2. Consume comments","Unexpected EOF"],r)),r}if(t===r&&(void 0!==n.codePointSource[n.cursor]&&n.codePointSource[n.cursor]===H)){n.advanceCodePoint();break}}return[exports.TokenType.Comment,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,void 0]}function consumeEscapedCodePoint(o,n){const r=n.readCodePoint();if(!1===r)return o.onParseError(new ParseError(e.UnexpectedEOFInEscapedCodePoint,n.representationStart,n.representationEnd,["4.3.7. Consume an escaped code point","Unexpected EOF"])),L;if(isHexDigitCodePoint(r)){const e=[r];for(;void 0!==n.codePointSource[n.cursor]&&isHexDigitCodePoint(n.codePointSource[n.cursor])&&e.length<6;)e.push(n.codePointSource[n.cursor]),n.advanceCodePoint();isWhitespace(n.codePointSource[n.cursor])&&n.advanceCodePoint();const o=parseInt(String.fromCodePoint(...e),16);return 0===o?L:(t=o)>=55296&&t<=57343||o>I?L:o}var t;return r}function consumeIdentSequence(e,o){const n=[];for(;;)if(isIdentCodePoint(o.codePointSource[o.cursor]))n.push(o.codePointSource[o.cursor]),o.advanceCodePoint();else{if(!checkIfTwoCodePointsAreAValidEscape(o))return n;o.advanceCodePoint(),n.push(consumeEscapedCodePoint(e,o))}}function consumeHashToken(e,o){if(o.advanceCodePoint(),void 0!==o.codePointSource[o.cursor]&&(isIdentCodePoint(o.codePointSource[o.cursor])||checkIfTwoCodePointsAreAValidEscape(o))){let n=exports.HashType.Unrestricted;checkIfThreeCodePointsWouldStartAnIdentSequence(0,o)&&(n=exports.HashType.ID);const r=consumeIdentSequence(e,o);return[exports.TokenType.Hash,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:String.fromCodePoint(...r),type:n}]}return[exports.TokenType.Delim,"#",o.representationStart,o.representationEnd,{value:"#"}]}function consumeNumber(e,o){let n=exports.NumberType.Integer;for(o.codePointSource[o.cursor]!==R&&o.codePointSource[o.cursor]!==k||o.advanceCodePoint();isDigitCodePoint(o.codePointSource[o.cursor]);)o.advanceCodePoint();if(o.codePointSource[o.cursor]===P&&isDigitCodePoint(o.codePointSource[o.cursor+1]))for(o.advanceCodePoint(2),n=exports.NumberType.Number;isDigitCodePoint(o.codePointSource[o.cursor]);)o.advanceCodePoint();if(o.codePointSource[o.cursor]===f||o.codePointSource[o.cursor]===l){if(isDigitCodePoint(o.codePointSource[o.cursor+1]))o.advanceCodePoint(2);else{if(o.codePointSource[o.cursor+1]!==k&&o.codePointSource[o.cursor+1]!==R||!isDigitCodePoint(o.codePointSource[o.cursor+2]))return n;o.advanceCodePoint(3)}for(n=exports.NumberType.Number;isDigitCodePoint(o.codePointSource[o.cursor]);)o.advanceCodePoint()}return n}function consumeNumericToken(e,o){let n;{const e=o.codePointSource[o.cursor];e===k?n="-":e===R&&(n="+")}const r=consumeNumber(0,o),t=parseFloat(o.source.slice(o.representationStart,o.representationEnd+1));if(checkIfThreeCodePointsWouldStartAnIdentSequence(0,o)){const i=consumeIdentSequence(e,o);return[exports.TokenType.Dimension,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t,signCharacter:n,type:r,unit:String.fromCodePoint(...i)}]}return o.codePointSource[o.cursor]===D?(o.advanceCodePoint(),[exports.TokenType.Percentage,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t,signCharacter:n}]):[exports.TokenType.Number,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t,signCharacter:n,type:r}]}function consumeWhiteSpace(e){for(;isWhitespace(e.codePointSource[e.cursor]);)e.advanceCodePoint();return[exports.TokenType.Whitespace,e.source.slice(e.representationStart,e.representationEnd+1),e.representationStart,e.representationEnd,void 0]}function consumeStringToken(o,n){let r="";const t=n.readCodePoint();for(;;){const s=n.readCodePoint();if(!1===s){const t=[exports.TokenType.String,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r}];return o.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInString,n.representationStart,n.representationEnd,["4.3.5. Consume a string token","Unexpected EOF"],t)),t}if(isNewLine(s)){n.unreadCodePoint();const r=[exports.TokenType.BadString,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,void 0];return o.onParseError(new ParseErrorWithToken(e.UnexpectedNewLineInString,n.representationStart,n.codePointSource[n.cursor]===i&&n.codePointSource[n.cursor+1]===y?n.representationEnd+2:n.representationEnd+1,["4.3.5. Consume a string token","Unexpected newline"],r)),r}if(s===t)return[exports.TokenType.String,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r}];if(s!==A)r+=String.fromCodePoint(s);else{if(void 0===n.codePointSource[n.cursor])continue;if(isNewLine(n.codePointSource[n.cursor])){n.codePointSource[n.cursor]===i&&n.codePointSource[n.cursor+1]===y&&n.advanceCodePoint(),n.advanceCodePoint();continue}r+=String.fromCodePoint(consumeEscapedCodePoint(o,n))}}}function checkIfCodePointsMatchURLIdent(e){return!(3!==e.length||e[0]!==V&&e[0]!==z||e[1]!==K&&e[1]!==M||e[2]!==$&&e[2]!==J)}function consumeBadURL(e,o){for(;;){if(void 0===o.codePointSource[o.cursor])return;if(o.codePointSource[o.cursor]===N)return void o.advanceCodePoint();checkIfTwoCodePointsAreAValidEscape(o)?(o.advanceCodePoint(),consumeEscapedCodePoint(e,o)):o.advanceCodePoint()}}function consumeUrlToken(o,r){for(;isWhitespace(r.codePointSource[r.cursor]);)r.advanceCodePoint();let i="";for(;;){if(void 0===r.codePointSource[r.cursor]){const n=[exports.TokenType.URL,r.source.slice(r.representationStart,r.representationEnd+1),r.representationStart,r.representationEnd,{value:i}];return o.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,r.representationStart,r.representationEnd,["4.3.6. Consume a url token","Unexpected EOF"],n)),n}if(r.codePointSource[r.cursor]===N)return r.advanceCodePoint(),[exports.TokenType.URL,r.source.slice(r.representationStart,r.representationEnd+1),r.representationStart,r.representationEnd,{value:i}];if(isWhitespace(r.codePointSource[r.cursor])){for(r.advanceCodePoint();isWhitespace(r.codePointSource[r.cursor]);)r.advanceCodePoint();if(void 0===r.codePointSource[r.cursor]){const n=[exports.TokenType.URL,r.source.slice(r.representationStart,r.representationEnd+1),r.representationStart,r.representationEnd,{value:i}];return o.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,r.representationStart,r.representationEnd,["4.3.6. Consume a url token","Consume as much whitespace as possible","Unexpected EOF"],n)),n}return r.codePointSource[r.cursor]===N?(r.advanceCodePoint(),[exports.TokenType.URL,r.source.slice(r.representationStart,r.representationEnd+1),r.representationStart,r.representationEnd,{value:i}]):(consumeBadURL(o,r),[exports.TokenType.BadURL,r.source.slice(r.representationStart,r.representationEnd+1),r.representationStart,r.representationEnd,void 0])}if(r.codePointSource[r.cursor]===w||r.codePointSource[r.cursor]===n||r.codePointSource[r.cursor]===m||((s=r.codePointSource[r.cursor])===v||s===d||U<=s&&s<=t||b<=s&&s<=C)){consumeBadURL(o,r);const n=[exports.TokenType.BadURL,r.source.slice(r.representationStart,r.representationEnd+1),r.representationStart,r.representationEnd,void 0];return o.onParseError(new ParseErrorWithToken(e.UnexpectedCharacterInURL,r.representationStart,r.representationEnd,["4.3.6. Consume a url token","Unexpected U+0022 QUOTATION MARK (\"), U+0027 APOSTROPHE ('), U+0028 LEFT PARENTHESIS (() or non-printable code point"],n)),n}if(r.codePointSource[r.cursor]===A){if(checkIfTwoCodePointsAreAValidEscape(r)){r.advanceCodePoint(),i+=String.fromCodePoint(consumeEscapedCodePoint(o,r));continue}consumeBadURL(o,r);const n=[exports.TokenType.BadURL,r.source.slice(r.representationStart,r.representationEnd+1),r.representationStart,r.representationEnd,void 0];return o.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceInURL,r.representationStart,r.representationEnd,["4.3.6. Consume a url token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],n)),n}i+=String.fromCodePoint(r.codePointSource[r.cursor]),r.advanceCodePoint()}var s}function consumeIdentLikeToken(e,o){const r=consumeIdentSequence(e,o);if(o.codePointSource[o.cursor]!==m)return[exports.TokenType.Ident,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:String.fromCodePoint(...r)}];if(checkIfCodePointsMatchURLIdent(r)){o.advanceCodePoint();let t=0;for(;;){const e=isWhitespace(o.codePointSource[o.cursor]),i=isWhitespace(o.codePointSource[o.cursor+1]);if(e&&i){t+=1,o.advanceCodePoint(1);continue}const s=e?o.codePointSource[o.cursor+1]:o.codePointSource[o.cursor];if(s===w||s===n)return t>0&&o.unreadCodePoint(t),[exports.TokenType.Function,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:String.fromCodePoint(...r)}];break}return consumeUrlToken(e,o)}return o.advanceCodePoint(),[exports.TokenType.Function,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:String.fromCodePoint(...r)}]}function checkIfThreeCodePointsWouldStartAUnicodeRange(e){return!(e.codePointSource[e.cursor]!==V&&e.codePointSource[e.cursor]!==z||e.codePointSource[e.cursor+1]!==R||e.codePointSource[e.cursor+2]!==_&&!isHexDigitCodePoint(e.codePointSource[e.cursor+2]))}function consumeUnicodeRangeToken(e,o){o.advanceCodePoint(2);const n=[],r=[];for(;void 0!==o.codePointSource[o.cursor]&&n.length<6&&isHexDigitCodePoint(o.codePointSource[o.cursor]);)n.push(o.codePointSource[o.cursor]),o.advanceCodePoint();for(;void 0!==o.codePointSource[o.cursor]&&n.length<6&&o.codePointSource[o.cursor]===_;)0===r.length&&r.push(...n),n.push(j),r.push(Q),o.advanceCodePoint();if(!r.length&&o.codePointSource[o.cursor]===k&&isHexDigitCodePoint(o.codePointSource[o.cursor+1]))for(o.advanceCodePoint();void 0!==o.codePointSource[o.cursor]&&r.length<6&&isHexDigitCodePoint(o.codePointSource[o.cursor]);)r.push(o.codePointSource[o.cursor]),o.advanceCodePoint();if(!r.length){const e=parseInt(String.fromCodePoint(...n),16);return[exports.TokenType.UnicodeRange,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{startOfRange:e,endOfRange:e}]}const t=parseInt(String.fromCodePoint(...n),16),i=parseInt(String.fromCodePoint(...r),16);return[exports.TokenType.UnicodeRange,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{startOfRange:t,endOfRange:i}]}function tokenizer(o,r){const t=o.css.valueOf(),d=o.unicodeRangesAllowed??!1,p=new Reader(t),S={onParseError:r?.onParseError??noop};return{nextToken:function nextToken(){p.resetRepresentation();const o=p.codePointSource[p.cursor];if(void 0===o)return[exports.TokenType.EOF,"",-1,-1,void 0];if(o===H&&checkIfTwoCodePointsStartAComment(p))return consumeComment(S,p);if(d&&(o===V||o===z)&&checkIfThreeCodePointsWouldStartAUnicodeRange(p))return consumeUnicodeRangeToken(0,p);if(isIdentStartCodePoint(o))return consumeIdentLikeToken(S,p);if(isDigitCodePoint(o))return consumeNumericToken(S,p);switch(o){case a:return p.advanceCodePoint(),[exports.TokenType.Comma,",",p.representationStart,p.representationEnd,void 0];case c:return p.advanceCodePoint(),[exports.TokenType.Colon,":",p.representationStart,p.representationEnd,void 0];case q:return p.advanceCodePoint(),[exports.TokenType.Semicolon,";",p.representationStart,p.representationEnd,void 0];case m:return p.advanceCodePoint(),[exports.TokenType.OpenParen,"(",p.representationStart,p.representationEnd,void 0];case N:return p.advanceCodePoint(),[exports.TokenType.CloseParen,")",p.representationStart,p.representationEnd,void 0];case h:return p.advanceCodePoint(),[exports.TokenType.OpenSquare,"[",p.representationStart,p.representationEnd,void 0];case F:return p.advanceCodePoint(),[exports.TokenType.CloseSquare,"]",p.representationStart,p.representationEnd,void 0];case x:return p.advanceCodePoint(),[exports.TokenType.OpenCurly,"{",p.representationStart,p.representationEnd,void 0];case W:return p.advanceCodePoint(),[exports.TokenType.CloseCurly,"}",p.representationStart,p.representationEnd,void 0];case n:case w:return consumeStringToken(S,p);case O:return consumeHashToken(S,p);case R:case P:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(S,p):(p.advanceCodePoint(),[exports.TokenType.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]);case y:case i:case T:case s:case B:return consumeWhiteSpace(p);case k:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(S,p):checkIfThreeCodePointsWouldStartCDC(p)?(p.advanceCodePoint(3),[exports.TokenType.CDC,"--\x3e",p.representationStart,p.representationEnd,void 0]):checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)?consumeIdentLikeToken(S,p):(p.advanceCodePoint(),[exports.TokenType.Delim,"-",p.representationStart,p.representationEnd,{value:"-"}]);case E:return checkIfFourCodePointsWouldStartCDO(p)?(p.advanceCodePoint(4),[exports.TokenType.CDO,"\x3c!--",p.representationStart,p.representationEnd,void 0]):(p.advanceCodePoint(),[exports.TokenType.Delim,"<",p.representationStart,p.representationEnd,{value:"<"}]);case u:if(p.advanceCodePoint(),checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)){const e=consumeIdentSequence(S,p);return[exports.TokenType.AtKeyword,p.source.slice(p.representationStart,p.representationEnd+1),p.representationStart,p.representationEnd,{value:String.fromCodePoint(...e)}]}return[exports.TokenType.Delim,"@",p.representationStart,p.representationEnd,{value:"@"}];case A:{if(checkIfTwoCodePointsAreAValidEscape(p))return consumeIdentLikeToken(S,p);p.advanceCodePoint();const o=[exports.TokenType.Delim,"\\",p.representationStart,p.representationEnd,{value:"\\"}];return S.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceAfterBackslash,p.representationStart,p.representationEnd,["4.3.1. Consume a token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],o)),o}}return p.advanceCodePoint(),[exports.TokenType.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]},endOfFile:function endOfFile(){return void 0===p.codePointSource[p.cursor]}}}function noop(){}function ensureThatValueRoundTripsAsIdent(e){let o=0;e[0]===k&&e[1]===k?o=2:e[0]===k&&e[1]?(o=2,isIdentStartCodePoint(e[1])||(o+=insertEscapedCodePoint(e,1,e[1]))):isIdentStartCodePoint(e[0])?o=1:(o=1,o+=insertEscapedCodePoint(e,0,e[0]));for(let n=o;n=48&&e<=57}function isUppercaseLetterCodePoint(e){return void 0!==e&&e>=65&&e<=90}function isLowercaseLetterCodePoint(e){return void 0!==e&&e>=97&&e<=122}function isHexDigitCodePoint(e){return void 0!==e&&(e>=48&&e<=57||e>=97&&e<=102||e>=65&&e<=70)}function isLetterCodePoint(e){return isLowercaseLetterCodePoint(e)||isUppercaseLetterCodePoint(e)}function isIdentStartCodePoint(e){return isLetterCodePoint(e)||isNonASCII_IdentCodePoint(e)||e===A}function isIdentCodePoint(e){return isIdentStartCodePoint(e)||isDigitCodePoint(e)||e===C}function isNonASCII_IdentCodePoint(e){return 183===e||8204===e||8205===e||8255===e||8256===e||8204===e||void 0!==e&&(192<=e&&e<=214||216<=e&&e<=246||248<=e&&e<=893||895<=e&&e<=8191||8304<=e&&e<=8591||11264<=e&&e<=12271||12289<=e&&e<=55295||63744<=e&&e<=64975||65008<=e&&e<=65533||e>=65536)}function isNewLine(e){return e===y||e===s||e===T}function isWhitespace(e){return e===B||e===y||e===i||e===s||e===T}function checkIfTwoCodePointsAreAValidEscape(e){return e.source.codePointAt(e.cursor)===L&&!isNewLine(e.source.codePointAt(e.cursor+1))}function checkIfThreeCodePointsWouldStartAnIdentSequence(e,n){return n.source.codePointAt(n.cursor)===C?n.source.codePointAt(n.cursor+1)===C||(!!isIdentStartCodePoint(n.source.codePointAt(n.cursor+1))||n.source.codePointAt(n.cursor+1)===L&&!isNewLine(n.source.codePointAt(n.cursor+2))):!!isIdentStartCodePoint(n.source.codePointAt(n.cursor))||checkIfTwoCodePointsAreAValidEscape(n)}function checkIfThreeCodePointsWouldStartANumber(e){return e.source.codePointAt(e.cursor)===R||e.source.codePointAt(e.cursor)===C?!!isDigitCodePoint(e.source.codePointAt(e.cursor+1))||e.source.codePointAt(e.cursor+1)===P&&isDigitCodePoint(e.source.codePointAt(e.cursor+2)):e.source.codePointAt(e.cursor)===P?isDigitCodePoint(e.source.codePointAt(e.cursor+1)):isDigitCodePoint(e.source.codePointAt(e.cursor))}function checkIfTwoCodePointsStartAComment(e){return e.source.codePointAt(e.cursor)===H&&e.source.codePointAt(e.cursor+1)===t}function checkIfThreeCodePointsWouldStartCDC(e){return e.source.codePointAt(e.cursor)===C&&e.source.codePointAt(e.cursor+1)===C&&e.source.codePointAt(e.cursor+2)===k}var G,X,Y;function consumeComment(n,o){for(o.advanceCodePoint(2);;){const r=o.readCodePoint();if(void 0===r){const t=[exports.TokenType.Comment,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInComment,o.representationStart,o.representationEnd,["4.3.2. Consume comments","Unexpected EOF"],t)),t}if(r===t&&(void 0!==o.source.codePointAt(o.cursor)&&o.source.codePointAt(o.cursor)===H)){o.advanceCodePoint();break}}return[exports.TokenType.Comment,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0]}function consumeEscapedCodePoint(n,o){const t=o.readCodePoint();if(void 0===t)return n.onParseError(new ParseError(e.UnexpectedEOFInEscapedCodePoint,o.representationStart,o.representationEnd,["4.3.7. Consume an escaped code point","Unexpected EOF"])),w;if(isHexDigitCodePoint(t)){const e=[t];let n;for(;void 0!==(n=o.source.codePointAt(o.cursor))&&isHexDigitCodePoint(n)&&e.length<6;)e.push(n),o.advanceCodePoint();isWhitespace(o.source.codePointAt(o.cursor))&&o.advanceCodePoint();const s=parseInt(String.fromCodePoint(...e),16);return 0===s?w:void 0!==(r=s)&&r>=55296&&r<=57343||s>g?w:s}var r;return t}function consumeIdentSequence(e,n){const o=[];for(;;){const t=n.source.codePointAt(n.cursor);if(isIdentCodePoint(t))o.push(t),n.advanceCodePoint(+(t>65535)+1);else{if(!checkIfTwoCodePointsAreAValidEscape(n))return o;n.advanceCodePoint(),o.push(consumeEscapedCodePoint(e,n))}}}function consumeHashToken(e,n){n.advanceCodePoint();const o=n.source.codePointAt(n.cursor);if(void 0!==o&&(isIdentCodePoint(o)||checkIfTwoCodePointsAreAValidEscape(n))){let o=exports.HashType.Unrestricted;checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)&&(o=exports.HashType.ID);const t=consumeIdentSequence(e,n);return[exports.TokenType.Hash,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t),type:o}]}return[exports.TokenType.Delim,"#",n.representationStart,n.representationEnd,{value:"#"}]}function consumeNumber(e,n){let o=exports.NumberType.Integer;for(n.source.codePointAt(n.cursor)!==R&&n.source.codePointAt(n.cursor)!==C||n.advanceCodePoint();isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===P&&isDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint(2),o=exports.NumberType.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===x||n.source.codePointAt(n.cursor)===f){if(isDigitCodePoint(n.source.codePointAt(n.cursor+1)))n.advanceCodePoint(2);else{if(n.source.codePointAt(n.cursor+1)!==C&&n.source.codePointAt(n.cursor+1)!==R||!isDigitCodePoint(n.source.codePointAt(n.cursor+2)))return o;n.advanceCodePoint(3)}for(o=exports.NumberType.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint()}return o}function consumeNumericToken(e,n){let o;{const e=n.source.codePointAt(n.cursor);e===C?o="-":e===R&&(o="+")}const t=consumeNumber(0,n),r=parseFloat(n.source.slice(n.representationStart,n.representationEnd+1));if(checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)){const s=consumeIdentSequence(e,n);return[exports.TokenType.Dimension,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o,type:t,unit:String.fromCodePoint(...s)}]}return n.source.codePointAt(n.cursor)===O?(n.advanceCodePoint(),[exports.TokenType.Percentage,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o}]):[exports.TokenType.Number,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o,type:t}]}function consumeWhiteSpace(e){for(;isWhitespace(e.source.codePointAt(e.cursor));)e.advanceCodePoint();return[exports.TokenType.Whitespace,e.source.slice(e.representationStart,e.representationEnd+1),e.representationStart,e.representationEnd,void 0]}function consumeStringToken(n,o){let t="";const r=o.readCodePoint();for(;;){const i=o.readCodePoint();if(void 0===i){const r=[exports.TokenType.String,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInString,o.representationStart,o.representationEnd,["4.3.5. Consume a string token","Unexpected EOF"],r)),r}if(isNewLine(i)){o.unreadCodePoint();const t=[exports.TokenType.BadString,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedNewLineInString,o.representationStart,o.source.codePointAt(o.cursor)===s&&o.source.codePointAt(o.cursor+1)===y?o.representationEnd+2:o.representationEnd+1,["4.3.5. Consume a string token","Unexpected newline"],t)),t}if(i===r)return[exports.TokenType.String,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t}];if(i!==L)t+=String.fromCodePoint(i);else{if(void 0===o.source.codePointAt(o.cursor))continue;if(isNewLine(o.source.codePointAt(o.cursor))){o.source.codePointAt(o.cursor)===s&&o.source.codePointAt(o.cursor+1)===y&&o.advanceCodePoint(),o.advanceCodePoint();continue}t+=String.fromCodePoint(consumeEscapedCodePoint(n,o))}}}function checkIfCodePointsMatchURLIdent(e){return!(3!==e.length||e[0]!==V&&e[0]!==z||e[1]!==K&&e[1]!==M||e[2]!==$&&e[2]!==J)}function consumeBadURL(e,n){for(;;){const o=n.source.codePointAt(n.cursor);if(void 0===o)return;if(o===N)return void n.advanceCodePoint();checkIfTwoCodePointsAreAValidEscape(n)?(n.advanceCodePoint(),consumeEscapedCodePoint(e,n)):n.advanceCodePoint()}}function consumeUrlToken(n,t){for(;isWhitespace(t.source.codePointAt(t.cursor));)t.advanceCodePoint();let s="";for(;;){if(void 0===t.source.codePointAt(t.cursor)){const o=[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Unexpected EOF"],o)),o}if(t.source.codePointAt(t.cursor)===N)return t.advanceCodePoint(),[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}];if(isWhitespace(t.source.codePointAt(t.cursor))){for(t.advanceCodePoint();isWhitespace(t.source.codePointAt(t.cursor));)t.advanceCodePoint();if(void 0===t.source.codePointAt(t.cursor)){const o=[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Consume as much whitespace as possible","Unexpected EOF"],o)),o}return t.source.codePointAt(t.cursor)===N?(t.advanceCodePoint(),[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}]):(consumeBadURL(n,t),[exports.TokenType.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0])}const c=t.source.codePointAt(t.cursor);if(c===D||c===o||c===m||void 0!==(i=c)&&(i===v||i===d||I<=i&&i<=r||b<=i&&i<=l)){consumeBadURL(n,t);const o=[exports.TokenType.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedCharacterInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Unexpected U+0022 QUOTATION MARK (\"), U+0027 APOSTROPHE ('), U+0028 LEFT PARENTHESIS (() or non-printable code point"],o)),o}if(c===L){if(checkIfTwoCodePointsAreAValidEscape(t)){t.advanceCodePoint(),s+=String.fromCodePoint(consumeEscapedCodePoint(n,t));continue}consumeBadURL(n,t);const o=[exports.TokenType.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],o)),o}s+=t.source[t.cursor],t.advanceCodePoint()}var i}function consumeIdentLikeToken(e,n){const t=consumeIdentSequence(e,n);if(n.source.codePointAt(n.cursor)!==m)return[exports.TokenType.Ident,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}];if(checkIfCodePointsMatchURLIdent(t)){n.advanceCodePoint();let r=0;for(;;){const e=isWhitespace(n.source.codePointAt(n.cursor)),s=isWhitespace(n.source.codePointAt(n.cursor+1));if(e&&s){r+=1,n.advanceCodePoint(1);continue}const i=e?n.source.codePointAt(n.cursor+1):n.source.codePointAt(n.cursor);if(i===D||i===o)return r>0&&n.unreadCodePoint(r),[exports.TokenType.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}];break}return consumeUrlToken(e,n)}return n.advanceCodePoint(),[exports.TokenType.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}]}function checkIfThreeCodePointsWouldStartAUnicodeRange(e){return!(e.source.codePointAt(e.cursor)!==V&&e.source.codePointAt(e.cursor)!==z||e.source.codePointAt(e.cursor+1)!==R||e.source.codePointAt(e.cursor+2)!==_&&!isHexDigitCodePoint(e.source.codePointAt(e.cursor+2)))}function consumeUnicodeRangeToken(e,n){n.advanceCodePoint(2);const o=[],t=[];let r;for(;void 0!==(r=n.source.codePointAt(n.cursor))&&o.length<6&&isHexDigitCodePoint(r);)o.push(r),n.advanceCodePoint();for(;void 0!==(r=n.source.codePointAt(n.cursor))&&o.length<6&&r===_;)0===t.length&&t.push(...o),o.push(j),t.push(Q),n.advanceCodePoint();if(!t.length&&n.source.codePointAt(n.cursor)===C&&isHexDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint();void 0!==(r=n.source.codePointAt(n.cursor))&&t.length<6&&isHexDigitCodePoint(r);)t.push(r),n.advanceCodePoint();if(!t.length){const e=parseInt(String.fromCodePoint(...o),16);return[exports.TokenType.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:e,endOfRange:e}]}const s=parseInt(String.fromCodePoint(...o),16),i=parseInt(String.fromCodePoint(...t),16);return[exports.TokenType.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:s,endOfRange:i}]}function tokenizer(n,t){const r=n.css.valueOf(),d=n.unicodeRangesAllowed??!1,p=new Reader(r),k={onParseError:t?.onParseError??noop};return{nextToken:function nextToken(){p.resetRepresentation();const n=p.source.codePointAt(p.cursor);if(void 0===n)return[exports.TokenType.EOF,"",-1,-1,void 0];if(n===H&&checkIfTwoCodePointsStartAComment(p))return consumeComment(k,p);if(d&&(n===V||n===z)&&checkIfThreeCodePointsWouldStartAUnicodeRange(p))return consumeUnicodeRangeToken(0,p);if(isIdentStartCodePoint(n))return consumeIdentLikeToken(k,p);if(isDigitCodePoint(n))return consumeNumericToken(k,p);switch(n){case a:return p.advanceCodePoint(),[exports.TokenType.Comma,",",p.representationStart,p.representationEnd,void 0];case c:return p.advanceCodePoint(),[exports.TokenType.Colon,":",p.representationStart,p.representationEnd,void 0];case q:return p.advanceCodePoint(),[exports.TokenType.Semicolon,";",p.representationStart,p.representationEnd,void 0];case m:return p.advanceCodePoint(),[exports.TokenType.OpenParen,"(",p.representationStart,p.representationEnd,void 0];case N:return p.advanceCodePoint(),[exports.TokenType.CloseParen,")",p.representationStart,p.representationEnd,void 0];case E:return p.advanceCodePoint(),[exports.TokenType.OpenSquare,"[",p.representationStart,p.representationEnd,void 0];case F:return p.advanceCodePoint(),[exports.TokenType.CloseSquare,"]",p.representationStart,p.representationEnd,void 0];case S:return p.advanceCodePoint(),[exports.TokenType.OpenCurly,"{",p.representationStart,p.representationEnd,void 0];case W:return p.advanceCodePoint(),[exports.TokenType.CloseCurly,"}",p.representationStart,p.representationEnd,void 0];case o:case D:return consumeStringToken(k,p);case U:return consumeHashToken(k,p);case R:case P:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(k,p):(p.advanceCodePoint(),[exports.TokenType.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]);case y:case s:case T:case i:case B:return consumeWhiteSpace(p);case C:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(k,p):checkIfThreeCodePointsWouldStartCDC(p)?(p.advanceCodePoint(3),[exports.TokenType.CDC,"--\x3e",p.representationStart,p.representationEnd,void 0]):checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)?consumeIdentLikeToken(k,p):(p.advanceCodePoint(),[exports.TokenType.Delim,"-",p.representationStart,p.representationEnd,{value:"-"}]);case h:return checkIfFourCodePointsWouldStartCDO(p)?(p.advanceCodePoint(4),[exports.TokenType.CDO,"\x3c!--",p.representationStart,p.representationEnd,void 0]):(p.advanceCodePoint(),[exports.TokenType.Delim,"<",p.representationStart,p.representationEnd,{value:"<"}]);case u:if(p.advanceCodePoint(),checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)){const e=consumeIdentSequence(k,p);return[exports.TokenType.AtKeyword,p.source.slice(p.representationStart,p.representationEnd+1),p.representationStart,p.representationEnd,{value:String.fromCodePoint(...e)}]}return[exports.TokenType.Delim,"@",p.representationStart,p.representationEnd,{value:"@"}];case L:{if(checkIfTwoCodePointsAreAValidEscape(p))return consumeIdentLikeToken(k,p);p.advanceCodePoint();const n=[exports.TokenType.Delim,"\\",p.representationStart,p.representationEnd,{value:"\\"}];return k.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceAfterBackslash,p.representationStart,p.representationEnd,["4.3.1. Consume a token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],n)),n}}return p.advanceCodePoint(),[exports.TokenType.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]},endOfFile:function endOfFile(){return void 0===p.source.codePointAt(p.cursor)}}}function noop(){}function ensureThatValueRoundTripsAsIdent(e){let n=0;e[0]===C&&e[1]===C?n=2:e[0]===C&&e[1]?(n=2,isIdentStartCodePoint(e[1])||(n+=insertEscapedCodePoint(e,1,e[1]))):isIdentStartCodePoint(e[0])?n=1:(n=1,n+=insertEscapedCodePoint(e,0,e[0]));for(let o=n;o; - representationIndices: Array; source: string; advanceCodePoint(n?: number): void; - readCodePoint(n?: number): number | false; + readCodePoint(): number | undefined; unreadCodePoint(n?: number): void; resetRepresentation(): void; }; @@ -238,14 +236,11 @@ export declare class ParseErrorWithToken extends ParseError { export declare class Reader implements CodePointReader { cursor: number; source: string; - codePointSource: Array; - representationIndices: Array; - length: number; representationStart: number; representationEnd: number; constructor(source: string); advanceCodePoint(n?: number): void; - readCodePoint(n?: number): number | false; + readCodePoint(): number | undefined; unreadCodePoint(n?: number): void; resetRepresentation(): void; } diff --git a/packages/css-tokenizer/dist/index.mjs b/packages/css-tokenizer/dist/index.mjs index 546539f48..04191c961 100644 --- a/packages/css-tokenizer/dist/index.mjs +++ b/packages/css-tokenizer/dist/index.mjs @@ -1 +1 @@ -class ParseError extends Error{sourceStart;sourceEnd;parserState;constructor(e,n,o,t){super(e),this.name="ParseError",this.sourceStart=n,this.sourceEnd=o,this.parserState=t}}class ParseErrorWithToken extends ParseError{token;constructor(e,n,o,t,r){super(e,n,o,t),this.token=r}}const e={UnexpectedNewLineInString:"Unexpected newline while consuming a string token.",UnexpectedEOFInString:"Unexpected EOF while consuming a string token.",UnexpectedEOFInComment:"Unexpected EOF while consuming a comment.",UnexpectedEOFInURL:"Unexpected EOF while consuming a url token.",UnexpectedEOFInEscapedCodePoint:"Unexpected EOF while consuming an escaped code point.",UnexpectedCharacterInURL:"Unexpected character while consuming a url token.",InvalidEscapeSequenceInURL:"Invalid escape sequence while consuming a url token.",InvalidEscapeSequenceAfterBackslash:'Invalid escape sequence after "\\"'};class Reader{cursor=0;source="";codePointSource=[];representationIndices=[-1];length=0;representationStart=0;representationEnd=-1;constructor(e){this.source=e;{let n=-1,o="";for(o of e)n+=o.length,this.codePointSource.push(o.codePointAt(0)),this.representationIndices.push(n)}this.length=this.codePointSource.length}advanceCodePoint(e=1){this.cursor=this.cursor+e,this.representationEnd=this.representationIndices[this.cursor]}readCodePoint(e=1){const n=this.codePointSource[this.cursor];return void 0!==n&&(this.cursor=this.cursor+e,this.representationEnd=this.representationIndices[this.cursor],n)}unreadCodePoint(e=1){this.cursor=this.cursor-e,this.representationEnd=this.representationIndices[this.cursor]}resetRepresentation(){this.representationStart=this.representationIndices[this.cursor]+1,this.representationEnd=-1}}const n="undefined"!=typeof globalThis&&"structuredClone"in globalThis;function cloneTokens(e){return n?structuredClone(e):JSON.parse(JSON.stringify(e))}function stringify(...e){let n="";for(let o=0;o=48&&e<=57}function isUppercaseLetterCodePoint(e){return e>=65&&e<=90}function isLowercaseLetterCodePoint(e){return e>=97&&e<=122}function isHexDigitCodePoint(e){return isDigitCodePoint(e)||e>=97&&e<=102||e>=65&&e<=70}function isLetterCodePoint(e){return isLowercaseLetterCodePoint(e)||isUppercaseLetterCodePoint(e)}function isIdentStartCodePoint(e){return isLetterCodePoint(e)||isNonASCII_IdentCodePoint(e)||e===U}function isIdentCodePoint(e){return isIdentStartCodePoint(e)||isDigitCodePoint(e)||e===l}function isNonASCII_IdentCodePoint(e){return 183===e||8204===e||8205===e||8255===e||8256===e||8204===e||(192<=e&&e<=214||216<=e&&e<=246||248<=e&&e<=893||895<=e&&e<=8191||8304<=e&&e<=8591||11264<=e&&e<=12271||12289<=e&&e<=55295||63744<=e&&e<=64975||65008<=e&&e<=65533||e>=65536)}function isNewLine(e){return e===g||e===i||e===P}function isWhitespace(e){return e===H||e===g||e===s||e===i||e===P}function checkIfTwoCodePointsAreAValidEscape(e){return e.codePointSource[e.cursor]===W&&!isNewLine(e.codePointSource[e.cursor+1])}function checkIfThreeCodePointsWouldStartAnIdentSequence(e,n){return n.codePointSource[n.cursor]===l?n.codePointSource[n.cursor+1]===l||(!!isIdentStartCodePoint(n.codePointSource[n.cursor+1])||n.codePointSource[n.cursor+1]===W&&!isNewLine(n.codePointSource[n.cursor+2])):!!isIdentStartCodePoint(n.codePointSource[n.cursor])||checkIfTwoCodePointsAreAValidEscape(n)}function checkIfThreeCodePointsWouldStartANumber(e){return e.codePointSource[e.cursor]===L||e.codePointSource[e.cursor]===l?!!isDigitCodePoint(e.codePointSource[e.cursor+1])||e.codePointSource[e.cursor+1]===S&&isDigitCodePoint(e.codePointSource[e.cursor+2]):e.codePointSource[e.cursor]===S?isDigitCodePoint(e.codePointSource[e.cursor+1]):isDigitCodePoint(e.codePointSource[e.cursor])}function checkIfTwoCodePointsStartAComment(e){return e.codePointSource[e.cursor]===B&&e.codePointSource[e.cursor+1]===t}function checkIfThreeCodePointsWouldStartCDC(e){return e.codePointSource[e.cursor]===l&&e.codePointSource[e.cursor+1]===l&&e.codePointSource[e.cursor+2]===C}var G,X,Y;function mirrorVariantType(e){switch(e){case G.OpenParen:return G.CloseParen;case G.CloseParen:return G.OpenParen;case G.OpenCurly:return G.CloseCurly;case G.CloseCurly:return G.OpenCurly;case G.OpenSquare:return G.CloseSquare;case G.CloseSquare:return G.OpenSquare;default:return null}}function mirrorVariant(e){switch(e[0]){case G.OpenParen:return[G.CloseParen,")",-1,-1,void 0];case G.CloseParen:return[G.OpenParen,"(",-1,-1,void 0];case G.OpenCurly:return[G.CloseCurly,"}",-1,-1,void 0];case G.CloseCurly:return[G.OpenCurly,"{",-1,-1,void 0];case G.OpenSquare:return[G.CloseSquare,"]",-1,-1,void 0];case G.CloseSquare:return[G.OpenSquare,"[",-1,-1,void 0];default:return null}}function consumeComment(n,o){for(o.advanceCodePoint(2);;){const r=o.readCodePoint();if(!1===r){const t=[G.Comment,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInComment,o.representationStart,o.representationEnd,["4.3.2. Consume comments","Unexpected EOF"],t)),t}if(r===t&&(void 0!==o.codePointSource[o.cursor]&&o.codePointSource[o.cursor]===B)){o.advanceCodePoint();break}}return[G.Comment,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0]}function consumeEscapedCodePoint(n,o){const t=o.readCodePoint();if(!1===t)return n.onParseError(new ParseError(e.UnexpectedEOFInEscapedCodePoint,o.representationStart,o.representationEnd,["4.3.7. Consume an escaped code point","Unexpected EOF"])),x;if(isHexDigitCodePoint(t)){const e=[t];for(;void 0!==o.codePointSource[o.cursor]&&isHexDigitCodePoint(o.codePointSource[o.cursor])&&e.length<6;)e.push(o.codePointSource[o.cursor]),o.advanceCodePoint();isWhitespace(o.codePointSource[o.cursor])&&o.advanceCodePoint();const n=parseInt(String.fromCodePoint(...e),16);return 0===n?x:(r=n)>=55296&&r<=57343||n>O?x:n}var r;return t}function consumeIdentSequence(e,n){const o=[];for(;;)if(isIdentCodePoint(n.codePointSource[n.cursor]))o.push(n.codePointSource[n.cursor]),n.advanceCodePoint();else{if(!checkIfTwoCodePointsAreAValidEscape(n))return o;n.advanceCodePoint(),o.push(consumeEscapedCodePoint(e,n))}}function consumeHashToken(e,n){if(n.advanceCodePoint(),void 0!==n.codePointSource[n.cursor]&&(isIdentCodePoint(n.codePointSource[n.cursor])||checkIfTwoCodePointsAreAValidEscape(n))){let o=Y.Unrestricted;checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)&&(o=Y.ID);const t=consumeIdentSequence(e,n);return[G.Hash,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t),type:o}]}return[G.Delim,"#",n.representationStart,n.representationEnd,{value:"#"}]}function consumeNumber(e,n){let o=X.Integer;for(n.codePointSource[n.cursor]!==L&&n.codePointSource[n.cursor]!==l||n.advanceCodePoint();isDigitCodePoint(n.codePointSource[n.cursor]);)n.advanceCodePoint();if(n.codePointSource[n.cursor]===S&&isDigitCodePoint(n.codePointSource[n.cursor+1]))for(n.advanceCodePoint(2),o=X.Number;isDigitCodePoint(n.codePointSource[n.cursor]);)n.advanceCodePoint();if(n.codePointSource[n.cursor]===h||n.codePointSource[n.cursor]===m){if(isDigitCodePoint(n.codePointSource[n.cursor+1]))n.advanceCodePoint(2);else{if(n.codePointSource[n.cursor+1]!==l&&n.codePointSource[n.cursor+1]!==L||!isDigitCodePoint(n.codePointSource[n.cursor+2]))return o;n.advanceCodePoint(3)}for(o=X.Number;isDigitCodePoint(n.codePointSource[n.cursor]);)n.advanceCodePoint()}return o}function consumeNumericToken(e,n){let o;{const e=n.codePointSource[n.cursor];e===l?o="-":e===L&&(o="+")}const t=consumeNumber(0,n),r=parseFloat(n.source.slice(n.representationStart,n.representationEnd+1));if(checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)){const i=consumeIdentSequence(e,n);return[G.Dimension,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o,type:t,unit:String.fromCodePoint(...i)}]}return n.codePointSource[n.cursor]===w?(n.advanceCodePoint(),[G.Percentage,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o}]):[G.Number,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o,type:t}]}function consumeWhiteSpace(e){for(;isWhitespace(e.codePointSource[e.cursor]);)e.advanceCodePoint();return[G.Whitespace,e.source.slice(e.representationStart,e.representationEnd+1),e.representationStart,e.representationEnd,void 0]}function consumeStringToken(n,o){let t="";const r=o.readCodePoint();for(;;){const s=o.readCodePoint();if(!1===s){const r=[G.String,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInString,o.representationStart,o.representationEnd,["4.3.5. Consume a string token","Unexpected EOF"],r)),r}if(isNewLine(s)){o.unreadCodePoint();const t=[G.BadString,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedNewLineInString,o.representationStart,o.codePointSource[o.cursor]===i&&o.codePointSource[o.cursor+1]===g?o.representationEnd+2:o.representationEnd+1,["4.3.5. Consume a string token","Unexpected newline"],t)),t}if(s===r)return[G.String,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t}];if(s!==W)t+=String.fromCodePoint(s);else{if(void 0===o.codePointSource[o.cursor])continue;if(isNewLine(o.codePointSource[o.cursor])){o.codePointSource[o.cursor]===i&&o.codePointSource[o.cursor+1]===g&&o.advanceCodePoint(),o.advanceCodePoint();continue}t+=String.fromCodePoint(consumeEscapedCodePoint(n,o))}}}function checkIfCodePointsMatchURLIdent(e){return!(3!==e.length||e[0]!==V&&e[0]!==K||e[1]!==z&&e[1]!==M||e[2]!==$&&e[2]!==J)}function consumeBadURL(e,n){for(;;){if(void 0===n.codePointSource[n.cursor])return;if(n.codePointSource[n.cursor]===F)return void n.advanceCodePoint();checkIfTwoCodePointsAreAValidEscape(n)?(n.advanceCodePoint(),consumeEscapedCodePoint(e,n)):n.advanceCodePoint()}}function consumeUrlToken(n,t){for(;isWhitespace(t.codePointSource[t.cursor]);)t.advanceCodePoint();let i="";for(;;){if(void 0===t.codePointSource[t.cursor]){const o=[G.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:i}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Unexpected EOF"],o)),o}if(t.codePointSource[t.cursor]===F)return t.advanceCodePoint(),[G.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:i}];if(isWhitespace(t.codePointSource[t.cursor])){for(t.advanceCodePoint();isWhitespace(t.codePointSource[t.cursor]);)t.advanceCodePoint();if(void 0===t.codePointSource[t.cursor]){const o=[G.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:i}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Consume as much whitespace as possible","Unexpected EOF"],o)),o}return t.codePointSource[t.cursor]===F?(t.advanceCodePoint(),[G.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:i}]):(consumeBadURL(n,t),[G.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0])}if(t.codePointSource[t.cursor]===A||t.codePointSource[t.cursor]===o||t.codePointSource[t.cursor]===E||((s=t.codePointSource[t.cursor])===I||s===d||D<=s&&s<=r||b<=s&&s<=f)){consumeBadURL(n,t);const o=[G.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedCharacterInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Unexpected U+0022 QUOTATION MARK (\"), U+0027 APOSTROPHE ('), U+0028 LEFT PARENTHESIS (() or non-printable code point"],o)),o}if(t.codePointSource[t.cursor]===W){if(checkIfTwoCodePointsAreAValidEscape(t)){t.advanceCodePoint(),i+=String.fromCodePoint(consumeEscapedCodePoint(n,t));continue}consumeBadURL(n,t);const o=[G.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],o)),o}i+=String.fromCodePoint(t.codePointSource[t.cursor]),t.advanceCodePoint()}var s}function consumeIdentLikeToken(e,n){const t=consumeIdentSequence(e,n);if(n.codePointSource[n.cursor]!==E)return[G.Ident,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}];if(checkIfCodePointsMatchURLIdent(t)){n.advanceCodePoint();let r=0;for(;;){const e=isWhitespace(n.codePointSource[n.cursor]),i=isWhitespace(n.codePointSource[n.cursor+1]);if(e&&i){r+=1,n.advanceCodePoint(1);continue}const s=e?n.codePointSource[n.cursor+1]:n.codePointSource[n.cursor];if(s===A||s===o)return r>0&&n.unreadCodePoint(r),[G.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}];break}return consumeUrlToken(e,n)}return n.advanceCodePoint(),[G.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}]}function checkIfThreeCodePointsWouldStartAUnicodeRange(e){return!(e.codePointSource[e.cursor]!==V&&e.codePointSource[e.cursor]!==K||e.codePointSource[e.cursor+1]!==L||e.codePointSource[e.cursor+2]!==_&&!isHexDigitCodePoint(e.codePointSource[e.cursor+2]))}function consumeUnicodeRangeToken(e,n){n.advanceCodePoint(2);const o=[],t=[];for(;void 0!==n.codePointSource[n.cursor]&&o.length<6&&isHexDigitCodePoint(n.codePointSource[n.cursor]);)o.push(n.codePointSource[n.cursor]),n.advanceCodePoint();for(;void 0!==n.codePointSource[n.cursor]&&o.length<6&&n.codePointSource[n.cursor]===_;)0===t.length&&t.push(...o),o.push(j),t.push(Q),n.advanceCodePoint();if(!t.length&&n.codePointSource[n.cursor]===l&&isHexDigitCodePoint(n.codePointSource[n.cursor+1]))for(n.advanceCodePoint();void 0!==n.codePointSource[n.cursor]&&t.length<6&&isHexDigitCodePoint(n.codePointSource[n.cursor]);)t.push(n.codePointSource[n.cursor]),n.advanceCodePoint();if(!t.length){const e=parseInt(String.fromCodePoint(...o),16);return[G.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:e,endOfRange:e}]}const r=parseInt(String.fromCodePoint(...o),16),i=parseInt(String.fromCodePoint(...t),16);return[G.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:r,endOfRange:i}]}function tokenize(e,n){const o=tokenizer(e,n),t=[];{for(;!o.endOfFile();){const e=o.nextToken();e&&t.push(e)}const e=o.nextToken();e&&t.push(e)}return t}function tokenizer(n,t){const r=n.css.valueOf(),d=n.unicodeRangesAllowed??!1,p=new Reader(r),C={onParseError:t?.onParseError??noop};return{nextToken:function nextToken(){p.resetRepresentation();const n=p.codePointSource[p.cursor];if(void 0===n)return[G.EOF,"",-1,-1,void 0];if(n===B&&checkIfTwoCodePointsStartAComment(p))return consumeComment(C,p);if(d&&(n===V||n===K)&&checkIfThreeCodePointsWouldStartAUnicodeRange(p))return consumeUnicodeRangeToken(0,p);if(isIdentStartCodePoint(n))return consumeIdentLikeToken(C,p);if(isDigitCodePoint(n))return consumeNumericToken(C,p);switch(n){case a:return p.advanceCodePoint(),[G.Comma,",",p.representationStart,p.representationEnd,void 0];case c:return p.advanceCodePoint(),[G.Colon,":",p.representationStart,p.representationEnd,void 0];case N:return p.advanceCodePoint(),[G.Semicolon,";",p.representationStart,p.representationEnd,void 0];case E:return p.advanceCodePoint(),[G.OpenParen,"(",p.representationStart,p.representationEnd,void 0];case F:return p.advanceCodePoint(),[G.CloseParen,")",p.representationStart,p.representationEnd,void 0];case T:return p.advanceCodePoint(),[G.OpenSquare,"[",p.representationStart,p.representationEnd,void 0];case q:return p.advanceCodePoint(),[G.CloseSquare,"]",p.representationStart,p.representationEnd,void 0];case k:return p.advanceCodePoint(),[G.OpenCurly,"{",p.representationStart,p.representationEnd,void 0];case y:return p.advanceCodePoint(),[G.CloseCurly,"}",p.representationStart,p.representationEnd,void 0];case o:case A:return consumeStringToken(C,p);case R:return consumeHashToken(C,p);case L:case S:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(C,p):(p.advanceCodePoint(),[G.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]);case g:case i:case P:case s:case H:return consumeWhiteSpace(p);case l:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(C,p):checkIfThreeCodePointsWouldStartCDC(p)?(p.advanceCodePoint(3),[G.CDC,"--\x3e",p.representationStart,p.representationEnd,void 0]):checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)?consumeIdentLikeToken(C,p):(p.advanceCodePoint(),[G.Delim,"-",p.representationStart,p.representationEnd,{value:"-"}]);case v:return checkIfFourCodePointsWouldStartCDO(p)?(p.advanceCodePoint(4),[G.CDO,"\x3c!--",p.representationStart,p.representationEnd,void 0]):(p.advanceCodePoint(),[G.Delim,"<",p.representationStart,p.representationEnd,{value:"<"}]);case u:if(p.advanceCodePoint(),checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)){const e=consumeIdentSequence(C,p);return[G.AtKeyword,p.source.slice(p.representationStart,p.representationEnd+1),p.representationStart,p.representationEnd,{value:String.fromCodePoint(...e)}]}return[G.Delim,"@",p.representationStart,p.representationEnd,{value:"@"}];case W:{if(checkIfTwoCodePointsAreAValidEscape(p))return consumeIdentLikeToken(C,p);p.advanceCodePoint();const n=[G.Delim,"\\",p.representationStart,p.representationEnd,{value:"\\"}];return C.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceAfterBackslash,p.representationStart,p.representationEnd,["4.3.1. Consume a token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],n)),n}}return p.advanceCodePoint(),[G.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]},endOfFile:function endOfFile(){return void 0===p.codePointSource[p.cursor]}}}function noop(){}function mutateIdent(e,n){const o=[];for(const e of n)o.push(e.codePointAt(0));const t=String.fromCodePoint(...ensureThatValueRoundTripsAsIdent(o));e[1]=t,e[4].value=n}function mutateUnit(e,n){const o=[];for(const e of n)o.push(e.codePointAt(0));const t=ensureThatValueRoundTripsAsIdent(o);101===t[0]&&insertEscapedCodePoint(t,0,t[0]);const r=String.fromCodePoint(...t),i="+"===e[4].signCharacter?e[4].signCharacter:"",s=e[4].value.toString();e[1]=`${i}${s}${r}`,e[4].unit=n}function ensureThatValueRoundTripsAsIdent(e){let n=0;e[0]===l&&e[1]===l?n=2:e[0]===l&&e[1]?(n=2,isIdentStartCodePoint(e[1])||(n+=insertEscapedCodePoint(e,1,e[1]))):isIdentStartCodePoint(e[0])?n=1:(n=1,n+=insertEscapedCodePoint(e,0,e[0]));for(let o=n;o=48&&e<=57}function isUppercaseLetterCodePoint(e){return void 0!==e&&e>=65&&e<=90}function isLowercaseLetterCodePoint(e){return void 0!==e&&e>=97&&e<=122}function isHexDigitCodePoint(e){return void 0!==e&&(e>=48&&e<=57||e>=97&&e<=102||e>=65&&e<=70)}function isLetterCodePoint(e){return isLowercaseLetterCodePoint(e)||isUppercaseLetterCodePoint(e)}function isIdentStartCodePoint(e){return isLetterCodePoint(e)||isNonASCII_IdentCodePoint(e)||e===I}function isIdentCodePoint(e){return isIdentStartCodePoint(e)||isDigitCodePoint(e)||e===f}function isNonASCII_IdentCodePoint(e){return 183===e||8204===e||8205===e||8255===e||8256===e||8204===e||void 0!==e&&(192<=e&&e<=214||216<=e&&e<=246||248<=e&&e<=893||895<=e&&e<=8191||8304<=e&&e<=8591||11264<=e&&e<=12271||12289<=e&&e<=55295||63744<=e&&e<=64975||65008<=e&&e<=65533||e>=65536)}function isNewLine(e){return e===A||e===i||e===P}function isWhitespace(e){return e===H||e===A||e===s||e===i||e===P}function checkIfTwoCodePointsAreAValidEscape(e){return e.source.codePointAt(e.cursor)===W&&!isNewLine(e.source.codePointAt(e.cursor+1))}function checkIfThreeCodePointsWouldStartAnIdentSequence(e,n){return n.source.codePointAt(n.cursor)===f?n.source.codePointAt(n.cursor+1)===f||(!!isIdentStartCodePoint(n.source.codePointAt(n.cursor+1))||n.source.codePointAt(n.cursor+1)===W&&!isNewLine(n.source.codePointAt(n.cursor+2))):!!isIdentStartCodePoint(n.source.codePointAt(n.cursor))||checkIfTwoCodePointsAreAValidEscape(n)}function checkIfThreeCodePointsWouldStartANumber(e){return e.source.codePointAt(e.cursor)===w||e.source.codePointAt(e.cursor)===f?!!isDigitCodePoint(e.source.codePointAt(e.cursor+1))||e.source.codePointAt(e.cursor+1)===C&&isDigitCodePoint(e.source.codePointAt(e.cursor+2)):e.source.codePointAt(e.cursor)===C?isDigitCodePoint(e.source.codePointAt(e.cursor+1)):isDigitCodePoint(e.source.codePointAt(e.cursor))}function checkIfTwoCodePointsStartAComment(e){return e.source.codePointAt(e.cursor)===B&&e.source.codePointAt(e.cursor+1)===o}function checkIfThreeCodePointsWouldStartCDC(e){return e.source.codePointAt(e.cursor)===f&&e.source.codePointAt(e.cursor+1)===f&&e.source.codePointAt(e.cursor+2)===l}var G,X,Y;function mirrorVariantType(e){switch(e){case G.OpenParen:return G.CloseParen;case G.CloseParen:return G.OpenParen;case G.OpenCurly:return G.CloseCurly;case G.CloseCurly:return G.OpenCurly;case G.OpenSquare:return G.CloseSquare;case G.CloseSquare:return G.OpenSquare;default:return null}}function mirrorVariant(e){switch(e[0]){case G.OpenParen:return[G.CloseParen,")",-1,-1,void 0];case G.CloseParen:return[G.OpenParen,"(",-1,-1,void 0];case G.OpenCurly:return[G.CloseCurly,"}",-1,-1,void 0];case G.CloseCurly:return[G.OpenCurly,"{",-1,-1,void 0];case G.OpenSquare:return[G.CloseSquare,"]",-1,-1,void 0];case G.CloseSquare:return[G.OpenSquare,"[",-1,-1,void 0];default:return null}}function consumeComment(n,t){for(t.advanceCodePoint(2);;){const r=t.readCodePoint();if(void 0===r){const o=[G.Comment,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInComment,t.representationStart,t.representationEnd,["4.3.2. Consume comments","Unexpected EOF"],o)),o}if(r===o&&(void 0!==t.source.codePointAt(t.cursor)&&t.source.codePointAt(t.cursor)===B)){t.advanceCodePoint();break}}return[G.Comment,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0]}function consumeEscapedCodePoint(n,t){const o=t.readCodePoint();if(void 0===o)return n.onParseError(new ParseError(e.UnexpectedEOFInEscapedCodePoint,t.representationStart,t.representationEnd,["4.3.7. Consume an escaped code point","Unexpected EOF"])),x;if(isHexDigitCodePoint(o)){const e=[o];let n;for(;void 0!==(n=t.source.codePointAt(t.cursor))&&isHexDigitCodePoint(n)&&e.length<6;)e.push(n),t.advanceCodePoint();isWhitespace(t.source.codePointAt(t.cursor))&&t.advanceCodePoint();const i=parseInt(String.fromCodePoint(...e),16);return 0===i?x:void 0!==(r=i)&&r>=55296&&r<=57343||i>U?x:i}var r;return o}function consumeIdentSequence(e,n){const t=[];for(;;){const o=n.source.codePointAt(n.cursor);if(isIdentCodePoint(o))t.push(o),n.advanceCodePoint(+(o>65535)+1);else{if(!checkIfTwoCodePointsAreAValidEscape(n))return t;n.advanceCodePoint(),t.push(consumeEscapedCodePoint(e,n))}}}function consumeHashToken(e,n){n.advanceCodePoint();const t=n.source.codePointAt(n.cursor);if(void 0!==t&&(isIdentCodePoint(t)||checkIfTwoCodePointsAreAValidEscape(n))){let t=Y.Unrestricted;checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)&&(t=Y.ID);const o=consumeIdentSequence(e,n);return[G.Hash,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o),type:t}]}return[G.Delim,"#",n.representationStart,n.representationEnd,{value:"#"}]}function consumeNumber(e,n){let t=X.Integer;for(n.source.codePointAt(n.cursor)!==w&&n.source.codePointAt(n.cursor)!==f||n.advanceCodePoint();isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===C&&isDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint(2),t=X.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===k||n.source.codePointAt(n.cursor)===m){if(isDigitCodePoint(n.source.codePointAt(n.cursor+1)))n.advanceCodePoint(2);else{if(n.source.codePointAt(n.cursor+1)!==f&&n.source.codePointAt(n.cursor+1)!==w||!isDigitCodePoint(n.source.codePointAt(n.cursor+2)))return t;n.advanceCodePoint(3)}for(t=X.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint()}return t}function consumeNumericToken(e,n){let t;{const e=n.source.codePointAt(n.cursor);e===f?t="-":e===w&&(t="+")}const o=consumeNumber(0,n),r=parseFloat(n.source.slice(n.representationStart,n.representationEnd+1));if(checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)){const i=consumeIdentSequence(e,n);return[G.Dimension,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:t,type:o,unit:String.fromCodePoint(...i)}]}return n.source.codePointAt(n.cursor)===R?(n.advanceCodePoint(),[G.Percentage,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:t}]):[G.Number,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:t,type:o}]}function consumeWhiteSpace(e){for(;isWhitespace(e.source.codePointAt(e.cursor));)e.advanceCodePoint();return[G.Whitespace,e.source.slice(e.representationStart,e.representationEnd+1),e.representationStart,e.representationEnd,void 0]}function consumeStringToken(n,t){let o="";const r=t.readCodePoint();for(;;){const s=t.readCodePoint();if(void 0===s){const r=[G.String,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:o}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInString,t.representationStart,t.representationEnd,["4.3.5. Consume a string token","Unexpected EOF"],r)),r}if(isNewLine(s)){t.unreadCodePoint();const o=[G.BadString,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedNewLineInString,t.representationStart,t.source.codePointAt(t.cursor)===i&&t.source.codePointAt(t.cursor+1)===A?t.representationEnd+2:t.representationEnd+1,["4.3.5. Consume a string token","Unexpected newline"],o)),o}if(s===r)return[G.String,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:o}];if(s!==W)o+=String.fromCodePoint(s);else{if(void 0===t.source.codePointAt(t.cursor))continue;if(isNewLine(t.source.codePointAt(t.cursor))){t.source.codePointAt(t.cursor)===i&&t.source.codePointAt(t.cursor+1)===A&&t.advanceCodePoint(),t.advanceCodePoint();continue}o+=String.fromCodePoint(consumeEscapedCodePoint(n,t))}}}function checkIfCodePointsMatchURLIdent(e){return!(3!==e.length||e[0]!==V&&e[0]!==K||e[1]!==z&&e[1]!==M||e[2]!==$&&e[2]!==J)}function consumeBadURL(e,n){for(;;){const t=n.source.codePointAt(n.cursor);if(void 0===t)return;if(t===F)return void n.advanceCodePoint();checkIfTwoCodePointsAreAValidEscape(n)?(n.advanceCodePoint(),consumeEscapedCodePoint(e,n)):n.advanceCodePoint()}}function consumeUrlToken(n,o){for(;isWhitespace(o.source.codePointAt(o.cursor));)o.advanceCodePoint();let i="";for(;;){if(void 0===o.source.codePointAt(o.cursor)){const t=[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","Unexpected EOF"],t)),t}if(o.source.codePointAt(o.cursor)===F)return o.advanceCodePoint(),[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}];if(isWhitespace(o.source.codePointAt(o.cursor))){for(o.advanceCodePoint();isWhitespace(o.source.codePointAt(o.cursor));)o.advanceCodePoint();if(void 0===o.source.codePointAt(o.cursor)){const t=[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","Consume as much whitespace as possible","Unexpected EOF"],t)),t}return o.source.codePointAt(o.cursor)===F?(o.advanceCodePoint(),[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}]):(consumeBadURL(n,o),[G.BadURL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0])}const c=o.source.codePointAt(o.cursor);if(c===L||c===t||c===h||void 0!==(s=c)&&(s===g||s===d||O<=s&&s<=r||b<=s&&s<=S)){consumeBadURL(n,o);const t=[G.BadURL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedCharacterInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","Unexpected U+0022 QUOTATION MARK (\"), U+0027 APOSTROPHE ('), U+0028 LEFT PARENTHESIS (() or non-printable code point"],t)),t}if(c===W){if(checkIfTwoCodePointsAreAValidEscape(o)){o.advanceCodePoint(),i+=String.fromCodePoint(consumeEscapedCodePoint(n,o));continue}consumeBadURL(n,o);const t=[G.BadURL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],t)),t}i+=o.source[o.cursor],o.advanceCodePoint()}var s}function consumeIdentLikeToken(e,n){const o=consumeIdentSequence(e,n);if(n.source.codePointAt(n.cursor)!==h)return[G.Ident,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o)}];if(checkIfCodePointsMatchURLIdent(o)){n.advanceCodePoint();let r=0;for(;;){const e=isWhitespace(n.source.codePointAt(n.cursor)),i=isWhitespace(n.source.codePointAt(n.cursor+1));if(e&&i){r+=1,n.advanceCodePoint(1);continue}const s=e?n.source.codePointAt(n.cursor+1):n.source.codePointAt(n.cursor);if(s===L||s===t)return r>0&&n.unreadCodePoint(r),[G.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o)}];break}return consumeUrlToken(e,n)}return n.advanceCodePoint(),[G.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o)}]}function checkIfThreeCodePointsWouldStartAUnicodeRange(e){return!(e.source.codePointAt(e.cursor)!==V&&e.source.codePointAt(e.cursor)!==K||e.source.codePointAt(e.cursor+1)!==w||e.source.codePointAt(e.cursor+2)!==_&&!isHexDigitCodePoint(e.source.codePointAt(e.cursor+2)))}function consumeUnicodeRangeToken(e,n){n.advanceCodePoint(2);const t=[],o=[];let r;for(;void 0!==(r=n.source.codePointAt(n.cursor))&&t.length<6&&isHexDigitCodePoint(r);)t.push(r),n.advanceCodePoint();for(;void 0!==(r=n.source.codePointAt(n.cursor))&&t.length<6&&r===_;)0===o.length&&o.push(...t),t.push(j),o.push(Q),n.advanceCodePoint();if(!o.length&&n.source.codePointAt(n.cursor)===f&&isHexDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint();void 0!==(r=n.source.codePointAt(n.cursor))&&o.length<6&&isHexDigitCodePoint(r);)o.push(r),n.advanceCodePoint();if(!o.length){const e=parseInt(String.fromCodePoint(...t),16);return[G.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:e,endOfRange:e}]}const i=parseInt(String.fromCodePoint(...t),16),s=parseInt(String.fromCodePoint(...o),16);return[G.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:i,endOfRange:s}]}function tokenize(e,n){const t=tokenizer(e,n),o=[];{for(;!t.endOfFile();){const e=t.nextToken();e&&o.push(e)}const e=t.nextToken();e&&o.push(e)}return o}function tokenizer(n,o){const r=n.css.valueOf(),d=n.unicodeRangesAllowed??!1,p=new Reader(r),l={onParseError:o?.onParseError??noop};return{nextToken:function nextToken(){p.resetRepresentation();const n=p.source.codePointAt(p.cursor);if(void 0===n)return[G.EOF,"",-1,-1,void 0];if(n===B&&checkIfTwoCodePointsStartAComment(p))return consumeComment(l,p);if(d&&(n===V||n===K)&&checkIfThreeCodePointsWouldStartAUnicodeRange(p))return consumeUnicodeRangeToken(0,p);if(isIdentStartCodePoint(n))return consumeIdentLikeToken(l,p);if(isDigitCodePoint(n))return consumeNumericToken(l,p);switch(n){case a:return p.advanceCodePoint(),[G.Comma,",",p.representationStart,p.representationEnd,void 0];case c:return p.advanceCodePoint(),[G.Colon,":",p.representationStart,p.representationEnd,void 0];case N:return p.advanceCodePoint(),[G.Semicolon,";",p.representationStart,p.representationEnd,void 0];case h:return p.advanceCodePoint(),[G.OpenParen,"(",p.representationStart,p.representationEnd,void 0];case F:return p.advanceCodePoint(),[G.CloseParen,")",p.representationStart,p.representationEnd,void 0];case v:return p.advanceCodePoint(),[G.OpenSquare,"[",p.representationStart,p.representationEnd,void 0];case q:return p.advanceCodePoint(),[G.CloseSquare,"]",p.representationStart,p.representationEnd,void 0];case E:return p.advanceCodePoint(),[G.OpenCurly,"{",p.representationStart,p.representationEnd,void 0];case y:return p.advanceCodePoint(),[G.CloseCurly,"}",p.representationStart,p.representationEnd,void 0];case t:case L:return consumeStringToken(l,p);case D:return consumeHashToken(l,p);case w:case C:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(l,p):(p.advanceCodePoint(),[G.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]);case A:case i:case P:case s:case H:return consumeWhiteSpace(p);case f:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(l,p):checkIfThreeCodePointsWouldStartCDC(p)?(p.advanceCodePoint(3),[G.CDC,"--\x3e",p.representationStart,p.representationEnd,void 0]):checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)?consumeIdentLikeToken(l,p):(p.advanceCodePoint(),[G.Delim,"-",p.representationStart,p.representationEnd,{value:"-"}]);case T:return checkIfFourCodePointsWouldStartCDO(p)?(p.advanceCodePoint(4),[G.CDO,"\x3c!--",p.representationStart,p.representationEnd,void 0]):(p.advanceCodePoint(),[G.Delim,"<",p.representationStart,p.representationEnd,{value:"<"}]);case u:if(p.advanceCodePoint(),checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)){const e=consumeIdentSequence(l,p);return[G.AtKeyword,p.source.slice(p.representationStart,p.representationEnd+1),p.representationStart,p.representationEnd,{value:String.fromCodePoint(...e)}]}return[G.Delim,"@",p.representationStart,p.representationEnd,{value:"@"}];case W:{if(checkIfTwoCodePointsAreAValidEscape(p))return consumeIdentLikeToken(l,p);p.advanceCodePoint();const n=[G.Delim,"\\",p.representationStart,p.representationEnd,{value:"\\"}];return l.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceAfterBackslash,p.representationStart,p.representationEnd,["4.3.1. Consume a token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],n)),n}}return p.advanceCodePoint(),[G.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]},endOfFile:function endOfFile(){return void 0===p.source.codePointAt(p.cursor)}}}function noop(){}function mutateIdent(e,n){const t=[];for(const e of n)t.push(e.codePointAt(0));const o=String.fromCodePoint(...ensureThatValueRoundTripsAsIdent(t));e[1]=o,e[4].value=n}function mutateUnit(e,n){const t=[];for(const e of n)t.push(e.codePointAt(0));const o=ensureThatValueRoundTripsAsIdent(t);101===o[0]&&insertEscapedCodePoint(o,0,o[0]);const r=String.fromCodePoint(...o),i="+"===e[4].signCharacter?e[4].signCharacter:"",s=e[4].value.toString();e[1]=`${i}${s}${r}`,e[4].unit=n}function ensureThatValueRoundTripsAsIdent(e){let n=0;e[0]===f&&e[1]===f?n=2:e[0]===f&&e[1]?(n=2,isIdentStartCodePoint(e[1])||(n+=insertEscapedCodePoint(e,1,e[1]))):isIdentStartCodePoint(e[0])?n=1:(n=1,n+=insertEscapedCodePoint(e,0,e[0]));for(let t=n;t= 0x0030 && search <= 0x0039; +export function isDigitCodePoint(search: number | undefined): search is number { + return (typeof search !== "undefined") && search >= 0x0030 && search <= 0x0039; } // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#uppercase-letter -function isUppercaseLetterCodePoint(search: number): boolean { - return search >= 0x0041 && search <= 0x005a; +function isUppercaseLetterCodePoint(search: number | undefined): search is number { + return (typeof search !== "undefined") && search >= 0x0041 && search <= 0x005a; } // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#lowercase-letter -function isLowercaseLetterCodePoint(search: number): boolean { - return search >= 0x0061 && search <= 0x007a; +function isLowercaseLetterCodePoint(search: number | undefined): search is number { + return (typeof search !== "undefined") && search >= 0x0061 && search <= 0x007a; } // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#hex-digit -export function isHexDigitCodePoint(search: number): boolean { - return ( - isDigitCodePoint(search) || // 0 .. 9 +export function isHexDigitCodePoint(search: number | undefined): search is number { + return (typeof search !== "undefined") && ( + (search >= 0x0030 && search <= 0x0039) || // 0 .. 9 (search >= 0x0061 && search <= 0x0066) || // a .. f (search >= 0x0041 && search <= 0x0046) // A .. F ); } // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#letter -function isLetterCodePoint(search: number): boolean { +function isLetterCodePoint(search: number | undefined): search is number { return isLowercaseLetterCodePoint(search) || isUppercaseLetterCodePoint(search); } // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#ident-start-code-point -export function isIdentStartCodePoint(search: number): boolean { +export function isIdentStartCodePoint(search: number | undefined): search is number { return isLetterCodePoint(search) || isNonASCII_IdentCodePoint(search) || search === LOW_LINE; } // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#ident-code-point -export function isIdentCodePoint(search: number): boolean { +export function isIdentCodePoint(search: number | undefined): search is number { return isIdentStartCodePoint(search) || isDigitCodePoint(search) || search === HYPHEN_MINUS; } // https://drafts.csswg.org/css-syntax/#non-ascii-ident-code-point -function isNonASCII_IdentCodePoint(search: number): boolean { +function isNonASCII_IdentCodePoint(search: number | undefined): search is number { if ( search === 0x00B7 || search === 0x200C || @@ -53,6 +53,10 @@ function isNonASCII_IdentCodePoint(search: number): boolean { return true; } + if (typeof search === "undefined") { + return false; + } + if ( (0x00C0 <= search && search <= 0x00D6) || (0x00D8 <= search && search <= 0x00F6) || @@ -71,8 +75,8 @@ function isNonASCII_IdentCodePoint(search: number): boolean { } // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#non-printable-code-point -export function isNonPrintableCodePoint(search: number): boolean { - return ( +export function isNonPrintableCodePoint(search: number | undefined): search is number { + return (typeof search !== "undefined") &&( (search === LINE_TABULATION) || (search === DELETE) || (NULL <= search && search <= BACKSPACE) || @@ -81,16 +85,16 @@ export function isNonPrintableCodePoint(search: number): boolean { } // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#whitespace -export function isNewLine(search: number): boolean { +export function isNewLine(search: number | undefined): search is number { return search === LINE_FEED || search === CARRIAGE_RETURN || search === FORM_FEED; } // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#whitespace -export function isWhitespace(search: number): boolean { +export function isWhitespace(search: number | undefined): search is number { return search === SPACE || search === LINE_FEED || search === CHARACTER_TABULATION || search === CARRIAGE_RETURN || search === FORM_FEED; } // https://infra.spec.whatwg.org/#surrogate -export function isSurrogate(search: number): boolean { - return search >= 0xd800 && search <= 0xdfff; +export function isSurrogate(search: number | undefined): search is number { + return (typeof search !== "undefined") && search >= 0xd800 && search <= 0xdfff; } diff --git a/packages/css-tokenizer/src/consume/bad-url.ts b/packages/css-tokenizer/src/consume/bad-url.ts index 591f12a3e..20981e5cb 100644 --- a/packages/css-tokenizer/src/consume/bad-url.ts +++ b/packages/css-tokenizer/src/consume/bad-url.ts @@ -7,11 +7,12 @@ import { consumeEscapedCodePoint } from './escaped-code-point'; // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#consume-remnants-of-bad-url export function consumeBadURL(ctx: Context, reader: CodePointReader): void { while (true) { - if (reader.codePointSource[reader.cursor] === undefined) { + const codePoint = reader.source.codePointAt(reader.cursor); + if (typeof codePoint === "undefined") { return; } - if (reader.codePointSource[reader.cursor] === RIGHT_PARENTHESIS) { + if (codePoint === RIGHT_PARENTHESIS) { reader.advanceCodePoint(); return; } diff --git a/packages/css-tokenizer/src/consume/comment.ts b/packages/css-tokenizer/src/consume/comment.ts index 94c31d7ac..02c4d6b25 100644 --- a/packages/css-tokenizer/src/consume/comment.ts +++ b/packages/css-tokenizer/src/consume/comment.ts @@ -11,7 +11,7 @@ export function consumeComment(ctx: Context, reader: CodePointReader): TokenComm while (true) { const codePoint = reader.readCodePoint(); - if (codePoint === false) { + if (typeof codePoint === "undefined") { const token: CSSToken = [ TokenType.Comment, reader.source.slice(reader.representationStart, reader.representationEnd + 1), @@ -38,11 +38,11 @@ export function consumeComment(ctx: Context, reader: CodePointReader): TokenComm continue; } - if (reader.codePointSource[reader.cursor] === undefined) { + if (typeof reader.source.codePointAt(reader.cursor) === "undefined") { continue; } - if (reader.codePointSource[reader.cursor] === SOLIDUS) { + if (reader.source.codePointAt(reader.cursor) === SOLIDUS) { reader.advanceCodePoint(); break; } diff --git a/packages/css-tokenizer/src/consume/escaped-code-point.ts b/packages/css-tokenizer/src/consume/escaped-code-point.ts index 51814c1f9..bf4f8fef6 100644 --- a/packages/css-tokenizer/src/consume/escaped-code-point.ts +++ b/packages/css-tokenizer/src/consume/escaped-code-point.ts @@ -7,7 +7,7 @@ import { ParseError, ParseErrorMessage } from '../interfaces/error'; // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#consume-escaped-code-point export function consumeEscapedCodePoint(ctx: Context, reader: CodePointReader): number { const codePoint = reader.readCodePoint(); - if (codePoint === false) { + if (typeof codePoint === "undefined") { ctx.onParseError(new ParseError( ParseErrorMessage.UnexpectedEOFInEscapedCodePoint, reader.representationStart, @@ -24,12 +24,13 @@ export function consumeEscapedCodePoint(ctx: Context, reader: CodePointReader): if (isHexDigitCodePoint(codePoint)) { const hexSequence: Array = [codePoint]; - while ((reader.codePointSource[reader.cursor] !== undefined) && isHexDigitCodePoint(reader.codePointSource[reader.cursor]) && hexSequence.length < 6) { - hexSequence.push(reader.codePointSource[reader.cursor]); + let nextCodePoint: number | undefined; + while ((typeof (nextCodePoint = reader.source.codePointAt(reader.cursor)) !== "undefined") && isHexDigitCodePoint(nextCodePoint) && hexSequence.length < 6) { + hexSequence.push(nextCodePoint); reader.advanceCodePoint(); } - if (isWhitespace(reader.codePointSource[reader.cursor])) { + if (isWhitespace(reader.source.codePointAt(reader.cursor))) { reader.advanceCodePoint(); } diff --git a/packages/css-tokenizer/src/consume/hash-token.ts b/packages/css-tokenizer/src/consume/hash-token.ts index b4ef6e413..3f04ea9ea 100644 --- a/packages/css-tokenizer/src/consume/hash-token.ts +++ b/packages/css-tokenizer/src/consume/hash-token.ts @@ -11,9 +11,10 @@ import { consumeIdentSequence } from './ident-sequence'; export function consumeHashToken(ctx: Context, reader: CodePointReader): TokenDelim|TokenHash { reader.advanceCodePoint(); + const codePoint = reader.source.codePointAt(reader.cursor); if ( - (reader.codePointSource[reader.cursor] !== undefined) && ( - isIdentCodePoint(reader.codePointSource[reader.cursor]) || + (typeof codePoint !== "undefined") && ( + isIdentCodePoint(codePoint) || checkIfTwoCodePointsAreAValidEscape(reader) ) ) { diff --git a/packages/css-tokenizer/src/consume/ident-like-token.ts b/packages/css-tokenizer/src/consume/ident-like-token.ts index fe4c2bfb9..9b794b9a1 100644 --- a/packages/css-tokenizer/src/consume/ident-like-token.ts +++ b/packages/css-tokenizer/src/consume/ident-like-token.ts @@ -12,7 +12,7 @@ import { consumeUrlToken } from './url-token'; export function consumeIdentLikeToken(ctx: Context, reader: CodePointReader): TokenIdent | TokenFunction | TokenURL | TokenBadURL { const codePoints = consumeIdentSequence(ctx, reader); - if (reader.codePointSource[reader.cursor] !== LEFT_PARENTHESIS) { + if (reader.source.codePointAt(reader.cursor) !== LEFT_PARENTHESIS) { return [ TokenType.Ident, reader.source.slice(reader.representationStart, reader.representationEnd + 1), @@ -29,15 +29,15 @@ export function consumeIdentLikeToken(ctx: Context, reader: CodePointReader): To let read = 0; while (true) { - const firstIsWhitespace = isWhitespace(reader.codePointSource[reader.cursor]); - const secondIsWhitespace = isWhitespace(reader.codePointSource[reader.cursor+1]); + const firstIsWhitespace = isWhitespace(reader.source.codePointAt(reader.cursor)); + const secondIsWhitespace = isWhitespace(reader.source.codePointAt(reader.cursor + 1)); if (firstIsWhitespace && secondIsWhitespace) { read = read + 1; reader.advanceCodePoint(1); continue; } - const firstNonWhitespace = firstIsWhitespace ? reader.codePointSource[reader.cursor+1] : reader.codePointSource[reader.cursor]; + const firstNonWhitespace = firstIsWhitespace ? reader.source.codePointAt(reader.cursor + 1) : reader.source.codePointAt(reader.cursor); if (firstNonWhitespace === QUOTATION_MARK || firstNonWhitespace === APOSTROPHE) { if (read > 0) { // https://github.com/w3c/csswg-drafts/issues/8280#issuecomment-1370566921 diff --git a/packages/css-tokenizer/src/consume/ident-sequence.ts b/packages/css-tokenizer/src/consume/ident-sequence.ts index d5c1893e0..0ec6e1537 100644 --- a/packages/css-tokenizer/src/consume/ident-sequence.ts +++ b/packages/css-tokenizer/src/consume/ident-sequence.ts @@ -9,9 +9,10 @@ export function consumeIdentSequence(ctx: Context, reader: CodePointReader): Arr const result: Array = []; while (true) { - if (isIdentCodePoint(reader.codePointSource[reader.cursor])) { - result.push(reader.codePointSource[reader.cursor]); - reader.advanceCodePoint(); + const codePoint = reader.source.codePointAt(reader.cursor); + if (isIdentCodePoint(codePoint)) { + result.push(codePoint); + reader.advanceCodePoint(1 + +(codePoint > 0xffff)); continue; } diff --git a/packages/css-tokenizer/src/consume/number.ts b/packages/css-tokenizer/src/consume/number.ts index ccc629af5..a32556128 100644 --- a/packages/css-tokenizer/src/consume/number.ts +++ b/packages/css-tokenizer/src/consume/number.ts @@ -10,17 +10,17 @@ export function consumeNumber(ctx: Context, reader: CodePointReader): NumberType let type = NumberType.Integer; // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-), consume it and append it to repr. - if (reader.codePointSource[reader.cursor] === PLUS_SIGN || reader.codePointSource[reader.cursor] === HYPHEN_MINUS) { + if (reader.source.codePointAt(reader.cursor) === PLUS_SIGN || reader.source.codePointAt(reader.cursor) === HYPHEN_MINUS) { reader.advanceCodePoint(); } // 3. While the next input code point is a digit, consume it and append it to repr. - while (isDigitCodePoint(reader.codePointSource[reader.cursor])) { + while (isDigitCodePoint(reader.source.codePointAt(reader.cursor))) { reader.advanceCodePoint(); } // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then: - if (reader.codePointSource[reader.cursor] === FULL_STOP && isDigitCodePoint(reader.codePointSource[reader.cursor+1])) { + if (reader.source.codePointAt(reader.cursor) === FULL_STOP && isDigitCodePoint(reader.source.codePointAt(reader.cursor + 1))) { // 4.1. Consume them. reader.advanceCodePoint(2); @@ -28,7 +28,7 @@ export function consumeNumber(ctx: Context, reader: CodePointReader): NumberType type = NumberType.Number; // 4.4. While the next input code point is a digit, consume it and append it to repr. - while (isDigitCodePoint(reader.codePointSource[reader.cursor])) { + while (isDigitCodePoint(reader.source.codePointAt(reader.cursor))) { reader.advanceCodePoint(); } } @@ -36,13 +36,13 @@ export function consumeNumber(ctx: Context, reader: CodePointReader): NumberType // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E) or U+0065 LATIN SMALL LETTER E (e), // optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+), // followed by a digit, then: - if (reader.codePointSource[reader.cursor] === LATIN_SMALL_LETTER_E || reader.codePointSource[reader.cursor] === LATIN_CAPITAL_LETTER_E) { - if (isDigitCodePoint(reader.codePointSource[reader.cursor + 1])) { + if (reader.source.codePointAt(reader.cursor) === LATIN_SMALL_LETTER_E || reader.source.codePointAt(reader.cursor) === LATIN_CAPITAL_LETTER_E) { + if (isDigitCodePoint(reader.source.codePointAt(reader.cursor + 1))) { // 5.1. Consume them. reader.advanceCodePoint(2); } else if ( - (reader.codePointSource[reader.cursor + 1] === HYPHEN_MINUS || reader.codePointSource[reader.cursor + 1] === PLUS_SIGN) && - isDigitCodePoint(reader.codePointSource[reader.cursor + 2]) + (reader.source.codePointAt(reader.cursor + 1) === HYPHEN_MINUS || reader.source.codePointAt(reader.cursor + 1) === PLUS_SIGN) && + isDigitCodePoint(reader.source.codePointAt(reader.cursor + 2)) ) { // 5.1. Consume them. reader.advanceCodePoint(3); @@ -54,7 +54,7 @@ export function consumeNumber(ctx: Context, reader: CodePointReader): NumberType type = NumberType.Number; // 5.4. While the next input code point is a digit, consume it and append it to repr. - while (isDigitCodePoint(reader.codePointSource[reader.cursor])) { + while (isDigitCodePoint(reader.source.codePointAt(reader.cursor))) { reader.advanceCodePoint(); } } diff --git a/packages/css-tokenizer/src/consume/numeric-token.ts b/packages/css-tokenizer/src/consume/numeric-token.ts index ddc73fc1b..fb27bb1cc 100644 --- a/packages/css-tokenizer/src/consume/numeric-token.ts +++ b/packages/css-tokenizer/src/consume/numeric-token.ts @@ -12,7 +12,7 @@ export function consumeNumericToken(ctx: Context, reader: CodePointReader): Toke let signCharacter: undefined | '+' | '-' = undefined; { - const peeked = reader.codePointSource[reader.cursor]; + const peeked = reader.source.codePointAt(reader.cursor); if (peeked === HYPHEN_MINUS) { signCharacter = '-'; } else if (peeked === PLUS_SIGN) { @@ -39,7 +39,7 @@ export function consumeNumericToken(ctx: Context, reader: CodePointReader): Toke ]; } - if (reader.codePointSource[reader.cursor] === PERCENTAGE_SIGN) { + if (reader.source.codePointAt(reader.cursor) === PERCENTAGE_SIGN) { reader.advanceCodePoint(); return [ diff --git a/packages/css-tokenizer/src/consume/string-token.ts b/packages/css-tokenizer/src/consume/string-token.ts index 1d04e03d8..855429343 100644 --- a/packages/css-tokenizer/src/consume/string-token.ts +++ b/packages/css-tokenizer/src/consume/string-token.ts @@ -16,7 +16,7 @@ export function consumeStringToken(ctx: Context, reader: CodePointReader): Token while (true) { const next = reader.readCodePoint(); - if (next === false) { + if (typeof next === "undefined") { const token: CSSToken = [TokenType.String, reader.source.slice(reader.representationStart, reader.representationEnd + 1), reader.representationStart, reader.representationEnd, { value: result }]; ctx.onParseError(new ParseErrorWithToken( @@ -43,8 +43,8 @@ export function consumeStringToken(ctx: Context, reader: CodePointReader): Token reader.representationStart, ( ( - reader.codePointSource[reader.cursor] === CARRIAGE_RETURN && - reader.codePointSource[reader.cursor + 1] === LINE_FEED + reader.source.codePointAt(reader.cursor) === CARRIAGE_RETURN && + reader.source.codePointAt(reader.cursor + 1) === LINE_FEED ) ? // CR LF reader.representationEnd + 2 : @@ -66,14 +66,14 @@ export function consumeStringToken(ctx: Context, reader: CodePointReader): Token } if (next === REVERSE_SOLIDUS) { - if (reader.codePointSource[reader.cursor] === undefined) { + if (typeof reader.source.codePointAt(reader.cursor) === "undefined") { continue; } - if (isNewLine(reader.codePointSource[reader.cursor])) { + if (isNewLine(reader.source.codePointAt(reader.cursor))) { if ( - reader.codePointSource[reader.cursor] === CARRIAGE_RETURN && - reader.codePointSource[reader.cursor + 1] === LINE_FEED + reader.source.codePointAt(reader.cursor) === CARRIAGE_RETURN && + reader.source.codePointAt(reader.cursor + 1) === LINE_FEED ) { reader.advanceCodePoint(); } diff --git a/packages/css-tokenizer/src/consume/unicode-range-token.ts b/packages/css-tokenizer/src/consume/unicode-range-token.ts index 254d72a28..19d3c1b24 100644 --- a/packages/css-tokenizer/src/consume/unicode-range-token.ts +++ b/packages/css-tokenizer/src/consume/unicode-range-token.ts @@ -15,12 +15,13 @@ export function consumeUnicodeRangeToken(ctx: Context, reader: CodePointReader): // 2. Consume as many hex digits as possible, // but no more than 6. + let codePoint: number | undefined; while ( - (reader.codePointSource[reader.cursor] !== undefined) && + (typeof (codePoint = reader.source.codePointAt(reader.cursor)) !== "undefined") && firstSegment.length < 6 && - isHexDigitCodePoint(reader.codePointSource[reader.cursor]) + isHexDigitCodePoint(codePoint) ) { - firstSegment.push(reader.codePointSource[reader.cursor]); + firstSegment.push(codePoint); reader.advanceCodePoint(); } @@ -28,9 +29,9 @@ export function consumeUnicodeRangeToken(ctx: Context, reader: CodePointReader): // consume as many U+003F QUESTION MARK (?) code points as possible, // but no more than enough to make the total of hex digits and U+003F QUESTION MARK (?) code points equal to 6. while ( - (reader.codePointSource[reader.cursor] !== undefined) && + (typeof (codePoint = reader.source.codePointAt(reader.cursor)) !== "undefined") && firstSegment.length < 6 && - reader.codePointSource[reader.cursor] === QUESTION_MARK + codePoint === QUESTION_MARK ) { if (secondSegment.length === 0) { secondSegment.push(...firstSegment); @@ -47,8 +48,8 @@ export function consumeUnicodeRangeToken(ctx: Context, reader: CodePointReader): if (!secondSegment.length) { // 5. If the next 2 input code points are U+002D HYPHEN-MINUS (-) followed by a hex digit if ( - reader.codePointSource[reader.cursor] === HYPHEN_MINUS && - isHexDigitCodePoint(reader.codePointSource[reader.cursor + 1]) + reader.source.codePointAt(reader.cursor) === HYPHEN_MINUS && + isHexDigitCodePoint(reader.source.codePointAt(reader.cursor + 1)) ) { // 5.1. Consume the next input code point. reader.advanceCodePoint(); @@ -56,11 +57,11 @@ export function consumeUnicodeRangeToken(ctx: Context, reader: CodePointReader): // 5.2 Consume as many hex digits as possible, // but no more than 6. while ( - (reader.codePointSource[reader.cursor] !== undefined) && + (typeof (codePoint = reader.source.codePointAt(reader.cursor)) !== "undefined") && secondSegment.length < 6 && - isHexDigitCodePoint(reader.codePointSource[reader.cursor]) + isHexDigitCodePoint(codePoint) ) { - secondSegment.push(reader.codePointSource[reader.cursor]); + secondSegment.push(codePoint); reader.advanceCodePoint(); } } diff --git a/packages/css-tokenizer/src/consume/url-token.ts b/packages/css-tokenizer/src/consume/url-token.ts index ab09e9ee4..bc7376d66 100644 --- a/packages/css-tokenizer/src/consume/url-token.ts +++ b/packages/css-tokenizer/src/consume/url-token.ts @@ -11,14 +11,14 @@ import { consumeEscapedCodePoint } from './escaped-code-point'; // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#consume-url-token export function consumeUrlToken(ctx: Context, reader: CodePointReader): TokenURL|TokenBadURL { - while (isWhitespace(reader.codePointSource[reader.cursor])) { + while (isWhitespace(reader.source.codePointAt(reader.cursor))) { reader.advanceCodePoint(); } let string = ''; while (true) { - if (reader.codePointSource[reader.cursor] === undefined) { + if (typeof reader.source.codePointAt(reader.cursor) === "undefined") { const token: CSSToken = [ TokenType.URL, reader.source.slice(reader.representationStart, reader.representationEnd + 1), @@ -43,7 +43,7 @@ export function consumeUrlToken(ctx: Context, reader: CodePointReader): TokenURL return token; } - if (reader.codePointSource[reader.cursor] === RIGHT_PARENTHESIS) { + if (reader.source.codePointAt(reader.cursor) === RIGHT_PARENTHESIS) { reader.advanceCodePoint(); return [ TokenType.URL, @@ -56,13 +56,13 @@ export function consumeUrlToken(ctx: Context, reader: CodePointReader): TokenURL ]; } - if (isWhitespace(reader.codePointSource[reader.cursor])) { + if (isWhitespace(reader.source.codePointAt(reader.cursor))) { reader.advanceCodePoint(); - while (isWhitespace(reader.codePointSource[reader.cursor])) { + while (isWhitespace(reader.source.codePointAt(reader.cursor))) { reader.advanceCodePoint(); } - if (reader.codePointSource[reader.cursor] === undefined) { + if (typeof reader.source.codePointAt(reader.cursor) === "undefined") { const token: CSSToken = [ TokenType.URL, reader.source.slice(reader.representationStart, reader.representationEnd + 1), @@ -88,7 +88,7 @@ export function consumeUrlToken(ctx: Context, reader: CodePointReader): TokenURL return token; } - if (reader.codePointSource[reader.cursor] === RIGHT_PARENTHESIS) { + if (reader.source.codePointAt(reader.cursor) === RIGHT_PARENTHESIS) { reader.advanceCodePoint(); return [ TokenType.URL, @@ -111,7 +111,8 @@ export function consumeUrlToken(ctx: Context, reader: CodePointReader): TokenURL ]; } - if (reader.codePointSource[reader.cursor] === QUOTATION_MARK || reader.codePointSource[reader.cursor] === APOSTROPHE || reader.codePointSource[reader.cursor] === LEFT_PARENTHESIS || isNonPrintableCodePoint(reader.codePointSource[reader.cursor])) { + const codePoint = reader.source.codePointAt(reader.cursor); + if (codePoint === QUOTATION_MARK || codePoint === APOSTROPHE || codePoint === LEFT_PARENTHESIS || isNonPrintableCodePoint(codePoint)) { consumeBadURL(ctx, reader); const token: CSSToken = [ @@ -136,7 +137,7 @@ export function consumeUrlToken(ctx: Context, reader: CodePointReader): TokenURL return token; } - if (reader.codePointSource[reader.cursor] === REVERSE_SOLIDUS) { + if (codePoint === REVERSE_SOLIDUS) { if (checkIfTwoCodePointsAreAValidEscape(reader)) { reader.advanceCodePoint(); string = string + String.fromCodePoint(consumeEscapedCodePoint(ctx, reader)); @@ -168,7 +169,7 @@ export function consumeUrlToken(ctx: Context, reader: CodePointReader): TokenURL return token; } - string = string + String.fromCodePoint(reader.codePointSource[reader.cursor]); + string = string + reader.source[reader.cursor]; reader.advanceCodePoint(); } } diff --git a/packages/css-tokenizer/src/consume/whitespace-token.ts b/packages/css-tokenizer/src/consume/whitespace-token.ts index 7857a6ef8..f3b80d84e 100644 --- a/packages/css-tokenizer/src/consume/whitespace-token.ts +++ b/packages/css-tokenizer/src/consume/whitespace-token.ts @@ -4,7 +4,7 @@ import type { TokenWhitespace } from '../interfaces/token'; import { TokenType } from '../interfaces/token'; export function consumeWhiteSpace(reader: CodePointReader): TokenWhitespace { - while (isWhitespace(reader.codePointSource[reader.cursor])) { + while (isWhitespace(reader.source.codePointAt(reader.cursor))) { reader.advanceCodePoint(); } diff --git a/packages/css-tokenizer/src/interfaces/code-point-reader.ts b/packages/css-tokenizer/src/interfaces/code-point-reader.ts index f025ada5d..01e1f4810 100644 --- a/packages/css-tokenizer/src/interfaces/code-point-reader.ts +++ b/packages/css-tokenizer/src/interfaces/code-point-reader.ts @@ -6,12 +6,10 @@ export type CodePointReader = { representationEnd: number; cursor: number; - codePointSource: Array; - representationIndices: Array; source: string; advanceCodePoint(n?: number): void - readCodePoint(n?: number): number | false + readCodePoint(): number | undefined unreadCodePoint(n?: number): void resetRepresentation(): void } diff --git a/packages/css-tokenizer/src/reader.ts b/packages/css-tokenizer/src/reader.ts index 247b24d60..8a8d44986 100644 --- a/packages/css-tokenizer/src/reader.ts +++ b/packages/css-tokenizer/src/reader.ts @@ -6,58 +6,40 @@ import type { CodePointReader } from './interfaces/code-point-reader'; export class Reader implements CodePointReader { cursor = 0; source = ''; - codePointSource: Array = []; - representationIndices: Array = [-1]; - length = 0; representationStart = 0; representationEnd = -1; constructor(source: string) { this.source = source; - - { - let representationEnd = -1; - let codePoint = ''; - - for (codePoint of source) { - representationEnd += codePoint.length; - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.codePointSource.push(codePoint.codePointAt(0)!); - this.representationIndices.push(representationEnd); - } - } - - this.length = this.codePointSource.length; } advanceCodePoint(n = 1): void { this.cursor = this.cursor + n; - this.representationEnd = this.representationIndices[this.cursor]; + this.representationEnd = this.cursor - 1; } - readCodePoint(n = 1): number | false { - const codePoint = this.codePointSource[this.cursor]; - if (codePoint === undefined) { - return false; + readCodePoint(): number | undefined { + const codePoint = this.source.codePointAt(this.cursor); + if (typeof codePoint === "undefined") { + return undefined; } - this.cursor = this.cursor + n; - this.representationEnd = this.representationIndices[this.cursor]; + this.cursor = this.cursor + 1; + this.representationEnd = this.cursor - 1; return codePoint; } unreadCodePoint(n = 1): void { this.cursor = this.cursor - n; - this.representationEnd = this.representationIndices[this.cursor]; + this.representationEnd = this.cursor - 1; return; } resetRepresentation(): void { - this.representationStart = this.representationIndices[this.cursor] + 1; + this.representationStart = this.cursor; this.representationEnd = -1; } } diff --git a/packages/css-tokenizer/src/tokenizer.ts b/packages/css-tokenizer/src/tokenizer.ts index 7026ef653..d28b21684 100644 --- a/packages/css-tokenizer/src/tokenizer.ts +++ b/packages/css-tokenizer/src/tokenizer.ts @@ -78,14 +78,14 @@ export function tokenizer( }; function endOfFile(): boolean { - return reader.codePointSource[reader.cursor] === undefined; + return typeof reader.source.codePointAt(reader.cursor) === "undefined"; } function nextToken(): CSSToken | undefined { reader.resetRepresentation(); - const peeked = reader.codePointSource[reader.cursor]; - if (peeked === undefined) { + const peeked = reader.source.codePointAt(reader.cursor); + if (typeof peeked === "undefined") { return [TokenType.EOF, '', -1, -1, undefined]; } diff --git a/packages/css-tokenizer/test/test-reader.mjs b/packages/css-tokenizer/test/test-reader.mjs deleted file mode 100644 index 16097bb60..000000000 --- a/packages/css-tokenizer/test/test-reader.mjs +++ /dev/null @@ -1,225 +0,0 @@ -import assert from 'node:assert'; -import { Reader } from '@csstools/css-tokenizer'; - -{ - const r = new Reader('abc👨‍👨‍👧‍👦d'); - - { - const peeked = r.codePointSource[r.cursor]; - assert.deepEqual( - peeked, - 97, - ); - - assert.deepEqual( - String.fromCodePoint(peeked), - 'a', - ); - - assert.deepEqual( - [ - r.representationStart, - r.representationEnd, - ], - [ - 0, - -1, - ], - ); - } - - { - const peeked = [ - r.codePointSource[r.cursor], - r.codePointSource[r.cursor+1], - ]; - assert.deepEqual( - peeked, - [97, 98], - ); - - assert.deepEqual( - String.fromCodePoint(peeked[0]), - 'a', - ); - - assert.deepEqual( - String.fromCodePoint(peeked[1]), - 'b', - ); - - assert.deepEqual( - [ - r.representationStart, - r.representationEnd, - ], - [ - 0, - -1, - ], - ); - } - - { - const peeked = [ - r.codePointSource[r.cursor], - r.codePointSource[r.cursor+1], - r.codePointSource[r.cursor+2], - ]; - assert.deepEqual( - peeked, - [97, 98, 99], - ); - - assert.deepEqual( - String.fromCodePoint(peeked[0]), - 'a', - ); - - assert.deepEqual( - String.fromCodePoint(peeked[1]), - 'b', - ); - - assert.deepEqual( - String.fromCodePoint(peeked[2]), - 'c', - ); - - assert.deepEqual( - [ - r.representationStart, - r.representationEnd, - ], - [ - 0, - -1, - ], - ); - } - - { - const read = r.readCodePoint(); - assert.deepEqual( - read, - 97, - ); - - assert.deepEqual( - String.fromCodePoint(read), - 'a', - ); - - assert.deepEqual( - [ - r.representationStart, - r.representationEnd, - ], - [ - 0, - 0, - ], - ); - - assert.deepEqual( - r.source.slice(r.representationStart, r.representationEnd + 1), - 'a', - ); - } - - r.representationStart = r.cursor; - r.representationEnd = -1; - - { - const read1 = r.readCodePoint(); - assert.deepEqual( - read1, - 98, - ); - - const read2 = r.readCodePoint(); - assert.deepEqual( - read2, - 99, - ); - - const read3 = r.readCodePoint(); - assert.deepEqual( - read3, - 128104, - ); - - assert.deepEqual( - String.fromCodePoint(read3), - '👨', - ); - - const read4 = r.readCodePoint(); - assert.deepEqual( - read4, - 8205, - ); - - assert.deepEqual( - String.fromCodePoint(read4), - '‍', - ); - - assert.deepEqual( - [ - r.representationStart, - r.representationEnd, - ], - [ - 1, - 5, - ], - ); - - // Read to the end - r.readCodePoint(); - r.readCodePoint(); - r.readCodePoint(); - r.readCodePoint(); - r.readCodePoint(); - r.readCodePoint(); - - assert.deepEqual( - [ - r.representationStart, - r.representationEnd, - ], - [ - 1, - 14, - ], - ); - - assert.deepEqual( - r.source.slice(r.representationStart, r.representationEnd + 1), - 'bc👨‍👨‍👧‍👦d', - ); - - { - // Reader should be exhausted. - // Extra reads do not change the representation. - - r.readCodePoint(); - assert.deepEqual( - [ - r.representationStart, - r.representationEnd, - ], - [ - 1, - 14, - ], - ); - - assert.deepEqual( - r.source.slice(r.representationStart, r.representationEnd + 1), - 'bc👨‍👨‍👧‍👦d', - ); - } - } -} diff --git a/packages/css-tokenizer/test/test.mjs b/packages/css-tokenizer/test/test.mjs index 551ef4ea6..9c5dafb72 100644 --- a/packages/css-tokenizer/test/test.mjs +++ b/packages/css-tokenizer/test/test.mjs @@ -1,6 +1,3 @@ -// Reader -import './test-reader.mjs'; - // Code points import './code-points/code-points.mjs'; import './code-points/ranges.mjs'; diff --git a/packages/css-tokenizer/test/token/basic.mjs b/packages/css-tokenizer/test/token/basic.mjs index 32099d6b0..661a5e5ae 100644 --- a/packages/css-tokenizer/test/token/basic.mjs +++ b/packages/css-tokenizer/test/token/basic.mjs @@ -382,7 +382,7 @@ bar") and (fancy(baz))) {}`, { const t = tokenizer({ - css: `\\0 + css: `/*a𐀀*/ `, }); From 338cfe0d1be5b341afa2e083878ad0273e64ab28 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Sat, 3 Aug 2024 19:16:03 +0200 Subject: [PATCH 2/5] fix --- packages/css-tokenizer/test/token/basic.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/css-tokenizer/test/token/basic.mjs b/packages/css-tokenizer/test/token/basic.mjs index 661a5e5ae..32099d6b0 100644 --- a/packages/css-tokenizer/test/token/basic.mjs +++ b/packages/css-tokenizer/test/token/basic.mjs @@ -382,7 +382,7 @@ bar") and (fancy(baz))) {}`, { const t = tokenizer({ - css: `/*a𐀀*/ + css: `\\0 `, }); From 10db5e18a0fd1e96fdcb06970f34b2bc1401e179 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Sat, 3 Aug 2024 19:18:23 +0200 Subject: [PATCH 3/5] cleanup --- packages/css-tokenizer/dist/index.cjs | 2 +- packages/css-tokenizer/dist/index.d.ts | 29 -------------------------- packages/css-tokenizer/dist/index.mjs | 2 +- packages/css-tokenizer/src/index.ts | 2 -- 4 files changed, 2 insertions(+), 33 deletions(-) diff --git a/packages/css-tokenizer/dist/index.cjs b/packages/css-tokenizer/dist/index.cjs index 0f57e3a05..59fdf698b 100644 --- a/packages/css-tokenizer/dist/index.cjs +++ b/packages/css-tokenizer/dist/index.cjs @@ -1 +1 @@ -"use strict";class ParseError extends Error{sourceStart;sourceEnd;parserState;constructor(e,n,o,t){super(e),this.name="ParseError",this.sourceStart=n,this.sourceEnd=o,this.parserState=t}}class ParseErrorWithToken extends ParseError{token;constructor(e,n,o,t,r){super(e,n,o,t),this.token=r}}const e={UnexpectedNewLineInString:"Unexpected newline while consuming a string token.",UnexpectedEOFInString:"Unexpected EOF while consuming a string token.",UnexpectedEOFInComment:"Unexpected EOF while consuming a comment.",UnexpectedEOFInURL:"Unexpected EOF while consuming a url token.",UnexpectedEOFInEscapedCodePoint:"Unexpected EOF while consuming an escaped code point.",UnexpectedCharacterInURL:"Unexpected character while consuming a url token.",InvalidEscapeSequenceInURL:"Invalid escape sequence while consuming a url token.",InvalidEscapeSequenceAfterBackslash:'Invalid escape sequence after "\\"'};class Reader{cursor=0;source="";representationStart=0;representationEnd=-1;constructor(e){this.source=e}advanceCodePoint(e=1){this.cursor=this.cursor+e,this.representationEnd=this.cursor-1}readCodePoint(){const e=this.source.codePointAt(this.cursor);if(void 0!==e)return this.cursor=this.cursor+1,this.representationEnd=this.cursor-1,e}unreadCodePoint(e=1){this.cursor=this.cursor-e,this.representationEnd=this.cursor-1}resetRepresentation(){this.representationStart=this.cursor,this.representationEnd=-1}}const n="undefined"!=typeof globalThis&&"structuredClone"in globalThis;const o=39,t=42,r=8,s=13,i=9,c=58,a=44,u=64,d=127,p=33,T=12,P=46,k=62,C=45,l=31,f=69,x=101,S=123,m=40,E=91,h=60,y=10,v=11,A=95,g=1114111,I=0,U=35,O=37,R=43,D=34,w=65533,L=92,W=125,N=41,F=93,q=59,b=14,H=47,B=32,V=117,z=85,K=114,M=82,$=108,J=76,_=63,j=48,Q=70;function checkIfFourCodePointsWouldStartCDO(e){return e.source.codePointAt(e.cursor)===h&&e.source.codePointAt(e.cursor+1)===p&&e.source.codePointAt(e.cursor+2)===C&&e.source.codePointAt(e.cursor+3)===C}function isDigitCodePoint(e){return void 0!==e&&e>=48&&e<=57}function isUppercaseLetterCodePoint(e){return void 0!==e&&e>=65&&e<=90}function isLowercaseLetterCodePoint(e){return void 0!==e&&e>=97&&e<=122}function isHexDigitCodePoint(e){return void 0!==e&&(e>=48&&e<=57||e>=97&&e<=102||e>=65&&e<=70)}function isLetterCodePoint(e){return isLowercaseLetterCodePoint(e)||isUppercaseLetterCodePoint(e)}function isIdentStartCodePoint(e){return isLetterCodePoint(e)||isNonASCII_IdentCodePoint(e)||e===A}function isIdentCodePoint(e){return isIdentStartCodePoint(e)||isDigitCodePoint(e)||e===C}function isNonASCII_IdentCodePoint(e){return 183===e||8204===e||8205===e||8255===e||8256===e||8204===e||void 0!==e&&(192<=e&&e<=214||216<=e&&e<=246||248<=e&&e<=893||895<=e&&e<=8191||8304<=e&&e<=8591||11264<=e&&e<=12271||12289<=e&&e<=55295||63744<=e&&e<=64975||65008<=e&&e<=65533||e>=65536)}function isNewLine(e){return e===y||e===s||e===T}function isWhitespace(e){return e===B||e===y||e===i||e===s||e===T}function checkIfTwoCodePointsAreAValidEscape(e){return e.source.codePointAt(e.cursor)===L&&!isNewLine(e.source.codePointAt(e.cursor+1))}function checkIfThreeCodePointsWouldStartAnIdentSequence(e,n){return n.source.codePointAt(n.cursor)===C?n.source.codePointAt(n.cursor+1)===C||(!!isIdentStartCodePoint(n.source.codePointAt(n.cursor+1))||n.source.codePointAt(n.cursor+1)===L&&!isNewLine(n.source.codePointAt(n.cursor+2))):!!isIdentStartCodePoint(n.source.codePointAt(n.cursor))||checkIfTwoCodePointsAreAValidEscape(n)}function checkIfThreeCodePointsWouldStartANumber(e){return e.source.codePointAt(e.cursor)===R||e.source.codePointAt(e.cursor)===C?!!isDigitCodePoint(e.source.codePointAt(e.cursor+1))||e.source.codePointAt(e.cursor+1)===P&&isDigitCodePoint(e.source.codePointAt(e.cursor+2)):e.source.codePointAt(e.cursor)===P?isDigitCodePoint(e.source.codePointAt(e.cursor+1)):isDigitCodePoint(e.source.codePointAt(e.cursor))}function checkIfTwoCodePointsStartAComment(e){return e.source.codePointAt(e.cursor)===H&&e.source.codePointAt(e.cursor+1)===t}function checkIfThreeCodePointsWouldStartCDC(e){return e.source.codePointAt(e.cursor)===C&&e.source.codePointAt(e.cursor+1)===C&&e.source.codePointAt(e.cursor+2)===k}var G,X,Y;function consumeComment(n,o){for(o.advanceCodePoint(2);;){const r=o.readCodePoint();if(void 0===r){const t=[exports.TokenType.Comment,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInComment,o.representationStart,o.representationEnd,["4.3.2. Consume comments","Unexpected EOF"],t)),t}if(r===t&&(void 0!==o.source.codePointAt(o.cursor)&&o.source.codePointAt(o.cursor)===H)){o.advanceCodePoint();break}}return[exports.TokenType.Comment,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0]}function consumeEscapedCodePoint(n,o){const t=o.readCodePoint();if(void 0===t)return n.onParseError(new ParseError(e.UnexpectedEOFInEscapedCodePoint,o.representationStart,o.representationEnd,["4.3.7. Consume an escaped code point","Unexpected EOF"])),w;if(isHexDigitCodePoint(t)){const e=[t];let n;for(;void 0!==(n=o.source.codePointAt(o.cursor))&&isHexDigitCodePoint(n)&&e.length<6;)e.push(n),o.advanceCodePoint();isWhitespace(o.source.codePointAt(o.cursor))&&o.advanceCodePoint();const s=parseInt(String.fromCodePoint(...e),16);return 0===s?w:void 0!==(r=s)&&r>=55296&&r<=57343||s>g?w:s}var r;return t}function consumeIdentSequence(e,n){const o=[];for(;;){const t=n.source.codePointAt(n.cursor);if(isIdentCodePoint(t))o.push(t),n.advanceCodePoint(+(t>65535)+1);else{if(!checkIfTwoCodePointsAreAValidEscape(n))return o;n.advanceCodePoint(),o.push(consumeEscapedCodePoint(e,n))}}}function consumeHashToken(e,n){n.advanceCodePoint();const o=n.source.codePointAt(n.cursor);if(void 0!==o&&(isIdentCodePoint(o)||checkIfTwoCodePointsAreAValidEscape(n))){let o=exports.HashType.Unrestricted;checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)&&(o=exports.HashType.ID);const t=consumeIdentSequence(e,n);return[exports.TokenType.Hash,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t),type:o}]}return[exports.TokenType.Delim,"#",n.representationStart,n.representationEnd,{value:"#"}]}function consumeNumber(e,n){let o=exports.NumberType.Integer;for(n.source.codePointAt(n.cursor)!==R&&n.source.codePointAt(n.cursor)!==C||n.advanceCodePoint();isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===P&&isDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint(2),o=exports.NumberType.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===x||n.source.codePointAt(n.cursor)===f){if(isDigitCodePoint(n.source.codePointAt(n.cursor+1)))n.advanceCodePoint(2);else{if(n.source.codePointAt(n.cursor+1)!==C&&n.source.codePointAt(n.cursor+1)!==R||!isDigitCodePoint(n.source.codePointAt(n.cursor+2)))return o;n.advanceCodePoint(3)}for(o=exports.NumberType.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint()}return o}function consumeNumericToken(e,n){let o;{const e=n.source.codePointAt(n.cursor);e===C?o="-":e===R&&(o="+")}const t=consumeNumber(0,n),r=parseFloat(n.source.slice(n.representationStart,n.representationEnd+1));if(checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)){const s=consumeIdentSequence(e,n);return[exports.TokenType.Dimension,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o,type:t,unit:String.fromCodePoint(...s)}]}return n.source.codePointAt(n.cursor)===O?(n.advanceCodePoint(),[exports.TokenType.Percentage,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o}]):[exports.TokenType.Number,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o,type:t}]}function consumeWhiteSpace(e){for(;isWhitespace(e.source.codePointAt(e.cursor));)e.advanceCodePoint();return[exports.TokenType.Whitespace,e.source.slice(e.representationStart,e.representationEnd+1),e.representationStart,e.representationEnd,void 0]}function consumeStringToken(n,o){let t="";const r=o.readCodePoint();for(;;){const i=o.readCodePoint();if(void 0===i){const r=[exports.TokenType.String,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInString,o.representationStart,o.representationEnd,["4.3.5. Consume a string token","Unexpected EOF"],r)),r}if(isNewLine(i)){o.unreadCodePoint();const t=[exports.TokenType.BadString,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedNewLineInString,o.representationStart,o.source.codePointAt(o.cursor)===s&&o.source.codePointAt(o.cursor+1)===y?o.representationEnd+2:o.representationEnd+1,["4.3.5. Consume a string token","Unexpected newline"],t)),t}if(i===r)return[exports.TokenType.String,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t}];if(i!==L)t+=String.fromCodePoint(i);else{if(void 0===o.source.codePointAt(o.cursor))continue;if(isNewLine(o.source.codePointAt(o.cursor))){o.source.codePointAt(o.cursor)===s&&o.source.codePointAt(o.cursor+1)===y&&o.advanceCodePoint(),o.advanceCodePoint();continue}t+=String.fromCodePoint(consumeEscapedCodePoint(n,o))}}}function checkIfCodePointsMatchURLIdent(e){return!(3!==e.length||e[0]!==V&&e[0]!==z||e[1]!==K&&e[1]!==M||e[2]!==$&&e[2]!==J)}function consumeBadURL(e,n){for(;;){const o=n.source.codePointAt(n.cursor);if(void 0===o)return;if(o===N)return void n.advanceCodePoint();checkIfTwoCodePointsAreAValidEscape(n)?(n.advanceCodePoint(),consumeEscapedCodePoint(e,n)):n.advanceCodePoint()}}function consumeUrlToken(n,t){for(;isWhitespace(t.source.codePointAt(t.cursor));)t.advanceCodePoint();let s="";for(;;){if(void 0===t.source.codePointAt(t.cursor)){const o=[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Unexpected EOF"],o)),o}if(t.source.codePointAt(t.cursor)===N)return t.advanceCodePoint(),[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}];if(isWhitespace(t.source.codePointAt(t.cursor))){for(t.advanceCodePoint();isWhitespace(t.source.codePointAt(t.cursor));)t.advanceCodePoint();if(void 0===t.source.codePointAt(t.cursor)){const o=[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Consume as much whitespace as possible","Unexpected EOF"],o)),o}return t.source.codePointAt(t.cursor)===N?(t.advanceCodePoint(),[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}]):(consumeBadURL(n,t),[exports.TokenType.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0])}const c=t.source.codePointAt(t.cursor);if(c===D||c===o||c===m||void 0!==(i=c)&&(i===v||i===d||I<=i&&i<=r||b<=i&&i<=l)){consumeBadURL(n,t);const o=[exports.TokenType.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedCharacterInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Unexpected U+0022 QUOTATION MARK (\"), U+0027 APOSTROPHE ('), U+0028 LEFT PARENTHESIS (() or non-printable code point"],o)),o}if(c===L){if(checkIfTwoCodePointsAreAValidEscape(t)){t.advanceCodePoint(),s+=String.fromCodePoint(consumeEscapedCodePoint(n,t));continue}consumeBadURL(n,t);const o=[exports.TokenType.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],o)),o}s+=t.source[t.cursor],t.advanceCodePoint()}var i}function consumeIdentLikeToken(e,n){const t=consumeIdentSequence(e,n);if(n.source.codePointAt(n.cursor)!==m)return[exports.TokenType.Ident,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}];if(checkIfCodePointsMatchURLIdent(t)){n.advanceCodePoint();let r=0;for(;;){const e=isWhitespace(n.source.codePointAt(n.cursor)),s=isWhitespace(n.source.codePointAt(n.cursor+1));if(e&&s){r+=1,n.advanceCodePoint(1);continue}const i=e?n.source.codePointAt(n.cursor+1):n.source.codePointAt(n.cursor);if(i===D||i===o)return r>0&&n.unreadCodePoint(r),[exports.TokenType.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}];break}return consumeUrlToken(e,n)}return n.advanceCodePoint(),[exports.TokenType.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}]}function checkIfThreeCodePointsWouldStartAUnicodeRange(e){return!(e.source.codePointAt(e.cursor)!==V&&e.source.codePointAt(e.cursor)!==z||e.source.codePointAt(e.cursor+1)!==R||e.source.codePointAt(e.cursor+2)!==_&&!isHexDigitCodePoint(e.source.codePointAt(e.cursor+2)))}function consumeUnicodeRangeToken(e,n){n.advanceCodePoint(2);const o=[],t=[];let r;for(;void 0!==(r=n.source.codePointAt(n.cursor))&&o.length<6&&isHexDigitCodePoint(r);)o.push(r),n.advanceCodePoint();for(;void 0!==(r=n.source.codePointAt(n.cursor))&&o.length<6&&r===_;)0===t.length&&t.push(...o),o.push(j),t.push(Q),n.advanceCodePoint();if(!t.length&&n.source.codePointAt(n.cursor)===C&&isHexDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint();void 0!==(r=n.source.codePointAt(n.cursor))&&t.length<6&&isHexDigitCodePoint(r);)t.push(r),n.advanceCodePoint();if(!t.length){const e=parseInt(String.fromCodePoint(...o),16);return[exports.TokenType.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:e,endOfRange:e}]}const s=parseInt(String.fromCodePoint(...o),16),i=parseInt(String.fromCodePoint(...t),16);return[exports.TokenType.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:s,endOfRange:i}]}function tokenizer(n,t){const r=n.css.valueOf(),d=n.unicodeRangesAllowed??!1,p=new Reader(r),k={onParseError:t?.onParseError??noop};return{nextToken:function nextToken(){p.resetRepresentation();const n=p.source.codePointAt(p.cursor);if(void 0===n)return[exports.TokenType.EOF,"",-1,-1,void 0];if(n===H&&checkIfTwoCodePointsStartAComment(p))return consumeComment(k,p);if(d&&(n===V||n===z)&&checkIfThreeCodePointsWouldStartAUnicodeRange(p))return consumeUnicodeRangeToken(0,p);if(isIdentStartCodePoint(n))return consumeIdentLikeToken(k,p);if(isDigitCodePoint(n))return consumeNumericToken(k,p);switch(n){case a:return p.advanceCodePoint(),[exports.TokenType.Comma,",",p.representationStart,p.representationEnd,void 0];case c:return p.advanceCodePoint(),[exports.TokenType.Colon,":",p.representationStart,p.representationEnd,void 0];case q:return p.advanceCodePoint(),[exports.TokenType.Semicolon,";",p.representationStart,p.representationEnd,void 0];case m:return p.advanceCodePoint(),[exports.TokenType.OpenParen,"(",p.representationStart,p.representationEnd,void 0];case N:return p.advanceCodePoint(),[exports.TokenType.CloseParen,")",p.representationStart,p.representationEnd,void 0];case E:return p.advanceCodePoint(),[exports.TokenType.OpenSquare,"[",p.representationStart,p.representationEnd,void 0];case F:return p.advanceCodePoint(),[exports.TokenType.CloseSquare,"]",p.representationStart,p.representationEnd,void 0];case S:return p.advanceCodePoint(),[exports.TokenType.OpenCurly,"{",p.representationStart,p.representationEnd,void 0];case W:return p.advanceCodePoint(),[exports.TokenType.CloseCurly,"}",p.representationStart,p.representationEnd,void 0];case o:case D:return consumeStringToken(k,p);case U:return consumeHashToken(k,p);case R:case P:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(k,p):(p.advanceCodePoint(),[exports.TokenType.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]);case y:case s:case T:case i:case B:return consumeWhiteSpace(p);case C:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(k,p):checkIfThreeCodePointsWouldStartCDC(p)?(p.advanceCodePoint(3),[exports.TokenType.CDC,"--\x3e",p.representationStart,p.representationEnd,void 0]):checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)?consumeIdentLikeToken(k,p):(p.advanceCodePoint(),[exports.TokenType.Delim,"-",p.representationStart,p.representationEnd,{value:"-"}]);case h:return checkIfFourCodePointsWouldStartCDO(p)?(p.advanceCodePoint(4),[exports.TokenType.CDO,"\x3c!--",p.representationStart,p.representationEnd,void 0]):(p.advanceCodePoint(),[exports.TokenType.Delim,"<",p.representationStart,p.representationEnd,{value:"<"}]);case u:if(p.advanceCodePoint(),checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)){const e=consumeIdentSequence(k,p);return[exports.TokenType.AtKeyword,p.source.slice(p.representationStart,p.representationEnd+1),p.representationStart,p.representationEnd,{value:String.fromCodePoint(...e)}]}return[exports.TokenType.Delim,"@",p.representationStart,p.representationEnd,{value:"@"}];case L:{if(checkIfTwoCodePointsAreAValidEscape(p))return consumeIdentLikeToken(k,p);p.advanceCodePoint();const n=[exports.TokenType.Delim,"\\",p.representationStart,p.representationEnd,{value:"\\"}];return k.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceAfterBackslash,p.representationStart,p.representationEnd,["4.3.1. Consume a token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],n)),n}}return p.advanceCodePoint(),[exports.TokenType.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]},endOfFile:function endOfFile(){return void 0===p.source.codePointAt(p.cursor)}}}function noop(){}function ensureThatValueRoundTripsAsIdent(e){let n=0;e[0]===C&&e[1]===C?n=2:e[0]===C&&e[1]?(n=2,isIdentStartCodePoint(e[1])||(n+=insertEscapedCodePoint(e,1,e[1]))):isIdentStartCodePoint(e[0])?n=1:(n=1,n+=insertEscapedCodePoint(e,0,e[0]));for(let o=n;o=48&&e<=57}function isUppercaseLetterCodePoint(e){return void 0!==e&&e>=65&&e<=90}function isLowercaseLetterCodePoint(e){return void 0!==e&&e>=97&&e<=122}function isHexDigitCodePoint(e){return void 0!==e&&(e>=48&&e<=57||e>=97&&e<=102||e>=65&&e<=70)}function isLetterCodePoint(e){return isLowercaseLetterCodePoint(e)||isUppercaseLetterCodePoint(e)}function isIdentStartCodePoint(e){return isLetterCodePoint(e)||isNonASCII_IdentCodePoint(e)||e===A}function isIdentCodePoint(e){return isIdentStartCodePoint(e)||isDigitCodePoint(e)||e===C}function isNonASCII_IdentCodePoint(e){return 183===e||8204===e||8205===e||8255===e||8256===e||8204===e||void 0!==e&&(192<=e&&e<=214||216<=e&&e<=246||248<=e&&e<=893||895<=e&&e<=8191||8304<=e&&e<=8591||11264<=e&&e<=12271||12289<=e&&e<=55295||63744<=e&&e<=64975||65008<=e&&e<=65533||e>=65536)}function isNewLine(e){return e===y||e===s||e===T}function isWhitespace(e){return e===B||e===y||e===i||e===s||e===T}function checkIfTwoCodePointsAreAValidEscape(e){return e.source.codePointAt(e.cursor)===L&&!isNewLine(e.source.codePointAt(e.cursor+1))}function checkIfThreeCodePointsWouldStartAnIdentSequence(e,n){return n.source.codePointAt(n.cursor)===C?n.source.codePointAt(n.cursor+1)===C||(!!isIdentStartCodePoint(n.source.codePointAt(n.cursor+1))||n.source.codePointAt(n.cursor+1)===L&&!isNewLine(n.source.codePointAt(n.cursor+2))):!!isIdentStartCodePoint(n.source.codePointAt(n.cursor))||checkIfTwoCodePointsAreAValidEscape(n)}function checkIfThreeCodePointsWouldStartANumber(e){return e.source.codePointAt(e.cursor)===D||e.source.codePointAt(e.cursor)===C?!!isDigitCodePoint(e.source.codePointAt(e.cursor+1))||e.source.codePointAt(e.cursor+1)===P&&isDigitCodePoint(e.source.codePointAt(e.cursor+2)):e.source.codePointAt(e.cursor)===P?isDigitCodePoint(e.source.codePointAt(e.cursor+1)):isDigitCodePoint(e.source.codePointAt(e.cursor))}function checkIfTwoCodePointsStartAComment(e){return e.source.codePointAt(e.cursor)===H&&e.source.codePointAt(e.cursor+1)===t}function checkIfThreeCodePointsWouldStartCDC(e){return e.source.codePointAt(e.cursor)===C&&e.source.codePointAt(e.cursor+1)===C&&e.source.codePointAt(e.cursor+2)===k}var G,X,Y;function consumeComment(n,o){for(o.advanceCodePoint(2);;){const r=o.readCodePoint();if(void 0===r){const t=[exports.TokenType.Comment,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInComment,o.representationStart,o.representationEnd,["4.3.2. Consume comments","Unexpected EOF"],t)),t}if(r===t&&(void 0!==o.source.codePointAt(o.cursor)&&o.source.codePointAt(o.cursor)===H)){o.advanceCodePoint();break}}return[exports.TokenType.Comment,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0]}function consumeEscapedCodePoint(n,o){const t=o.readCodePoint();if(void 0===t)return n.onParseError(new ParseError(e.UnexpectedEOFInEscapedCodePoint,o.representationStart,o.representationEnd,["4.3.7. Consume an escaped code point","Unexpected EOF"])),w;if(isHexDigitCodePoint(t)){const e=[t];let n;for(;void 0!==(n=o.source.codePointAt(o.cursor))&&isHexDigitCodePoint(n)&&e.length<6;)e.push(n),o.advanceCodePoint();isWhitespace(o.source.codePointAt(o.cursor))&&o.advanceCodePoint();const s=parseInt(String.fromCodePoint(...e),16);return 0===s?w:void 0!==(r=s)&&r>=55296&&r<=57343||s>g?w:s}var r;return t}function consumeIdentSequence(e,n){const o=[];for(;;){const t=n.source.codePointAt(n.cursor);if(isIdentCodePoint(t))o.push(t),n.advanceCodePoint(+(t>65535)+1);else{if(!checkIfTwoCodePointsAreAValidEscape(n))return o;n.advanceCodePoint(),o.push(consumeEscapedCodePoint(e,n))}}}function consumeHashToken(e,n){n.advanceCodePoint();const o=n.source.codePointAt(n.cursor);if(void 0!==o&&(isIdentCodePoint(o)||checkIfTwoCodePointsAreAValidEscape(n))){let o=exports.HashType.Unrestricted;checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)&&(o=exports.HashType.ID);const t=consumeIdentSequence(e,n);return[exports.TokenType.Hash,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t),type:o}]}return[exports.TokenType.Delim,"#",n.representationStart,n.representationEnd,{value:"#"}]}function consumeNumber(e,n){let o=exports.NumberType.Integer;for(n.source.codePointAt(n.cursor)!==D&&n.source.codePointAt(n.cursor)!==C||n.advanceCodePoint();isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===P&&isDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint(2),o=exports.NumberType.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===x||n.source.codePointAt(n.cursor)===f){if(isDigitCodePoint(n.source.codePointAt(n.cursor+1)))n.advanceCodePoint(2);else{if(n.source.codePointAt(n.cursor+1)!==C&&n.source.codePointAt(n.cursor+1)!==D||!isDigitCodePoint(n.source.codePointAt(n.cursor+2)))return o;n.advanceCodePoint(3)}for(o=exports.NumberType.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint()}return o}function consumeNumericToken(e,n){let o;{const e=n.source.codePointAt(n.cursor);e===C?o="-":e===D&&(o="+")}const t=consumeNumber(0,n),r=parseFloat(n.source.slice(n.representationStart,n.representationEnd+1));if(checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)){const s=consumeIdentSequence(e,n);return[exports.TokenType.Dimension,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o,type:t,unit:String.fromCodePoint(...s)}]}return n.source.codePointAt(n.cursor)===O?(n.advanceCodePoint(),[exports.TokenType.Percentage,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o}]):[exports.TokenType.Number,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:o,type:t}]}function consumeWhiteSpace(e){for(;isWhitespace(e.source.codePointAt(e.cursor));)e.advanceCodePoint();return[exports.TokenType.Whitespace,e.source.slice(e.representationStart,e.representationEnd+1),e.representationStart,e.representationEnd,void 0]}exports.TokenType=void 0,(G=exports.TokenType||(exports.TokenType={})).Comment="comment",G.AtKeyword="at-keyword-token",G.BadString="bad-string-token",G.BadURL="bad-url-token",G.CDC="CDC-token",G.CDO="CDO-token",G.Colon="colon-token",G.Comma="comma-token",G.Delim="delim-token",G.Dimension="dimension-token",G.EOF="EOF-token",G.Function="function-token",G.Hash="hash-token",G.Ident="ident-token",G.Number="number-token",G.Percentage="percentage-token",G.Semicolon="semicolon-token",G.String="string-token",G.URL="url-token",G.Whitespace="whitespace-token",G.OpenParen="(-token",G.CloseParen=")-token",G.OpenSquare="[-token",G.CloseSquare="]-token",G.OpenCurly="{-token",G.CloseCurly="}-token",G.UnicodeRange="unicode-range-token",exports.NumberType=void 0,(X=exports.NumberType||(exports.NumberType={})).Integer="integer",X.Number="number",exports.HashType=void 0,(Y=exports.HashType||(exports.HashType={})).Unrestricted="unrestricted",Y.ID="id";class Reader{cursor=0;source="";representationStart=0;representationEnd=-1;constructor(e){this.source=e}advanceCodePoint(e=1){this.cursor=this.cursor+e,this.representationEnd=this.cursor-1}readCodePoint(){const e=this.source.codePointAt(this.cursor);if(void 0!==e)return this.cursor=this.cursor+1,this.representationEnd=this.cursor-1,e}unreadCodePoint(e=1){this.cursor=this.cursor-e,this.representationEnd=this.cursor-1}resetRepresentation(){this.representationStart=this.cursor,this.representationEnd=-1}}function consumeStringToken(n,o){let t="";const r=o.readCodePoint();for(;;){const i=o.readCodePoint();if(void 0===i){const r=[exports.TokenType.String,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInString,o.representationStart,o.representationEnd,["4.3.5. Consume a string token","Unexpected EOF"],r)),r}if(isNewLine(i)){o.unreadCodePoint();const t=[exports.TokenType.BadString,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedNewLineInString,o.representationStart,o.source.codePointAt(o.cursor)===s&&o.source.codePointAt(o.cursor+1)===y?o.representationEnd+2:o.representationEnd+1,["4.3.5. Consume a string token","Unexpected newline"],t)),t}if(i===r)return[exports.TokenType.String,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:t}];if(i!==L)t+=String.fromCodePoint(i);else{if(void 0===o.source.codePointAt(o.cursor))continue;if(isNewLine(o.source.codePointAt(o.cursor))){o.source.codePointAt(o.cursor)===s&&o.source.codePointAt(o.cursor+1)===y&&o.advanceCodePoint(),o.advanceCodePoint();continue}t+=String.fromCodePoint(consumeEscapedCodePoint(n,o))}}}function checkIfCodePointsMatchURLIdent(e){return!(3!==e.length||e[0]!==V&&e[0]!==z||e[1]!==K&&e[1]!==M||e[2]!==$&&e[2]!==J)}function consumeBadURL(e,n){for(;;){const o=n.source.codePointAt(n.cursor);if(void 0===o)return;if(o===N)return void n.advanceCodePoint();checkIfTwoCodePointsAreAValidEscape(n)?(n.advanceCodePoint(),consumeEscapedCodePoint(e,n)):n.advanceCodePoint()}}function consumeUrlToken(n,t){for(;isWhitespace(t.source.codePointAt(t.cursor));)t.advanceCodePoint();let s="";for(;;){if(void 0===t.source.codePointAt(t.cursor)){const o=[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Unexpected EOF"],o)),o}if(t.source.codePointAt(t.cursor)===N)return t.advanceCodePoint(),[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}];if(isWhitespace(t.source.codePointAt(t.cursor))){for(t.advanceCodePoint();isWhitespace(t.source.codePointAt(t.cursor));)t.advanceCodePoint();if(void 0===t.source.codePointAt(t.cursor)){const o=[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Consume as much whitespace as possible","Unexpected EOF"],o)),o}return t.source.codePointAt(t.cursor)===N?(t.advanceCodePoint(),[exports.TokenType.URL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:s}]):(consumeBadURL(n,t),[exports.TokenType.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0])}const c=t.source.codePointAt(t.cursor);if(c===R||c===o||c===m||void 0!==(i=c)&&(i===v||i===d||I<=i&&i<=r||b<=i&&i<=l)){consumeBadURL(n,t);const o=[exports.TokenType.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedCharacterInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","Unexpected U+0022 QUOTATION MARK (\"), U+0027 APOSTROPHE ('), U+0028 LEFT PARENTHESIS (() or non-printable code point"],o)),o}if(c===L){if(checkIfTwoCodePointsAreAValidEscape(t)){t.advanceCodePoint(),s+=String.fromCodePoint(consumeEscapedCodePoint(n,t));continue}consumeBadURL(n,t);const o=[exports.TokenType.BadURL,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceInURL,t.representationStart,t.representationEnd,["4.3.6. Consume a url token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],o)),o}s+=t.source[t.cursor],t.advanceCodePoint()}var i}function consumeIdentLikeToken(e,n){const t=consumeIdentSequence(e,n);if(n.source.codePointAt(n.cursor)!==m)return[exports.TokenType.Ident,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}];if(checkIfCodePointsMatchURLIdent(t)){n.advanceCodePoint();let r=0;for(;;){const e=isWhitespace(n.source.codePointAt(n.cursor)),s=isWhitespace(n.source.codePointAt(n.cursor+1));if(e&&s){r+=1,n.advanceCodePoint(1);continue}const i=e?n.source.codePointAt(n.cursor+1):n.source.codePointAt(n.cursor);if(i===R||i===o)return r>0&&n.unreadCodePoint(r),[exports.TokenType.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}];break}return consumeUrlToken(e,n)}return n.advanceCodePoint(),[exports.TokenType.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...t)}]}function checkIfThreeCodePointsWouldStartAUnicodeRange(e){return!(e.source.codePointAt(e.cursor)!==V&&e.source.codePointAt(e.cursor)!==z||e.source.codePointAt(e.cursor+1)!==D||e.source.codePointAt(e.cursor+2)!==_&&!isHexDigitCodePoint(e.source.codePointAt(e.cursor+2)))}function consumeUnicodeRangeToken(e,n){n.advanceCodePoint(2);const o=[],t=[];let r;for(;void 0!==(r=n.source.codePointAt(n.cursor))&&o.length<6&&isHexDigitCodePoint(r);)o.push(r),n.advanceCodePoint();for(;void 0!==(r=n.source.codePointAt(n.cursor))&&o.length<6&&r===_;)0===t.length&&t.push(...o),o.push(j),t.push(Q),n.advanceCodePoint();if(!t.length&&n.source.codePointAt(n.cursor)===C&&isHexDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint();void 0!==(r=n.source.codePointAt(n.cursor))&&t.length<6&&isHexDigitCodePoint(r);)t.push(r),n.advanceCodePoint();if(!t.length){const e=parseInt(String.fromCodePoint(...o),16);return[exports.TokenType.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:e,endOfRange:e}]}const s=parseInt(String.fromCodePoint(...o),16),i=parseInt(String.fromCodePoint(...t),16);return[exports.TokenType.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:s,endOfRange:i}]}function tokenizer(n,t){const r=n.css.valueOf(),d=n.unicodeRangesAllowed??!1,p=new Reader(r),k={onParseError:t?.onParseError??noop};return{nextToken:function nextToken(){p.resetRepresentation();const n=p.source.codePointAt(p.cursor);if(void 0===n)return[exports.TokenType.EOF,"",-1,-1,void 0];if(n===H&&checkIfTwoCodePointsStartAComment(p))return consumeComment(k,p);if(d&&(n===V||n===z)&&checkIfThreeCodePointsWouldStartAUnicodeRange(p))return consumeUnicodeRangeToken(0,p);if(isIdentStartCodePoint(n))return consumeIdentLikeToken(k,p);if(isDigitCodePoint(n))return consumeNumericToken(k,p);switch(n){case a:return p.advanceCodePoint(),[exports.TokenType.Comma,",",p.representationStart,p.representationEnd,void 0];case c:return p.advanceCodePoint(),[exports.TokenType.Colon,":",p.representationStart,p.representationEnd,void 0];case q:return p.advanceCodePoint(),[exports.TokenType.Semicolon,";",p.representationStart,p.representationEnd,void 0];case m:return p.advanceCodePoint(),[exports.TokenType.OpenParen,"(",p.representationStart,p.representationEnd,void 0];case N:return p.advanceCodePoint(),[exports.TokenType.CloseParen,")",p.representationStart,p.representationEnd,void 0];case E:return p.advanceCodePoint(),[exports.TokenType.OpenSquare,"[",p.representationStart,p.representationEnd,void 0];case F:return p.advanceCodePoint(),[exports.TokenType.CloseSquare,"]",p.representationStart,p.representationEnd,void 0];case S:return p.advanceCodePoint(),[exports.TokenType.OpenCurly,"{",p.representationStart,p.representationEnd,void 0];case W:return p.advanceCodePoint(),[exports.TokenType.CloseCurly,"}",p.representationStart,p.representationEnd,void 0];case o:case R:return consumeStringToken(k,p);case U:return consumeHashToken(k,p);case D:case P:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(k,p):(p.advanceCodePoint(),[exports.TokenType.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]);case y:case s:case T:case i:case B:return consumeWhiteSpace(p);case C:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(k,p):checkIfThreeCodePointsWouldStartCDC(p)?(p.advanceCodePoint(3),[exports.TokenType.CDC,"--\x3e",p.representationStart,p.representationEnd,void 0]):checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)?consumeIdentLikeToken(k,p):(p.advanceCodePoint(),[exports.TokenType.Delim,"-",p.representationStart,p.representationEnd,{value:"-"}]);case h:return checkIfFourCodePointsWouldStartCDO(p)?(p.advanceCodePoint(4),[exports.TokenType.CDO,"\x3c!--",p.representationStart,p.representationEnd,void 0]):(p.advanceCodePoint(),[exports.TokenType.Delim,"<",p.representationStart,p.representationEnd,{value:"<"}]);case u:if(p.advanceCodePoint(),checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)){const e=consumeIdentSequence(k,p);return[exports.TokenType.AtKeyword,p.source.slice(p.representationStart,p.representationEnd+1),p.representationStart,p.representationEnd,{value:String.fromCodePoint(...e)}]}return[exports.TokenType.Delim,"@",p.representationStart,p.representationEnd,{value:"@"}];case L:{if(checkIfTwoCodePointsAreAValidEscape(p))return consumeIdentLikeToken(k,p);p.advanceCodePoint();const n=[exports.TokenType.Delim,"\\",p.representationStart,p.representationEnd,{value:"\\"}];return k.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceAfterBackslash,p.representationStart,p.representationEnd,["4.3.1. Consume a token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],n)),n}}return p.advanceCodePoint(),[exports.TokenType.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]},endOfFile:function endOfFile(){return void 0===p.source.codePointAt(p.cursor)}}}function noop(){}function ensureThatValueRoundTripsAsIdent(e){let n=0;e[0]===C&&e[1]===C?n=2:e[0]===C&&e[1]?(n=2,isIdentStartCodePoint(e[1])||(n+=insertEscapedCodePoint(e,1,e[1]))):isIdentStartCodePoint(e[0])?n=1:(n=1,n+=insertEscapedCodePoint(e,0,e[0]));for(let o=n;o): Array; -/** - * @internal - */ -export declare type CodePointReader = { - representationStart: number; - representationEnd: number; - cursor: number; - source: string; - advanceCodePoint(n?: number): void; - readCodePoint(): number | undefined; - unreadCodePoint(n?: number): void; - resetRepresentation(): void; -}; - /** * The union of all possible CSS tokens */ @@ -230,21 +216,6 @@ export declare class ParseErrorWithToken extends ParseError { constructor(message: string, sourceStart: number, sourceEnd: number, parserState: Array, token: CSSToken); } -/** - * @internal - */ -export declare class Reader implements CodePointReader { - cursor: number; - source: string; - representationStart: number; - representationEnd: number; - constructor(source: string); - advanceCodePoint(n?: number): void; - readCodePoint(): number | undefined; - unreadCodePoint(n?: number): void; - resetRepresentation(): void; -} - /** * Concatenate the string representation of a list of tokens. * This is not a proper serializer that will handle escaping and whitespace. diff --git a/packages/css-tokenizer/dist/index.mjs b/packages/css-tokenizer/dist/index.mjs index 04191c961..ef13d8640 100644 --- a/packages/css-tokenizer/dist/index.mjs +++ b/packages/css-tokenizer/dist/index.mjs @@ -1 +1 @@ -class ParseError extends Error{sourceStart;sourceEnd;parserState;constructor(e,n,t,o){super(e),this.name="ParseError",this.sourceStart=n,this.sourceEnd=t,this.parserState=o}}class ParseErrorWithToken extends ParseError{token;constructor(e,n,t,o,r){super(e,n,t,o),this.token=r}}const e={UnexpectedNewLineInString:"Unexpected newline while consuming a string token.",UnexpectedEOFInString:"Unexpected EOF while consuming a string token.",UnexpectedEOFInComment:"Unexpected EOF while consuming a comment.",UnexpectedEOFInURL:"Unexpected EOF while consuming a url token.",UnexpectedEOFInEscapedCodePoint:"Unexpected EOF while consuming an escaped code point.",UnexpectedCharacterInURL:"Unexpected character while consuming a url token.",InvalidEscapeSequenceInURL:"Invalid escape sequence while consuming a url token.",InvalidEscapeSequenceAfterBackslash:'Invalid escape sequence after "\\"'};class Reader{cursor=0;source="";representationStart=0;representationEnd=-1;constructor(e){this.source=e}advanceCodePoint(e=1){this.cursor=this.cursor+e,this.representationEnd=this.cursor-1}readCodePoint(){const e=this.source.codePointAt(this.cursor);if(void 0!==e)return this.cursor=this.cursor+1,this.representationEnd=this.cursor-1,e}unreadCodePoint(e=1){this.cursor=this.cursor-e,this.representationEnd=this.cursor-1}resetRepresentation(){this.representationStart=this.cursor,this.representationEnd=-1}}const n="undefined"!=typeof globalThis&&"structuredClone"in globalThis;function cloneTokens(e){return n?structuredClone(e):JSON.parse(JSON.stringify(e))}function stringify(...e){let n="";for(let t=0;t=48&&e<=57}function isUppercaseLetterCodePoint(e){return void 0!==e&&e>=65&&e<=90}function isLowercaseLetterCodePoint(e){return void 0!==e&&e>=97&&e<=122}function isHexDigitCodePoint(e){return void 0!==e&&(e>=48&&e<=57||e>=97&&e<=102||e>=65&&e<=70)}function isLetterCodePoint(e){return isLowercaseLetterCodePoint(e)||isUppercaseLetterCodePoint(e)}function isIdentStartCodePoint(e){return isLetterCodePoint(e)||isNonASCII_IdentCodePoint(e)||e===I}function isIdentCodePoint(e){return isIdentStartCodePoint(e)||isDigitCodePoint(e)||e===f}function isNonASCII_IdentCodePoint(e){return 183===e||8204===e||8205===e||8255===e||8256===e||8204===e||void 0!==e&&(192<=e&&e<=214||216<=e&&e<=246||248<=e&&e<=893||895<=e&&e<=8191||8304<=e&&e<=8591||11264<=e&&e<=12271||12289<=e&&e<=55295||63744<=e&&e<=64975||65008<=e&&e<=65533||e>=65536)}function isNewLine(e){return e===A||e===i||e===P}function isWhitespace(e){return e===H||e===A||e===s||e===i||e===P}function checkIfTwoCodePointsAreAValidEscape(e){return e.source.codePointAt(e.cursor)===W&&!isNewLine(e.source.codePointAt(e.cursor+1))}function checkIfThreeCodePointsWouldStartAnIdentSequence(e,n){return n.source.codePointAt(n.cursor)===f?n.source.codePointAt(n.cursor+1)===f||(!!isIdentStartCodePoint(n.source.codePointAt(n.cursor+1))||n.source.codePointAt(n.cursor+1)===W&&!isNewLine(n.source.codePointAt(n.cursor+2))):!!isIdentStartCodePoint(n.source.codePointAt(n.cursor))||checkIfTwoCodePointsAreAValidEscape(n)}function checkIfThreeCodePointsWouldStartANumber(e){return e.source.codePointAt(e.cursor)===w||e.source.codePointAt(e.cursor)===f?!!isDigitCodePoint(e.source.codePointAt(e.cursor+1))||e.source.codePointAt(e.cursor+1)===C&&isDigitCodePoint(e.source.codePointAt(e.cursor+2)):e.source.codePointAt(e.cursor)===C?isDigitCodePoint(e.source.codePointAt(e.cursor+1)):isDigitCodePoint(e.source.codePointAt(e.cursor))}function checkIfTwoCodePointsStartAComment(e){return e.source.codePointAt(e.cursor)===B&&e.source.codePointAt(e.cursor+1)===o}function checkIfThreeCodePointsWouldStartCDC(e){return e.source.codePointAt(e.cursor)===f&&e.source.codePointAt(e.cursor+1)===f&&e.source.codePointAt(e.cursor+2)===l}var G,X,Y;function mirrorVariantType(e){switch(e){case G.OpenParen:return G.CloseParen;case G.CloseParen:return G.OpenParen;case G.OpenCurly:return G.CloseCurly;case G.CloseCurly:return G.OpenCurly;case G.OpenSquare:return G.CloseSquare;case G.CloseSquare:return G.OpenSquare;default:return null}}function mirrorVariant(e){switch(e[0]){case G.OpenParen:return[G.CloseParen,")",-1,-1,void 0];case G.CloseParen:return[G.OpenParen,"(",-1,-1,void 0];case G.OpenCurly:return[G.CloseCurly,"}",-1,-1,void 0];case G.CloseCurly:return[G.OpenCurly,"{",-1,-1,void 0];case G.OpenSquare:return[G.CloseSquare,"]",-1,-1,void 0];case G.CloseSquare:return[G.OpenSquare,"[",-1,-1,void 0];default:return null}}function consumeComment(n,t){for(t.advanceCodePoint(2);;){const r=t.readCodePoint();if(void 0===r){const o=[G.Comment,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInComment,t.representationStart,t.representationEnd,["4.3.2. Consume comments","Unexpected EOF"],o)),o}if(r===o&&(void 0!==t.source.codePointAt(t.cursor)&&t.source.codePointAt(t.cursor)===B)){t.advanceCodePoint();break}}return[G.Comment,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0]}function consumeEscapedCodePoint(n,t){const o=t.readCodePoint();if(void 0===o)return n.onParseError(new ParseError(e.UnexpectedEOFInEscapedCodePoint,t.representationStart,t.representationEnd,["4.3.7. Consume an escaped code point","Unexpected EOF"])),x;if(isHexDigitCodePoint(o)){const e=[o];let n;for(;void 0!==(n=t.source.codePointAt(t.cursor))&&isHexDigitCodePoint(n)&&e.length<6;)e.push(n),t.advanceCodePoint();isWhitespace(t.source.codePointAt(t.cursor))&&t.advanceCodePoint();const i=parseInt(String.fromCodePoint(...e),16);return 0===i?x:void 0!==(r=i)&&r>=55296&&r<=57343||i>U?x:i}var r;return o}function consumeIdentSequence(e,n){const t=[];for(;;){const o=n.source.codePointAt(n.cursor);if(isIdentCodePoint(o))t.push(o),n.advanceCodePoint(+(o>65535)+1);else{if(!checkIfTwoCodePointsAreAValidEscape(n))return t;n.advanceCodePoint(),t.push(consumeEscapedCodePoint(e,n))}}}function consumeHashToken(e,n){n.advanceCodePoint();const t=n.source.codePointAt(n.cursor);if(void 0!==t&&(isIdentCodePoint(t)||checkIfTwoCodePointsAreAValidEscape(n))){let t=Y.Unrestricted;checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)&&(t=Y.ID);const o=consumeIdentSequence(e,n);return[G.Hash,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o),type:t}]}return[G.Delim,"#",n.representationStart,n.representationEnd,{value:"#"}]}function consumeNumber(e,n){let t=X.Integer;for(n.source.codePointAt(n.cursor)!==w&&n.source.codePointAt(n.cursor)!==f||n.advanceCodePoint();isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===C&&isDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint(2),t=X.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===k||n.source.codePointAt(n.cursor)===m){if(isDigitCodePoint(n.source.codePointAt(n.cursor+1)))n.advanceCodePoint(2);else{if(n.source.codePointAt(n.cursor+1)!==f&&n.source.codePointAt(n.cursor+1)!==w||!isDigitCodePoint(n.source.codePointAt(n.cursor+2)))return t;n.advanceCodePoint(3)}for(t=X.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint()}return t}function consumeNumericToken(e,n){let t;{const e=n.source.codePointAt(n.cursor);e===f?t="-":e===w&&(t="+")}const o=consumeNumber(0,n),r=parseFloat(n.source.slice(n.representationStart,n.representationEnd+1));if(checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)){const i=consumeIdentSequence(e,n);return[G.Dimension,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:t,type:o,unit:String.fromCodePoint(...i)}]}return n.source.codePointAt(n.cursor)===R?(n.advanceCodePoint(),[G.Percentage,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:t}]):[G.Number,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:t,type:o}]}function consumeWhiteSpace(e){for(;isWhitespace(e.source.codePointAt(e.cursor));)e.advanceCodePoint();return[G.Whitespace,e.source.slice(e.representationStart,e.representationEnd+1),e.representationStart,e.representationEnd,void 0]}function consumeStringToken(n,t){let o="";const r=t.readCodePoint();for(;;){const s=t.readCodePoint();if(void 0===s){const r=[G.String,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:o}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInString,t.representationStart,t.representationEnd,["4.3.5. Consume a string token","Unexpected EOF"],r)),r}if(isNewLine(s)){t.unreadCodePoint();const o=[G.BadString,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedNewLineInString,t.representationStart,t.source.codePointAt(t.cursor)===i&&t.source.codePointAt(t.cursor+1)===A?t.representationEnd+2:t.representationEnd+1,["4.3.5. Consume a string token","Unexpected newline"],o)),o}if(s===r)return[G.String,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:o}];if(s!==W)o+=String.fromCodePoint(s);else{if(void 0===t.source.codePointAt(t.cursor))continue;if(isNewLine(t.source.codePointAt(t.cursor))){t.source.codePointAt(t.cursor)===i&&t.source.codePointAt(t.cursor+1)===A&&t.advanceCodePoint(),t.advanceCodePoint();continue}o+=String.fromCodePoint(consumeEscapedCodePoint(n,t))}}}function checkIfCodePointsMatchURLIdent(e){return!(3!==e.length||e[0]!==V&&e[0]!==K||e[1]!==z&&e[1]!==M||e[2]!==$&&e[2]!==J)}function consumeBadURL(e,n){for(;;){const t=n.source.codePointAt(n.cursor);if(void 0===t)return;if(t===F)return void n.advanceCodePoint();checkIfTwoCodePointsAreAValidEscape(n)?(n.advanceCodePoint(),consumeEscapedCodePoint(e,n)):n.advanceCodePoint()}}function consumeUrlToken(n,o){for(;isWhitespace(o.source.codePointAt(o.cursor));)o.advanceCodePoint();let i="";for(;;){if(void 0===o.source.codePointAt(o.cursor)){const t=[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","Unexpected EOF"],t)),t}if(o.source.codePointAt(o.cursor)===F)return o.advanceCodePoint(),[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}];if(isWhitespace(o.source.codePointAt(o.cursor))){for(o.advanceCodePoint();isWhitespace(o.source.codePointAt(o.cursor));)o.advanceCodePoint();if(void 0===o.source.codePointAt(o.cursor)){const t=[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","Consume as much whitespace as possible","Unexpected EOF"],t)),t}return o.source.codePointAt(o.cursor)===F?(o.advanceCodePoint(),[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}]):(consumeBadURL(n,o),[G.BadURL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0])}const c=o.source.codePointAt(o.cursor);if(c===L||c===t||c===h||void 0!==(s=c)&&(s===g||s===d||O<=s&&s<=r||b<=s&&s<=S)){consumeBadURL(n,o);const t=[G.BadURL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedCharacterInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","Unexpected U+0022 QUOTATION MARK (\"), U+0027 APOSTROPHE ('), U+0028 LEFT PARENTHESIS (() or non-printable code point"],t)),t}if(c===W){if(checkIfTwoCodePointsAreAValidEscape(o)){o.advanceCodePoint(),i+=String.fromCodePoint(consumeEscapedCodePoint(n,o));continue}consumeBadURL(n,o);const t=[G.BadURL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],t)),t}i+=o.source[o.cursor],o.advanceCodePoint()}var s}function consumeIdentLikeToken(e,n){const o=consumeIdentSequence(e,n);if(n.source.codePointAt(n.cursor)!==h)return[G.Ident,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o)}];if(checkIfCodePointsMatchURLIdent(o)){n.advanceCodePoint();let r=0;for(;;){const e=isWhitespace(n.source.codePointAt(n.cursor)),i=isWhitespace(n.source.codePointAt(n.cursor+1));if(e&&i){r+=1,n.advanceCodePoint(1);continue}const s=e?n.source.codePointAt(n.cursor+1):n.source.codePointAt(n.cursor);if(s===L||s===t)return r>0&&n.unreadCodePoint(r),[G.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o)}];break}return consumeUrlToken(e,n)}return n.advanceCodePoint(),[G.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o)}]}function checkIfThreeCodePointsWouldStartAUnicodeRange(e){return!(e.source.codePointAt(e.cursor)!==V&&e.source.codePointAt(e.cursor)!==K||e.source.codePointAt(e.cursor+1)!==w||e.source.codePointAt(e.cursor+2)!==_&&!isHexDigitCodePoint(e.source.codePointAt(e.cursor+2)))}function consumeUnicodeRangeToken(e,n){n.advanceCodePoint(2);const t=[],o=[];let r;for(;void 0!==(r=n.source.codePointAt(n.cursor))&&t.length<6&&isHexDigitCodePoint(r);)t.push(r),n.advanceCodePoint();for(;void 0!==(r=n.source.codePointAt(n.cursor))&&t.length<6&&r===_;)0===o.length&&o.push(...t),t.push(j),o.push(Q),n.advanceCodePoint();if(!o.length&&n.source.codePointAt(n.cursor)===f&&isHexDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint();void 0!==(r=n.source.codePointAt(n.cursor))&&o.length<6&&isHexDigitCodePoint(r);)o.push(r),n.advanceCodePoint();if(!o.length){const e=parseInt(String.fromCodePoint(...t),16);return[G.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:e,endOfRange:e}]}const i=parseInt(String.fromCodePoint(...t),16),s=parseInt(String.fromCodePoint(...o),16);return[G.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:i,endOfRange:s}]}function tokenize(e,n){const t=tokenizer(e,n),o=[];{for(;!t.endOfFile();){const e=t.nextToken();e&&o.push(e)}const e=t.nextToken();e&&o.push(e)}return o}function tokenizer(n,o){const r=n.css.valueOf(),d=n.unicodeRangesAllowed??!1,p=new Reader(r),l={onParseError:o?.onParseError??noop};return{nextToken:function nextToken(){p.resetRepresentation();const n=p.source.codePointAt(p.cursor);if(void 0===n)return[G.EOF,"",-1,-1,void 0];if(n===B&&checkIfTwoCodePointsStartAComment(p))return consumeComment(l,p);if(d&&(n===V||n===K)&&checkIfThreeCodePointsWouldStartAUnicodeRange(p))return consumeUnicodeRangeToken(0,p);if(isIdentStartCodePoint(n))return consumeIdentLikeToken(l,p);if(isDigitCodePoint(n))return consumeNumericToken(l,p);switch(n){case a:return p.advanceCodePoint(),[G.Comma,",",p.representationStart,p.representationEnd,void 0];case c:return p.advanceCodePoint(),[G.Colon,":",p.representationStart,p.representationEnd,void 0];case N:return p.advanceCodePoint(),[G.Semicolon,";",p.representationStart,p.representationEnd,void 0];case h:return p.advanceCodePoint(),[G.OpenParen,"(",p.representationStart,p.representationEnd,void 0];case F:return p.advanceCodePoint(),[G.CloseParen,")",p.representationStart,p.representationEnd,void 0];case v:return p.advanceCodePoint(),[G.OpenSquare,"[",p.representationStart,p.representationEnd,void 0];case q:return p.advanceCodePoint(),[G.CloseSquare,"]",p.representationStart,p.representationEnd,void 0];case E:return p.advanceCodePoint(),[G.OpenCurly,"{",p.representationStart,p.representationEnd,void 0];case y:return p.advanceCodePoint(),[G.CloseCurly,"}",p.representationStart,p.representationEnd,void 0];case t:case L:return consumeStringToken(l,p);case D:return consumeHashToken(l,p);case w:case C:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(l,p):(p.advanceCodePoint(),[G.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]);case A:case i:case P:case s:case H:return consumeWhiteSpace(p);case f:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(l,p):checkIfThreeCodePointsWouldStartCDC(p)?(p.advanceCodePoint(3),[G.CDC,"--\x3e",p.representationStart,p.representationEnd,void 0]):checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)?consumeIdentLikeToken(l,p):(p.advanceCodePoint(),[G.Delim,"-",p.representationStart,p.representationEnd,{value:"-"}]);case T:return checkIfFourCodePointsWouldStartCDO(p)?(p.advanceCodePoint(4),[G.CDO,"\x3c!--",p.representationStart,p.representationEnd,void 0]):(p.advanceCodePoint(),[G.Delim,"<",p.representationStart,p.representationEnd,{value:"<"}]);case u:if(p.advanceCodePoint(),checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)){const e=consumeIdentSequence(l,p);return[G.AtKeyword,p.source.slice(p.representationStart,p.representationEnd+1),p.representationStart,p.representationEnd,{value:String.fromCodePoint(...e)}]}return[G.Delim,"@",p.representationStart,p.representationEnd,{value:"@"}];case W:{if(checkIfTwoCodePointsAreAValidEscape(p))return consumeIdentLikeToken(l,p);p.advanceCodePoint();const n=[G.Delim,"\\",p.representationStart,p.representationEnd,{value:"\\"}];return l.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceAfterBackslash,p.representationStart,p.representationEnd,["4.3.1. Consume a token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],n)),n}}return p.advanceCodePoint(),[G.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]},endOfFile:function endOfFile(){return void 0===p.source.codePointAt(p.cursor)}}}function noop(){}function mutateIdent(e,n){const t=[];for(const e of n)t.push(e.codePointAt(0));const o=String.fromCodePoint(...ensureThatValueRoundTripsAsIdent(t));e[1]=o,e[4].value=n}function mutateUnit(e,n){const t=[];for(const e of n)t.push(e.codePointAt(0));const o=ensureThatValueRoundTripsAsIdent(t);101===o[0]&&insertEscapedCodePoint(o,0,o[0]);const r=String.fromCodePoint(...o),i="+"===e[4].signCharacter?e[4].signCharacter:"",s=e[4].value.toString();e[1]=`${i}${s}${r}`,e[4].unit=n}function ensureThatValueRoundTripsAsIdent(e){let n=0;e[0]===f&&e[1]===f?n=2:e[0]===f&&e[1]?(n=2,isIdentStartCodePoint(e[1])||(n+=insertEscapedCodePoint(e,1,e[1]))):isIdentStartCodePoint(e[0])?n=1:(n=1,n+=insertEscapedCodePoint(e,0,e[0]));for(let t=n;t=48&&e<=57}function isUppercaseLetterCodePoint(e){return void 0!==e&&e>=65&&e<=90}function isLowercaseLetterCodePoint(e){return void 0!==e&&e>=97&&e<=122}function isHexDigitCodePoint(e){return void 0!==e&&(e>=48&&e<=57||e>=97&&e<=102||e>=65&&e<=70)}function isLetterCodePoint(e){return isLowercaseLetterCodePoint(e)||isUppercaseLetterCodePoint(e)}function isIdentStartCodePoint(e){return isLetterCodePoint(e)||isNonASCII_IdentCodePoint(e)||e===I}function isIdentCodePoint(e){return isIdentStartCodePoint(e)||isDigitCodePoint(e)||e===f}function isNonASCII_IdentCodePoint(e){return 183===e||8204===e||8205===e||8255===e||8256===e||8204===e||void 0!==e&&(192<=e&&e<=214||216<=e&&e<=246||248<=e&&e<=893||895<=e&&e<=8191||8304<=e&&e<=8591||11264<=e&&e<=12271||12289<=e&&e<=55295||63744<=e&&e<=64975||65008<=e&&e<=65533||e>=65536)}function isNewLine(e){return e===A||e===i||e===P}function isWhitespace(e){return e===H||e===A||e===s||e===i||e===P}function checkIfTwoCodePointsAreAValidEscape(e){return e.source.codePointAt(e.cursor)===W&&!isNewLine(e.source.codePointAt(e.cursor+1))}function checkIfThreeCodePointsWouldStartAnIdentSequence(e,n){return n.source.codePointAt(n.cursor)===f?n.source.codePointAt(n.cursor+1)===f||(!!isIdentStartCodePoint(n.source.codePointAt(n.cursor+1))||n.source.codePointAt(n.cursor+1)===W&&!isNewLine(n.source.codePointAt(n.cursor+2))):!!isIdentStartCodePoint(n.source.codePointAt(n.cursor))||checkIfTwoCodePointsAreAValidEscape(n)}function checkIfThreeCodePointsWouldStartANumber(e){return e.source.codePointAt(e.cursor)===w||e.source.codePointAt(e.cursor)===f?!!isDigitCodePoint(e.source.codePointAt(e.cursor+1))||e.source.codePointAt(e.cursor+1)===C&&isDigitCodePoint(e.source.codePointAt(e.cursor+2)):e.source.codePointAt(e.cursor)===C?isDigitCodePoint(e.source.codePointAt(e.cursor+1)):isDigitCodePoint(e.source.codePointAt(e.cursor))}function checkIfTwoCodePointsStartAComment(e){return e.source.codePointAt(e.cursor)===B&&e.source.codePointAt(e.cursor+1)===o}function checkIfThreeCodePointsWouldStartCDC(e){return e.source.codePointAt(e.cursor)===f&&e.source.codePointAt(e.cursor+1)===f&&e.source.codePointAt(e.cursor+2)===l}var G,X,Y;function mirrorVariantType(e){switch(e){case G.OpenParen:return G.CloseParen;case G.CloseParen:return G.OpenParen;case G.OpenCurly:return G.CloseCurly;case G.CloseCurly:return G.OpenCurly;case G.OpenSquare:return G.CloseSquare;case G.CloseSquare:return G.OpenSquare;default:return null}}function mirrorVariant(e){switch(e[0]){case G.OpenParen:return[G.CloseParen,")",-1,-1,void 0];case G.CloseParen:return[G.OpenParen,"(",-1,-1,void 0];case G.OpenCurly:return[G.CloseCurly,"}",-1,-1,void 0];case G.CloseCurly:return[G.OpenCurly,"{",-1,-1,void 0];case G.OpenSquare:return[G.CloseSquare,"]",-1,-1,void 0];case G.CloseSquare:return[G.OpenSquare,"[",-1,-1,void 0];default:return null}}function consumeComment(n,t){for(t.advanceCodePoint(2);;){const r=t.readCodePoint();if(void 0===r){const o=[G.Comment,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInComment,t.representationStart,t.representationEnd,["4.3.2. Consume comments","Unexpected EOF"],o)),o}if(r===o&&(void 0!==t.source.codePointAt(t.cursor)&&t.source.codePointAt(t.cursor)===B)){t.advanceCodePoint();break}}return[G.Comment,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0]}function consumeEscapedCodePoint(n,t){const o=t.readCodePoint();if(void 0===o)return n.onParseError(new ParseError(e.UnexpectedEOFInEscapedCodePoint,t.representationStart,t.representationEnd,["4.3.7. Consume an escaped code point","Unexpected EOF"])),x;if(isHexDigitCodePoint(o)){const e=[o];let n;for(;void 0!==(n=t.source.codePointAt(t.cursor))&&isHexDigitCodePoint(n)&&e.length<6;)e.push(n),t.advanceCodePoint();isWhitespace(t.source.codePointAt(t.cursor))&&t.advanceCodePoint();const i=parseInt(String.fromCodePoint(...e),16);return 0===i?x:void 0!==(r=i)&&r>=55296&&r<=57343||i>U?x:i}var r;return o}function consumeIdentSequence(e,n){const t=[];for(;;){const o=n.source.codePointAt(n.cursor);if(isIdentCodePoint(o))t.push(o),n.advanceCodePoint(+(o>65535)+1);else{if(!checkIfTwoCodePointsAreAValidEscape(n))return t;n.advanceCodePoint(),t.push(consumeEscapedCodePoint(e,n))}}}function consumeHashToken(e,n){n.advanceCodePoint();const t=n.source.codePointAt(n.cursor);if(void 0!==t&&(isIdentCodePoint(t)||checkIfTwoCodePointsAreAValidEscape(n))){let t=Y.Unrestricted;checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)&&(t=Y.ID);const o=consumeIdentSequence(e,n);return[G.Hash,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o),type:t}]}return[G.Delim,"#",n.representationStart,n.representationEnd,{value:"#"}]}function consumeNumber(e,n){let t=X.Integer;for(n.source.codePointAt(n.cursor)!==w&&n.source.codePointAt(n.cursor)!==f||n.advanceCodePoint();isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===C&&isDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint(2),t=X.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint();if(n.source.codePointAt(n.cursor)===k||n.source.codePointAt(n.cursor)===m){if(isDigitCodePoint(n.source.codePointAt(n.cursor+1)))n.advanceCodePoint(2);else{if(n.source.codePointAt(n.cursor+1)!==f&&n.source.codePointAt(n.cursor+1)!==w||!isDigitCodePoint(n.source.codePointAt(n.cursor+2)))return t;n.advanceCodePoint(3)}for(t=X.Number;isDigitCodePoint(n.source.codePointAt(n.cursor));)n.advanceCodePoint()}return t}function consumeNumericToken(e,n){let t;{const e=n.source.codePointAt(n.cursor);e===f?t="-":e===w&&(t="+")}const o=consumeNumber(0,n),r=parseFloat(n.source.slice(n.representationStart,n.representationEnd+1));if(checkIfThreeCodePointsWouldStartAnIdentSequence(0,n)){const i=consumeIdentSequence(e,n);return[G.Dimension,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:t,type:o,unit:String.fromCodePoint(...i)}]}return n.source.codePointAt(n.cursor)===R?(n.advanceCodePoint(),[G.Percentage,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:t}]):[G.Number,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:r,signCharacter:t,type:o}]}function consumeWhiteSpace(e){for(;isWhitespace(e.source.codePointAt(e.cursor));)e.advanceCodePoint();return[G.Whitespace,e.source.slice(e.representationStart,e.representationEnd+1),e.representationStart,e.representationEnd,void 0]}!function(e){e.Comment="comment",e.AtKeyword="at-keyword-token",e.BadString="bad-string-token",e.BadURL="bad-url-token",e.CDC="CDC-token",e.CDO="CDO-token",e.Colon="colon-token",e.Comma="comma-token",e.Delim="delim-token",e.Dimension="dimension-token",e.EOF="EOF-token",e.Function="function-token",e.Hash="hash-token",e.Ident="ident-token",e.Number="number-token",e.Percentage="percentage-token",e.Semicolon="semicolon-token",e.String="string-token",e.URL="url-token",e.Whitespace="whitespace-token",e.OpenParen="(-token",e.CloseParen=")-token",e.OpenSquare="[-token",e.CloseSquare="]-token",e.OpenCurly="{-token",e.CloseCurly="}-token",e.UnicodeRange="unicode-range-token"}(G||(G={})),function(e){e.Integer="integer",e.Number="number"}(X||(X={})),function(e){e.Unrestricted="unrestricted",e.ID="id"}(Y||(Y={}));class Reader{cursor=0;source="";representationStart=0;representationEnd=-1;constructor(e){this.source=e}advanceCodePoint(e=1){this.cursor=this.cursor+e,this.representationEnd=this.cursor-1}readCodePoint(){const e=this.source.codePointAt(this.cursor);if(void 0!==e)return this.cursor=this.cursor+1,this.representationEnd=this.cursor-1,e}unreadCodePoint(e=1){this.cursor=this.cursor-e,this.representationEnd=this.cursor-1}resetRepresentation(){this.representationStart=this.cursor,this.representationEnd=-1}}function consumeStringToken(n,t){let o="";const r=t.readCodePoint();for(;;){const s=t.readCodePoint();if(void 0===s){const r=[G.String,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:o}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInString,t.representationStart,t.representationEnd,["4.3.5. Consume a string token","Unexpected EOF"],r)),r}if(isNewLine(s)){t.unreadCodePoint();const o=[G.BadString,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedNewLineInString,t.representationStart,t.source.codePointAt(t.cursor)===i&&t.source.codePointAt(t.cursor+1)===A?t.representationEnd+2:t.representationEnd+1,["4.3.5. Consume a string token","Unexpected newline"],o)),o}if(s===r)return[G.String,t.source.slice(t.representationStart,t.representationEnd+1),t.representationStart,t.representationEnd,{value:o}];if(s!==W)o+=String.fromCodePoint(s);else{if(void 0===t.source.codePointAt(t.cursor))continue;if(isNewLine(t.source.codePointAt(t.cursor))){t.source.codePointAt(t.cursor)===i&&t.source.codePointAt(t.cursor+1)===A&&t.advanceCodePoint(),t.advanceCodePoint();continue}o+=String.fromCodePoint(consumeEscapedCodePoint(n,t))}}}function checkIfCodePointsMatchURLIdent(e){return!(3!==e.length||e[0]!==V&&e[0]!==K||e[1]!==z&&e[1]!==M||e[2]!==$&&e[2]!==J)}function consumeBadURL(e,n){for(;;){const t=n.source.codePointAt(n.cursor);if(void 0===t)return;if(t===F)return void n.advanceCodePoint();checkIfTwoCodePointsAreAValidEscape(n)?(n.advanceCodePoint(),consumeEscapedCodePoint(e,n)):n.advanceCodePoint()}}function consumeUrlToken(n,o){for(;isWhitespace(o.source.codePointAt(o.cursor));)o.advanceCodePoint();let i="";for(;;){if(void 0===o.source.codePointAt(o.cursor)){const t=[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","Unexpected EOF"],t)),t}if(o.source.codePointAt(o.cursor)===F)return o.advanceCodePoint(),[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}];if(isWhitespace(o.source.codePointAt(o.cursor))){for(o.advanceCodePoint();isWhitespace(o.source.codePointAt(o.cursor));)o.advanceCodePoint();if(void 0===o.source.codePointAt(o.cursor)){const t=[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}];return n.onParseError(new ParseErrorWithToken(e.UnexpectedEOFInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","Consume as much whitespace as possible","Unexpected EOF"],t)),t}return o.source.codePointAt(o.cursor)===F?(o.advanceCodePoint(),[G.URL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,{value:i}]):(consumeBadURL(n,o),[G.BadURL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0])}const c=o.source.codePointAt(o.cursor);if(c===L||c===t||c===h||void 0!==(s=c)&&(s===g||s===d||O<=s&&s<=r||b<=s&&s<=S)){consumeBadURL(n,o);const t=[G.BadURL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.UnexpectedCharacterInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","Unexpected U+0022 QUOTATION MARK (\"), U+0027 APOSTROPHE ('), U+0028 LEFT PARENTHESIS (() or non-printable code point"],t)),t}if(c===W){if(checkIfTwoCodePointsAreAValidEscape(o)){o.advanceCodePoint(),i+=String.fromCodePoint(consumeEscapedCodePoint(n,o));continue}consumeBadURL(n,o);const t=[G.BadURL,o.source.slice(o.representationStart,o.representationEnd+1),o.representationStart,o.representationEnd,void 0];return n.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceInURL,o.representationStart,o.representationEnd,["4.3.6. Consume a url token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],t)),t}i+=o.source[o.cursor],o.advanceCodePoint()}var s}function consumeIdentLikeToken(e,n){const o=consumeIdentSequence(e,n);if(n.source.codePointAt(n.cursor)!==h)return[G.Ident,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o)}];if(checkIfCodePointsMatchURLIdent(o)){n.advanceCodePoint();let r=0;for(;;){const e=isWhitespace(n.source.codePointAt(n.cursor)),i=isWhitespace(n.source.codePointAt(n.cursor+1));if(e&&i){r+=1,n.advanceCodePoint(1);continue}const s=e?n.source.codePointAt(n.cursor+1):n.source.codePointAt(n.cursor);if(s===L||s===t)return r>0&&n.unreadCodePoint(r),[G.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o)}];break}return consumeUrlToken(e,n)}return n.advanceCodePoint(),[G.Function,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{value:String.fromCodePoint(...o)}]}function checkIfThreeCodePointsWouldStartAUnicodeRange(e){return!(e.source.codePointAt(e.cursor)!==V&&e.source.codePointAt(e.cursor)!==K||e.source.codePointAt(e.cursor+1)!==w||e.source.codePointAt(e.cursor+2)!==_&&!isHexDigitCodePoint(e.source.codePointAt(e.cursor+2)))}function consumeUnicodeRangeToken(e,n){n.advanceCodePoint(2);const t=[],o=[];let r;for(;void 0!==(r=n.source.codePointAt(n.cursor))&&t.length<6&&isHexDigitCodePoint(r);)t.push(r),n.advanceCodePoint();for(;void 0!==(r=n.source.codePointAt(n.cursor))&&t.length<6&&r===_;)0===o.length&&o.push(...t),t.push(j),o.push(Q),n.advanceCodePoint();if(!o.length&&n.source.codePointAt(n.cursor)===f&&isHexDigitCodePoint(n.source.codePointAt(n.cursor+1)))for(n.advanceCodePoint();void 0!==(r=n.source.codePointAt(n.cursor))&&o.length<6&&isHexDigitCodePoint(r);)o.push(r),n.advanceCodePoint();if(!o.length){const e=parseInt(String.fromCodePoint(...t),16);return[G.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:e,endOfRange:e}]}const i=parseInt(String.fromCodePoint(...t),16),s=parseInt(String.fromCodePoint(...o),16);return[G.UnicodeRange,n.source.slice(n.representationStart,n.representationEnd+1),n.representationStart,n.representationEnd,{startOfRange:i,endOfRange:s}]}function tokenize(e,n){const t=tokenizer(e,n),o=[];{for(;!t.endOfFile();){const e=t.nextToken();e&&o.push(e)}const e=t.nextToken();e&&o.push(e)}return o}function tokenizer(n,o){const r=n.css.valueOf(),d=n.unicodeRangesAllowed??!1,p=new Reader(r),l={onParseError:o?.onParseError??noop};return{nextToken:function nextToken(){p.resetRepresentation();const n=p.source.codePointAt(p.cursor);if(void 0===n)return[G.EOF,"",-1,-1,void 0];if(n===B&&checkIfTwoCodePointsStartAComment(p))return consumeComment(l,p);if(d&&(n===V||n===K)&&checkIfThreeCodePointsWouldStartAUnicodeRange(p))return consumeUnicodeRangeToken(0,p);if(isIdentStartCodePoint(n))return consumeIdentLikeToken(l,p);if(isDigitCodePoint(n))return consumeNumericToken(l,p);switch(n){case a:return p.advanceCodePoint(),[G.Comma,",",p.representationStart,p.representationEnd,void 0];case c:return p.advanceCodePoint(),[G.Colon,":",p.representationStart,p.representationEnd,void 0];case N:return p.advanceCodePoint(),[G.Semicolon,";",p.representationStart,p.representationEnd,void 0];case h:return p.advanceCodePoint(),[G.OpenParen,"(",p.representationStart,p.representationEnd,void 0];case F:return p.advanceCodePoint(),[G.CloseParen,")",p.representationStart,p.representationEnd,void 0];case v:return p.advanceCodePoint(),[G.OpenSquare,"[",p.representationStart,p.representationEnd,void 0];case q:return p.advanceCodePoint(),[G.CloseSquare,"]",p.representationStart,p.representationEnd,void 0];case E:return p.advanceCodePoint(),[G.OpenCurly,"{",p.representationStart,p.representationEnd,void 0];case y:return p.advanceCodePoint(),[G.CloseCurly,"}",p.representationStart,p.representationEnd,void 0];case t:case L:return consumeStringToken(l,p);case D:return consumeHashToken(l,p);case w:case C:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(l,p):(p.advanceCodePoint(),[G.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]);case A:case i:case P:case s:case H:return consumeWhiteSpace(p);case f:return checkIfThreeCodePointsWouldStartANumber(p)?consumeNumericToken(l,p):checkIfThreeCodePointsWouldStartCDC(p)?(p.advanceCodePoint(3),[G.CDC,"--\x3e",p.representationStart,p.representationEnd,void 0]):checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)?consumeIdentLikeToken(l,p):(p.advanceCodePoint(),[G.Delim,"-",p.representationStart,p.representationEnd,{value:"-"}]);case T:return checkIfFourCodePointsWouldStartCDO(p)?(p.advanceCodePoint(4),[G.CDO,"\x3c!--",p.representationStart,p.representationEnd,void 0]):(p.advanceCodePoint(),[G.Delim,"<",p.representationStart,p.representationEnd,{value:"<"}]);case u:if(p.advanceCodePoint(),checkIfThreeCodePointsWouldStartAnIdentSequence(0,p)){const e=consumeIdentSequence(l,p);return[G.AtKeyword,p.source.slice(p.representationStart,p.representationEnd+1),p.representationStart,p.representationEnd,{value:String.fromCodePoint(...e)}]}return[G.Delim,"@",p.representationStart,p.representationEnd,{value:"@"}];case W:{if(checkIfTwoCodePointsAreAValidEscape(p))return consumeIdentLikeToken(l,p);p.advanceCodePoint();const n=[G.Delim,"\\",p.representationStart,p.representationEnd,{value:"\\"}];return l.onParseError(new ParseErrorWithToken(e.InvalidEscapeSequenceAfterBackslash,p.representationStart,p.representationEnd,["4.3.1. Consume a token","U+005C REVERSE SOLIDUS (\\)","The input stream does not start with a valid escape sequence"],n)),n}}return p.advanceCodePoint(),[G.Delim,p.source[p.representationStart],p.representationStart,p.representationEnd,{value:p.source[p.representationStart]}]},endOfFile:function endOfFile(){return void 0===p.source.codePointAt(p.cursor)}}}function noop(){}function mutateIdent(e,n){const t=[];for(const e of n)t.push(e.codePointAt(0));const o=String.fromCodePoint(...ensureThatValueRoundTripsAsIdent(t));e[1]=o,e[4].value=n}function mutateUnit(e,n){const t=[];for(const e of n)t.push(e.codePointAt(0));const o=ensureThatValueRoundTripsAsIdent(t);101===o[0]&&insertEscapedCodePoint(o,0,o[0]);const r=String.fromCodePoint(...o),i="+"===e[4].signCharacter?e[4].signCharacter:"",s=e[4].value.toString();e[1]=`${i}${s}${r}`,e[4].unit=n}function ensureThatValueRoundTripsAsIdent(e){let n=0;e[0]===f&&e[1]===f?n=2:e[0]===f&&e[1]?(n=2,isIdentStartCodePoint(e[1])||(n+=insertEscapedCodePoint(e,1,e[1]))):isIdentStartCodePoint(e[0])?n=1:(n=1,n+=insertEscapedCodePoint(e,0,e[0]));for(let t=n;t Date: Sat, 3 Aug 2024 19:27:23 +0200 Subject: [PATCH 4/5] update results --- .../test/community/bootstrap-benchmark.mjs | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/css-tokenizer/test/community/bootstrap-benchmark.mjs b/packages/css-tokenizer/test/community/bootstrap-benchmark.mjs index 0f4818f8a..309d7605a 100644 --- a/packages/css-tokenizer/test/community/bootstrap-benchmark.mjs +++ b/packages/css-tokenizer/test/community/bootstrap-benchmark.mjs @@ -353,61 +353,61 @@ postcssLargeSource(); // Last result: // -------------- csstools tokenizer ------------- // tokens 43 -// tokens/μs @ 95th 2.445543991355516 -// tokens/μs @ 50th 7.818181818179839 -// tokens/μs @ 5th 9.213627598019114 +// tokens/μs @ 95th 2.224176278900998 +// tokens/μs @ 50th 9.92384029540142 +// tokens/μs @ 5th 11.862068965518729 // ----------------------------------------------- -// 95th 0.01758299999999835 -// 50th 0.005500000000001393 -// 5th 0.004667000000004862 -// deviation 0.012915999999993488 +// 95th 0.019333000000003153 +// 50th 0.004333000000002585 +// 5th 0.0036249999999995453 +// deviation 0.015708000000003608 // -------------- postcss tokenizer ------------- // tokens 24 -// tokens/μs @ 95th 4.721621089901807 +// tokens/μs @ 95th 4.500281267579009 // tokens/μs @ 50th 16.937191249075372 // tokens/μs @ 5th 17.454545454597408 // ----------------------------------------------- -// 95th 0.005083000000006166 +// 95th 0.005333000000000254 // 50th 0.0014170000000035543 // 5th 0.0013749999999959073 -// deviation 0.0037080000000102586 +// deviation 0.003958000000004347 // -------------- csstools tokenizer ------------- // tokens 254 -// tokens/μs @ 95th 3.4577581747392014 -// tokens/μs @ 50th 8.09561752988124 -// tokens/μs @ 5th 8.514061609627937 +// tokens/μs @ 95th 4.452859296657837 +// tokens/μs @ 50th 8.7333241644877 +// tokens/μs @ 5th 9.600120946403736 // ----------------------------------------------- -// 95th 0.07345800000000224 -// 50th 0.031374999999997044 -// 5th 0.029832999999996446 -// deviation 0.0436250000000058 +// 95th 0.05704200000000981 +// 50th 0.02908400000000455 +// 5th 0.0264580000000052 +// deviation 0.030584000000004608 // -------------- postcss tokenizer ------------- // tokens 214 -// tokens/μs @ 95th 8.503198633131982 -// tokens/μs @ 50th 33.56862745102589 -// tokens/μs @ 5th 34.4716494845312 +// tokens/μs @ 95th 8.588858564776066 +// tokens/μs @ 50th 33.354114713209 +// tokens/μs @ 5th 36.42553191496199 // ----------------------------------------------- -// 95th 0.025166999999996165 -// 50th 0.00637499999999136 -// 5th 0.0062080000000008795 -// deviation 0.018958999999995285 +// 95th 0.0249160000000046 +// 50th 0.006416000000001532 +// 5th 0.005874999999988972 +// deviation 0.01904100000001563 // -------------- csstools tokenizer ------------- // tokens 87709 -// tokens/μs @ 95th 6.563939456304076 -// tokens/μs @ 50th 8.16464186638891 -// tokens/μs @ 5th 8.251178870870593 +// tokens/μs @ 95th 9.569123769860967 +// tokens/μs @ 50th 9.760582022651974 +// tokens/μs @ 5th 9.936257012018164 // ----------------------------------------------- -// 95th 13.362250000000131 -// 50th 10.742541000000074 -// 5th 10.629875000000538 -// deviation 2.7323749999995925 +// 95th 9.165834000000018 +// 50th 8.986042000000452 +// 5th 8.827166999999463 +// deviation 0.33866700000055516 // -------------- postcss tokenizer ------------- // tokens 66238 -// tokens/μs @ 95th 15.56191875982649 -// tokens/μs @ 50th 27.895556959361063 -// tokens/μs @ 5th 30.688828400983496 +// tokens/μs @ 95th 23.904005774083252 +// tokens/μs @ 50th 30.075140175537726 +// tokens/μs @ 5th 30.758300441137337 // ----------------------------------------------- -// 95th 4.256415999998353 -// 50th 2.374499999999898 -// 5th 2.1583750000008877 -// deviation 2.0980409999974654 +// 95th 2.7710000000006403 +// 50th 2.2024170000004233 +// 5th 2.1535000000003492 +// deviation 0.617500000000291 From 52e353bed502011f4c99cc29b2a30021b44a4f7f Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Sat, 3 Aug 2024 19:32:11 +0200 Subject: [PATCH 5/5] update --- package-lock.json | 8 ++++---- packages/css-tokenizer/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 28942a6e7..d1585c182 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3026,9 +3026,9 @@ "dev": true }, "node_modules/@rmenke/css-tokenizer-tests": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rmenke/css-tokenizer-tests/-/css-tokenizer-tests-1.1.5.tgz", - "integrity": "sha512-C+ETPdnrHwJXfaetFz3HEmIQo7ztLtlx/XfxgPE/XGFQzW9vdMOxIW0i5IxeAEdql7aguGjQSI0W7eqvS3pABQ==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rmenke/css-tokenizer-tests/-/css-tokenizer-tests-1.1.6.tgz", + "integrity": "sha512-58z1pZzSOW1TaudB1hSQ+c17K327gC9JlQDoV1oj56M4/BdQ6euoiGdCpIAFRonf2QxjFXDwqJr07HMOM6BjGA==", "dev": true }, "node_modules/@rollup/plugin-babel": { @@ -9420,7 +9420,7 @@ ], "license": "MIT", "devDependencies": { - "@rmenke/css-tokenizer-tests": "^1.1.5", + "@rmenke/css-tokenizer-tests": "^1.1.6", "postcss": "^8.4.38", "postcss-parser-tests": "^8.8.0" }, diff --git a/packages/css-tokenizer/package.json b/packages/css-tokenizer/package.json index aaef0ce91..3e3a49a27 100644 --- a/packages/css-tokenizer/package.json +++ b/packages/css-tokenizer/package.json @@ -48,7 +48,7 @@ "dist" ], "devDependencies": { - "@rmenke/css-tokenizer-tests": "^1.1.5", + "@rmenke/css-tokenizer-tests": "^1.1.6", "postcss": "^8.4.38", "postcss-parser-tests": "^8.8.0" },