New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@adguard/css-tokenizer

Package Overview
Dependencies
Maintainers
0
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@adguard/css-tokenizer - npm Package Compare versions

Comparing version 0.0.1 to 1.0.0-alpha.0

dist/csstokenizer.esm.mjs

2

dist/build.txt

@@ -1,1 +0,1 @@

version=0.0.1
version=1.0.0-alpha.0
/*
* CSSTokenizer v0.0.1 (build date: Mon, 30 Oct 2023 16:57:22 GMT)
* (c) 2023 AdGuard Software Ltd.
* CSSTokenizer v1.0.0-alpha.0 (build date: Mon, 29 Jul 2024 13:42:35 GMT)
* (c) 2024 Adguard Software Ltd.
* Released under the MIT license

@@ -181,2 +181,6 @@ * https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/css-tokenizer#readme

/**
* Consumes a single whitespace code point, if the current code point is a whitespace
*/
consumeSingleWhitespace(): void;
/**
* Consumes everything until the end of the comment (or the end of the source)

@@ -214,5 +218,4 @@ */

* not otherwise set
* @todo Create a more specific type for `props` parameter, if needed & possible
*/
type OnTokenCallback = (type: TokenType, start: number, end: number, props?: object) => void;
type OnTokenCallback = (type: TokenType, start: number, end: number, props?: Record<string, unknown>) => void;
/**

@@ -241,9 +244,12 @@ * Callback which is called when a parsing error is found. According to the spec, parsing errors are not fatal and

/**
* Pairs of token types and their base names
*/
declare const TOKEN_NAMES: Record<TokenType, string>;
/**
* Get base token name by token type
*
* @param type Token type
*
* @example
* ```ts
* getBaseTokenName(TokenType.Ident); // 'ident'
* getBaseTokenName(-1); // 'unknown'
* ```
*
* @returns Base token name or 'unknown' if token type is unknown

@@ -256,2 +262,9 @@ */

* @param type Token type
*
* @example
* ```ts
* getFormattedTokenName(TokenType.Ident); // '<ident-token>'
* getFormattedTokenName(-1); // '<unknown-token>'
* ```
*
* @returns Formatted token name or `'<unknown-token>'` if token type is unknown

@@ -304,6 +317,24 @@ */

/**
* @file CSS identifier decoder.
*/
/**
* Decodes a CSS identifier according to the CSS Syntax Module Level 3 specification.
*
* @param ident CSS identifier to decode.
*
* @example
* ```ts
* decodeIdent(String.raw`\00075\00072\0006C`); // 'url'
* decodeIdent('url'); // 'url'
* ```
*
* @returns Decoded CSS identifier.
*/
declare const decodeIdent: (ident: string) => string;
/**
* @file Package version
*/
declare const version: string;
declare const CSS_TOKENIZER_VERSION: string;
export { type OnErrorCallback, type OnTokenCallback, TOKEN_NAMES, TokenType, TokenizerContext, type TokenizerContextFunction, getBaseTokenName, getFormattedTokenName, tokenize, tokenizeExtended, version };
export { CSS_TOKENIZER_VERSION, type OnErrorCallback, type OnTokenCallback, TokenType, TokenizerContext, type TokenizerContextFunction, decodeIdent, getBaseTokenName, getFormattedTokenName, tokenize, tokenizeExtended };
/*
* CSSTokenizer v0.0.1 (build date: Mon, 30 Oct 2023 16:57:22 GMT)
* (c) 2023 AdGuard Software Ltd.
* CSSTokenizer v1.0.0-alpha.0 (build date: Mon, 29 Jul 2024 13:42:35 GMT)
* (c) 2024 Adguard Software Ltd.
* Released under the MIT license
* https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/css-tokenizer#readme
*/
function _defineProperty(e,o,n){return(o=_toPropertyKey(o))in e?Object.defineProperty(e,o,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[o]=n,e}function _toPropertyKey(e){var o=_toPrimitive(e,"string");return"symbol"==typeof o?o:String(o)}function _toPrimitive(e,o){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var t=n.call(e,o||"default");if("object"!=typeof t)return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===o?String:Number)(e)}var CSSTokenizer=function(e){"use strict";function o(e,o,n){return e>=o&&e<=n}function n(e,o){return e>=o}function t(e){return o(e,48,57)}function i(e){return t(e)||o(e,65,70)||o(e,97,102)}function r(e){return o(e,65,90)}function s(e){return o(e,97,122)}function c(e){return r(e)||s(e)}function d(e){return n(e,128)}function a(e){return c(e)||d(e)||95===e}function f(e){return a(e)||t(e)||45===e}function T(e){return 10===e||13===e||12===e}function u(e){return T(e)||9===e||32===e}const k=(e,o)=>92===e&&!T(o),l=(e,o,n)=>45===e?a(o)||45===o||k(o,n):!!a(e)||92===e&&k(e,o),p=(e,o,n)=>43===e||45===e?!!t(o)||46===o&&t(n):t(46===e?o:e);function m(e,o,n){let t=5381;for(let i=o;i<n;i+=1)t=33*t^(32|e[i]);return t>>>0}class C{constructor(e,o,n,t){var i;if(_defineProperty(this,"length",void 0),_defineProperty(this,"onToken",void 0),_defineProperty(this,"onError",void 0),_defineProperty(this,"codes",void 0),_defineProperty(this,"cursor",void 0),_defineProperty(this,"customFunctionHandlers",void 0),this.length=e.length,this.preprocess(e),this.cursor=65279===(i=this.codes[0])||65534===i?1:0,this.onToken=o,this.onError=n,t){this.customFunctionHandlers=new Map;for(const[e,o]of t)this.customFunctionHandlers.set(e,o)}}preprocess(e){const o=e.length;this.codes=new Int32Array(o+1);for(let n=0;n<o;n+=1)this.codes[n]=e.charCodeAt(n);this.codes[o]=-1}getFunctionHandler(e){var o;return null===(o=this.customFunctionHandlers)||void 0===o?void 0:o.get(e)}hasFunctionHandler(e){var o;return(null===(o=this.customFunctionHandlers)||void 0===o?void 0:o.has(e))??!1}get offset(){return this.cursor}get code(){return this.codes[this.offset]}get prevCode(){return this.codes[this.offset-1]}get nextCode(){return this.codes[this.offset+1]}getRelativeCode(e){return this.codes[this.offset+e]}isEof(){return this.offset>=this.length}isNextEof(){return this.cursor+1===this.length}isLessThanEqualToEof(){return this.offset<=this.length}consumeCodePoint(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this.cursor+=e}getNextNonWsCode(){let e=this.cursor;for(;e<this.length&&u(this.codes[e]);)e+=1;return this.codes[e]}consumeWhitespace(){for(;this.code&&u(this.code);)this.consumeCodePoint()}consumeUntilCommentEnd(){for(;this.cursor<this.length;){if(42===this.code&&47===this.nextCode){this.cursor+=2;break}this.cursor+=1}}consumeTrivialToken(e){this.onToken(e,this.cursor,++this.cursor)}getHashFrom(e){return m(this.codes,e,this.cursor)}}var h;e.TokenType=void 0,(h=e.TokenType||(e.TokenType={}))[h.Eof=0]="Eof",h[h.Ident=1]="Ident",h[h.Function=2]="Function",h[h.AtKeyword=3]="AtKeyword",h[h.Hash=4]="Hash",h[h.String=5]="String",h[h.BadString=6]="BadString",h[h.Url=7]="Url",h[h.BadUrl=8]="BadUrl",h[h.Delim=9]="Delim",h[h.Number=10]="Number",h[h.Percentage=11]="Percentage",h[h.Dimension=12]="Dimension",h[h.Whitespace=13]="Whitespace",h[h.Cdo=14]="Cdo",h[h.Cdc=15]="Cdc",h[h.Colon=16]="Colon",h[h.Semicolon=17]="Semicolon",h[h.Comma=18]="Comma",h[h.OpenSquareBracket=19]="OpenSquareBracket",h[h.CloseSquareBracket=20]="CloseSquareBracket",h[h.OpenParenthesis=21]="OpenParenthesis",h[h.CloseParenthesis=22]="CloseParenthesis",h[h.OpenCurlyBracket=23]="OpenCurlyBracket",h[h.CloseCurlyBracket=24]="CloseCurlyBracket",h[h.Comment=25]="Comment";const v=Object.freeze({[e.TokenType.Eof]:"eof",[e.TokenType.Ident]:"ident",[e.TokenType.Function]:"function",[e.TokenType.AtKeyword]:"at-keyword",[e.TokenType.Hash]:"hash",[e.TokenType.String]:"string",[e.TokenType.BadString]:"bad-string",[e.TokenType.Url]:"url",[e.TokenType.BadUrl]:"bad-url",[e.TokenType.Delim]:"delim",[e.TokenType.Number]:"number",[e.TokenType.Percentage]:"percentage",[e.TokenType.Dimension]:"dimension",[e.TokenType.Whitespace]:"whitespace",[e.TokenType.Cdo]:"CDO",[e.TokenType.Cdc]:"CDC",[e.TokenType.Colon]:"colon",[e.TokenType.Semicolon]:"semicolon",[e.TokenType.Comma]:"comma",[e.TokenType.OpenSquareBracket]:"[",[e.TokenType.CloseSquareBracket]:"]",[e.TokenType.OpenParenthesis]:"(",[e.TokenType.CloseParenthesis]:")",[e.TokenType.OpenCurlyBracket]:"{",[e.TokenType.CloseCurlyBracket]:"}",[e.TokenType.Comment]:"comment"}),y=e=>v[e]??"unknown",g=e=>{if(e.consumeCodePoint(),i(e.code)){let o=0;for(;i(e.code)&&o<5;)e.consumeCodePoint(),o+=1}e.isEof()&&e.onError("Unexpected end of file while parsing escaped code point.",e.offset,e.offset)},P=e=>{for(;!e.isEof();)if(f(e.code))e.consumeCodePoint();else{if(!k(e.code,e.nextCode))return;e.consumeCodePoint(),g(e)}};function b(e){for(;!e.isEof();e.consumeCodePoint()){if(41===e.code)return void e.consumeCodePoint();k(e.getRelativeCode(1),e.getRelativeCode(2))&&(e.consumeCodePoint(),g(e))}}function E(o,n){b(o),o.onToken(e.TokenType.BadUrl,n,o.offset)}const R=(n,t)=>{for(;u(n.code);)n.consumeCodePoint();for(;n.offset<=n.length;){if(41===n.code)return n.consumeCodePoint(),void n.onToken(e.TokenType.Url,t,n.offset);if(n.isEof())return n.onToken(e.TokenType.Url,t,n.offset),void n.onError("Unexpected end of file while parsing URL.",t,n.offset);if(u(n.code)){for(;u(n.code);)n.consumeCodePoint();return 41===n.code||n.isEof()?(n.consumeCodePoint(),n.onToken(e.TokenType.Url,t,n.offset),void n.onError("Unexpected end of file while parsing URL.",t,n.offset)):(n.onError("Unexpected character in URL.",t,n.offset),void E(n,t))}if(34===n.code||39===n.code||40===n.code||(o(i=n.code,0,8)||11===i||o(i,14,31)||127===i))return n.onError("Unexpected character in URL.",t,n.offset),void E(n,t);if(92===n.code){if(k(n.code,n.nextCode)){n.consumeCodePoint(),g(n);continue}return n.onError("Unexpected character in URL.",t,n.offset),void E(n,t)}n.consumeCodePoint()}var i},S=o=>{const n=o.offset;if(P(o),40===o.code){const t=o.getHashFrom(n);if(o.consumeCodePoint(),193422222===t){const t=o.getNextNonWsCode();return 34===t||39===t?void o.onToken(e.TokenType.Function,n,o.offset):void R(o,n)}return o.hasFunctionHandler(t)?(o.onToken(e.TokenType.Function,n,o.offset),void o.getFunctionHandler(t)(o)):void o.onToken(e.TokenType.Function,n,o.offset)}o.onToken(e.TokenType.Ident,n,o.offset)},x=e=>{for(43!==e.code&&45!==e.code||e.consumeCodePoint();t(e.code);)e.consumeCodePoint();if(46===e.code&&t(e.nextCode))for(e.consumeCodePoint(2);t(e.code);)e.consumeCodePoint();if(69===e.code||101===e.code)if(45!==e.nextCode&&43!==e.nextCode||!t(e.getRelativeCode(2))){if(t(e.nextCode))for(e.consumeCodePoint(2);t(e.code);)e.consumeCodePoint()}else for(e.consumeCodePoint(3);t(e.code);)e.consumeCodePoint()},U=o=>{const n=o.offset;return x(o),l(o.code,o.nextCode,o.getRelativeCode(2))?(P(o),void o.onToken(e.TokenType.Dimension,n,o.offset)):37===o.code?(o.consumeCodePoint(),void o.onToken(e.TokenType.Percentage,n,o.offset)):void o.onToken(e.TokenType.Number,n,o.offset)},w=o=>{const n=o.code,t=o.offset;for(o.consumeCodePoint();o.isLessThanEqualToEof();)switch(o.code){case n:return o.consumeCodePoint(),void o.onToken(e.TokenType.String,t,o.offset);case-1:return o.onToken(e.TokenType.String,t,o.offset),void o.onError("Unexpected end of file while parsing string token.",t,o.offset);case 13:case 10:case 12:return 13===o.code&&10===o.nextCode&&o.consumeCodePoint(1),o.consumeCodePoint(1),o.onToken(e.TokenType.BadString,t,o.offset),void o.onError("Unexpected newline while parsing string token.",t,o.offset);case 92:if(o.isNextEof())return o.consumeCodePoint(),o.onToken(e.TokenType.String,t,o.offset),void o.onError("Unexpected end of file while parsing string token.",t,o.offset);if(T(o.nextCode)){o.consumeCodePoint(2);break}k(o.code,o.nextCode)&&(o.consumeCodePoint(),g(o));break;default:o.consumeCodePoint()}},B=o=>{const n=o.offset;o.consumeWhitespace(),o.onToken(e.TokenType.Whitespace,n,o.offset)},D=function(o,n){const t=new C(o,n,arguments.length>2&&void 0!==arguments[2]?arguments[2]:()=>{},arguments.length>3?arguments[3]:void 0);for(;!t.isEof();)switch(t.code){case 9:case 32:case 10:case 12:case 13:B(t);break;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:U(t);break;case 40:t.consumeTrivialToken(e.TokenType.OpenParenthesis);break;case 41:t.consumeTrivialToken(e.TokenType.CloseParenthesis);break;case 44:t.consumeTrivialToken(e.TokenType.Comma);break;case 58:t.consumeTrivialToken(e.TokenType.Colon);break;case 59:t.consumeTrivialToken(e.TokenType.Semicolon);break;case 91:t.consumeTrivialToken(e.TokenType.OpenSquareBracket);break;case 93:t.consumeTrivialToken(e.TokenType.CloseSquareBracket);break;case 123:t.consumeTrivialToken(e.TokenType.OpenCurlyBracket);break;case 125:t.consumeTrivialToken(e.TokenType.CloseCurlyBracket);break;case 39:case 34:w(t);break;case 35:if(f(t.getRelativeCode(1))||k(t.getRelativeCode(1),t.getRelativeCode(2))){const o=t.offset;t.consumeCodePoint(),P(t),t.onToken(e.TokenType.Hash,o,t.offset);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 43:case 46:if(p(t.code,t.getRelativeCode(1),t.getRelativeCode(2))){U(t);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 45:if(p(t.code,t.getRelativeCode(1),t.getRelativeCode(2))){U(t);break}if(45===t.getRelativeCode(1)&&62===t.getRelativeCode(2)){t.consumeCodePoint(3),t.onToken(e.TokenType.Cdc,t.offset-3,t.offset);break}if(l(t.code,t.getRelativeCode(1),t.getRelativeCode(2))){S(t);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 60:if(33===t.getRelativeCode(1)&&45===t.getRelativeCode(2)&&45===t.getRelativeCode(3)){t.consumeCodePoint(4),t.onToken(e.TokenType.Cdo,t.offset-4,t.offset);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 64:if(l(t.getRelativeCode(1),t.getRelativeCode(2),t.getRelativeCode(3))){const o=t.offset;t.consumeCodePoint(),P(t),t.onToken(e.TokenType.AtKeyword,o,t.offset);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 92:if(k(t.code,t.getRelativeCode(1))){S(t);break}t.consumeTrivialToken(e.TokenType.Delim),t.onError("Invalid escape sequence.",t.offset-1,t.offset);break;case 47:if(42===t.getRelativeCode(1)){const o=t.offset;t.consumeCodePoint(2),t.consumeUntilCommentEnd(),t.isEof()&&t.onError("Unterminated comment.",o,t.length-2),t.onToken(e.TokenType.Comment,o,t.offset);break}t.consumeTrivialToken(e.TokenType.Delim);break;default:if(a(t.code)){S(t);break}t.consumeTrivialToken(e.TokenType.Delim)}},F=o=>{const n=o.offset;if(o.consumeWhitespace(),39===o.code||34===o.code)return void(o.offset>n&&o.onToken(e.TokenType.Whitespace,n,o.offset));let t=1;for(let t=n;t<o.offset;t+=1)o.onToken(e.TokenType.Delim,t,t+1);for(;!o.isEof();){if(40===o.code&&92!==o.prevCode)t+=1;else if(41===o.code&&92!==o.prevCode&&(t-=1,0===t))break;o.consumeTrivialToken(e.TokenType.Delim)}};function O(e,o){const n=new Map;for(const[o,t]of e)n.set(o,t);for(const[e,t]of o)n.set(e,t);return n}const H=new Map([[1989084725,F],[2399470598,F],[1221663855,F],[102304302,F],[2923888231,F],[1739713050,F],[196571984,o=>{const n=o.offset;if(o.consumeWhitespace(),39===o.code||34===o.code)return void(o.offset>n&&o.onToken(e.TokenType.Whitespace,n,o.offset));let t=1;for(let t=n;t<o.offset;t+=1)o.onToken(e.TokenType.Delim,t,t+1);let i=!1;for(;!o.isEof();){if(34===o.code&&92!==o.prevCode&&(i=!i),!i)if(40===o.code&&92!==o.prevCode)t+=1;else if(41===o.code&&92!==o.prevCode&&(t-=1,0===t))break;o.consumeTrivialToken(e.TokenType.Delim)}}]]);return e.TOKEN_NAMES=v,e.TokenizerContext=C,e.getBaseTokenName=y,e.getFormattedTokenName=e=>`<${y(e)}-token>`,e.tokenize=D,e.tokenizeExtended=function(e,o){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:()=>{},t=arguments.length>3&&void 0!==arguments[3]?arguments[3]:new Map;D(e,o,n,t.size>0?O(H,t):H)},e.version="0.0.1",e}({});
function _defineProperty(e,o,n){return(o=_toPropertyKey(o))in e?Object.defineProperty(e,o,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[o]=n,e}function _toPropertyKey(e){var o=_toPrimitive(e,"string");return"symbol"==typeof o?o:o+""}function _toPrimitive(e,o){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var t=n.call(e,o||"default");if("object"!=typeof t)return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===o?String:Number)(e)}var CSSTokenizer=function(e){"use strict";function o(e,o,n){return e>=o&&e<=n}function n(e,o){return e>o}function t(e,o){return e>=o}function r(e){return o(e,48,57)}function i(e){return r(e)||o(e,65,70)||o(e,97,102)}function s(e){return o(e,65,90)}function c(e){return o(e,97,122)}function d(e){return s(e)||c(e)}function a(e){return t(e,128)}function f(e){return d(e)||a(e)||95===e}function T(e){return f(e)||r(e)||45===e}function u(e){return 10===e||13===e||12===e}function l(e){return u(e)||9===e||32===e}function k(e){return o(e,55296,56319)}function p(e){return o(e,56320,57343)}function m(e){return n(e,1114111)}const C=(e,o)=>92===e&&!u(o),h=(e,o,n)=>45===e?f(o)||45===o||C(o,n):!!f(e)||92===e&&C(e,o),v=(e,o,n)=>43===e||45===e?!!r(o)||46===o&&r(n):r(46===e?o:e);function y(e,o,n){let t=5381;for(let r=o;r<n;r+=1)t=33*t^(32|e[r]);return t>>>0}class g{constructor(e,o,n,t){var r;if(_defineProperty(this,"length",void 0),_defineProperty(this,"onToken",void 0),_defineProperty(this,"onError",void 0),_defineProperty(this,"codes",void 0),_defineProperty(this,"cursor",void 0),_defineProperty(this,"customFunctionHandlers",void 0),this.length=e.length,this.preprocess(e),this.cursor=65279===(r=this.codes[0])||65534===r?1:0,this.onToken=o,this.onError=n,t){this.customFunctionHandlers=new Map;for(const[e,o]of t)this.customFunctionHandlers.set(e,o)}}preprocess(e){const o=e.length;this.codes=new Int32Array(o+1);for(let n=0;n<o;n+=1)this.codes[n]=e.charCodeAt(n);this.codes[o]=-1}getFunctionHandler(e){var o;return null===(o=this.customFunctionHandlers)||void 0===o?void 0:o.get(e)}hasFunctionHandler(e){var o;return(null===(o=this.customFunctionHandlers)||void 0===o?void 0:o.has(e))??!1}get offset(){return this.cursor}get code(){return this.codes[this.offset]}get prevCode(){return this.codes[this.offset-1]}get nextCode(){return this.codes[this.offset+1]}getRelativeCode(e){return this.codes[this.offset+e]}isEof(){return this.offset>=this.length}isNextEof(){return this.cursor+1===this.length}isLessThanEqualToEof(){return this.offset<=this.length}consumeCodePoint(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this.cursor+=e}getNextNonWsCode(){let e=this.cursor;for(;e<this.length&&l(this.codes[e]);)e+=1;return this.codes[e]}consumeWhitespace(){for(;this.code&&l(this.code);)this.consumeCodePoint()}consumeSingleWhitespace(){l(this.code)&&(this.cursor+=13===this.code&&10===this.nextCode?2:1)}consumeUntilCommentEnd(){for(;this.cursor<this.length;){if(42===this.code&&47===this.nextCode){this.cursor+=2;break}this.cursor+=1}}consumeTrivialToken(e){this.onToken(e,this.cursor,++this.cursor)}getHashFrom(e){return y(this.codes,e,this.cursor)}}var P;e.TokenType=void 0,(P=e.TokenType||(e.TokenType={}))[P.Eof=0]="Eof",P[P.Ident=1]="Ident",P[P.Function=2]="Function",P[P.AtKeyword=3]="AtKeyword",P[P.Hash=4]="Hash",P[P.String=5]="String",P[P.BadString=6]="BadString",P[P.Url=7]="Url",P[P.BadUrl=8]="BadUrl",P[P.Delim=9]="Delim",P[P.Number=10]="Number",P[P.Percentage=11]="Percentage",P[P.Dimension=12]="Dimension",P[P.Whitespace=13]="Whitespace",P[P.Cdo=14]="Cdo",P[P.Cdc=15]="Cdc",P[P.Colon=16]="Colon",P[P.Semicolon=17]="Semicolon",P[P.Comma=18]="Comma",P[P.OpenSquareBracket=19]="OpenSquareBracket",P[P.CloseSquareBracket=20]="CloseSquareBracket",P[P.OpenParenthesis=21]="OpenParenthesis",P[P.CloseParenthesis=22]="CloseParenthesis",P[P.OpenCurlyBracket=23]="OpenCurlyBracket",P[P.CloseCurlyBracket=24]="CloseCurlyBracket",P[P.Comment=25]="Comment";const b=Object.freeze({[e.TokenType.Eof]:"eof",[e.TokenType.Ident]:"ident",[e.TokenType.Function]:"function",[e.TokenType.AtKeyword]:"at-keyword",[e.TokenType.Hash]:"hash",[e.TokenType.String]:"string",[e.TokenType.BadString]:"bad-string",[e.TokenType.Url]:"url",[e.TokenType.BadUrl]:"bad-url",[e.TokenType.Delim]:"delim",[e.TokenType.Number]:"number",[e.TokenType.Percentage]:"percentage",[e.TokenType.Dimension]:"dimension",[e.TokenType.Whitespace]:"whitespace",[e.TokenType.Cdo]:"CDO",[e.TokenType.Cdc]:"CDC",[e.TokenType.Colon]:"colon",[e.TokenType.Semicolon]:"semicolon",[e.TokenType.Comma]:"comma",[e.TokenType.OpenSquareBracket]:"[",[e.TokenType.CloseSquareBracket]:"]",[e.TokenType.OpenParenthesis]:"(",[e.TokenType.CloseParenthesis]:")",[e.TokenType.OpenCurlyBracket]:"{",[e.TokenType.CloseCurlyBracket]:"}",[e.TokenType.Comment]:"comment"}),E=e=>b[e]??"unknown",S=e=>{if(e.consumeCodePoint(),i(e.code)){let o=0;for(;i(e.code)&&o<=6;)e.consumeCodePoint(),o+=1;e.consumeSingleWhitespace()}e.isEof()&&e.onError("Unexpected end of file while parsing escaped code point.",e.offset,e.offset)},R=e=>{for(;!e.isEof();)if(T(e.code))e.consumeCodePoint();else{if(!C(e.code,e.nextCode))return;e.consumeCodePoint(),S(e)}};function x(e){for(;!e.isEof();e.consumeCodePoint()){if(41===e.code)return void e.consumeCodePoint();C(e.getRelativeCode(1),e.getRelativeCode(2))&&(e.consumeCodePoint(),S(e))}}function U(o,n){x(o),o.onToken(e.TokenType.BadUrl,n,o.offset)}const w=(n,t)=>{for(;l(n.code);)n.consumeCodePoint();for(;n.offset<=n.length;){if(41===n.code)return n.consumeCodePoint(),void n.onToken(e.TokenType.Url,t,n.offset);if(n.isEof())return n.onToken(e.TokenType.Url,t,n.offset),void n.onError("Unexpected end of file while parsing URL.",t,n.offset);if(l(n.code)){for(;l(n.code);)n.consumeCodePoint();return 41===n.code||n.isEof()?(n.consumeCodePoint(),n.onToken(e.TokenType.Url,t,n.offset),void n.onError("Unexpected end of file while parsing URL.",t,n.offset)):(n.onError("Unexpected character in URL.",t,n.offset),void U(n,t))}if(34===n.code||39===n.code||40===n.code||(o(r=n.code,0,8)||11===r||o(r,14,31)||127===r))return n.onError("Unexpected character in URL.",t,n.offset),void U(n,t);if(92===n.code){if(C(n.code,n.nextCode)){n.consumeCodePoint(),S(n);continue}return n.onError("Unexpected character in URL.",t,n.offset),void U(n,t)}n.consumeCodePoint()}var r},B=o=>{const n=o.offset;if(R(o),40===o.code){const t=o.getHashFrom(n);if(o.consumeCodePoint(),193422222===t){const t=o.getNextNonWsCode();return 34===t||39===t?void o.onToken(e.TokenType.Function,n,o.offset):void w(o,n)}return o.hasFunctionHandler(t)?(o.onToken(e.TokenType.Function,n,o.offset),void o.getFunctionHandler(t)(o)):void o.onToken(e.TokenType.Function,n,o.offset)}o.onToken(e.TokenType.Ident,n,o.offset)},D=e=>{for(43!==e.code&&45!==e.code||e.consumeCodePoint();r(e.code);)e.consumeCodePoint();if(46===e.code&&r(e.nextCode))for(e.consumeCodePoint(2);r(e.code);)e.consumeCodePoint();if(69===e.code||101===e.code)if(45!==e.nextCode&&43!==e.nextCode||!r(e.getRelativeCode(2))){if(r(e.nextCode))for(e.consumeCodePoint(2);r(e.code);)e.consumeCodePoint()}else for(e.consumeCodePoint(3);r(e.code);)e.consumeCodePoint()},F=o=>{const n=o.offset;return D(o),h(o.code,o.nextCode,o.getRelativeCode(2))?(R(o),void o.onToken(e.TokenType.Dimension,n,o.offset)):37===o.code?(o.consumeCodePoint(),void o.onToken(e.TokenType.Percentage,n,o.offset)):void o.onToken(e.TokenType.Number,n,o.offset)},O=o=>{const n=o.code,t=o.offset;for(o.consumeCodePoint();o.isLessThanEqualToEof();)switch(o.code){case n:return o.consumeCodePoint(),void o.onToken(e.TokenType.String,t,o.offset);case-1:return o.onToken(e.TokenType.String,t,o.offset),void o.onError("Unexpected end of file while parsing string token.",t,o.offset);case 13:case 10:case 12:return 13===o.code&&10===o.nextCode&&o.consumeCodePoint(1),o.consumeCodePoint(1),o.onToken(e.TokenType.BadString,t,o.offset),void o.onError("Unexpected newline while parsing string token.",t,o.offset);case 92:if(o.isNextEof())return o.consumeCodePoint(),o.onToken(e.TokenType.String,t,o.offset),void o.onError("Unexpected end of file while parsing string token.",t,o.offset);if(u(o.nextCode)){o.consumeCodePoint(2);break}C(o.code,o.nextCode)&&(o.consumeCodePoint(),S(o));break;default:o.consumeCodePoint()}},H=o=>{const n=o.offset;o.consumeWhitespace(),o.onToken(e.TokenType.Whitespace,n,o.offset)},N=function(o,n){const t=new g(o,n,arguments.length>2&&void 0!==arguments[2]?arguments[2]:()=>{},arguments.length>3?arguments[3]:void 0);for(;!t.isEof();)switch(t.code){case 9:case 32:case 10:case 12:case 13:H(t);break;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:F(t);break;case 40:t.consumeTrivialToken(e.TokenType.OpenParenthesis);break;case 41:t.consumeTrivialToken(e.TokenType.CloseParenthesis);break;case 44:t.consumeTrivialToken(e.TokenType.Comma);break;case 58:t.consumeTrivialToken(e.TokenType.Colon);break;case 59:t.consumeTrivialToken(e.TokenType.Semicolon);break;case 91:t.consumeTrivialToken(e.TokenType.OpenSquareBracket);break;case 93:t.consumeTrivialToken(e.TokenType.CloseSquareBracket);break;case 123:t.consumeTrivialToken(e.TokenType.OpenCurlyBracket);break;case 125:t.consumeTrivialToken(e.TokenType.CloseCurlyBracket);break;case 39:case 34:O(t);break;case 35:if(T(t.getRelativeCode(1))||C(t.getRelativeCode(1),t.getRelativeCode(2))){const o=t.offset;t.consumeCodePoint(),R(t),t.onToken(e.TokenType.Hash,o,t.offset);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 43:case 46:if(v(t.code,t.getRelativeCode(1),t.getRelativeCode(2))){F(t);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 45:if(v(t.code,t.getRelativeCode(1),t.getRelativeCode(2))){F(t);break}if(45===t.getRelativeCode(1)&&62===t.getRelativeCode(2)){t.consumeCodePoint(3),t.onToken(e.TokenType.Cdc,t.offset-3,t.offset);break}if(h(t.code,t.getRelativeCode(1),t.getRelativeCode(2))){B(t);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 60:if(33===t.getRelativeCode(1)&&45===t.getRelativeCode(2)&&45===t.getRelativeCode(3)){t.consumeCodePoint(4),t.onToken(e.TokenType.Cdo,t.offset-4,t.offset);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 64:if(h(t.getRelativeCode(1),t.getRelativeCode(2),t.getRelativeCode(3))){const o=t.offset;t.consumeCodePoint(),R(t),t.onToken(e.TokenType.AtKeyword,o,t.offset);break}t.consumeTrivialToken(e.TokenType.Delim);break;case 92:if(C(t.code,t.getRelativeCode(1))){B(t);break}t.consumeTrivialToken(e.TokenType.Delim),t.onError("Invalid escape sequence.",t.offset-1,t.offset);break;case 47:if(42===t.getRelativeCode(1)){const o=t.offset;t.consumeCodePoint(2),t.consumeUntilCommentEnd(),t.isEof()&&t.onError("Unterminated comment.",o,t.length-2),t.onToken(e.TokenType.Comment,o,t.offset);break}t.consumeTrivialToken(e.TokenType.Delim);break;default:if(f(t.code)){B(t);break}t.consumeTrivialToken(e.TokenType.Delim)}},W=o=>{const n=o.offset;if(o.consumeWhitespace(),39===o.code||34===o.code)return void(o.offset>n&&o.onToken(e.TokenType.Whitespace,n,o.offset));let t=1;for(let t=n;t<o.offset;t+=1)o.onToken(e.TokenType.Delim,t,t+1);for(;!o.isEof();){if(40===o.code&&92!==o.prevCode)t+=1;else if(41===o.code&&92!==o.prevCode&&(t-=1,0===t))break;o.consumeTrivialToken(e.TokenType.Delim)}};function _(e,o){const n=new Map;for(const[o,t]of e)n.set(o,t);for(const[e,t]of o)n.set(e,t);return n}const q=new Map([[1989084725,W],[2399470598,W],[1221663855,W],[102304302,W],[2923888231,W],[1739713050,W],[1860790666,W],[3376104318,W],[196571984,o=>{const n=o.offset;if(o.consumeWhitespace(),39===o.code||34===o.code)return void(o.offset>n&&o.onToken(e.TokenType.Whitespace,n,o.offset));let t=1;for(let t=n;t<o.offset;t+=1)o.onToken(e.TokenType.Delim,t,t+1);let r=!1;for(;!o.isEof();){if(34===o.code&&92!==o.prevCode&&(r=!r),!r)if(40===o.code&&92!==o.prevCode)t+=1;else if(41===o.code&&92!==o.prevCode&&(t-=1,0===t))break;o.consumeTrivialToken(e.TokenType.Delim)}}]]);return e.CSS_TOKENIZER_VERSION="1.0.0-alpha.0",e.TokenizerContext=g,e.decodeIdent=e=>{const o=[];for(let t=0;t<e.length;t+=1){if(92===e.charCodeAt(t)){if(i(e.charCodeAt(t+1))){let r=0,s=0;for(;s<6&&i(e.charCodeAt(t+s+1));)r=16*r+parseInt(e[t+s+1],16),s+=1;o.push(String.fromCodePoint(0===r||(k(n=r)||p(n))||m(r)?65533:r)),t+=s;const c=e.charCodeAt(t+1);l(c)&&(t+=1,13===c&&10===e.charCodeAt(t+1)&&(t+=1))}}else o.push(e[t])}var n;return o.join("")},e.getBaseTokenName=E,e.getFormattedTokenName=e=>`<${E(e)}-token>`,e.tokenize=N,e.tokenizeExtended=function(e,o){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:()=>{},t=arguments.length>3&&void 0!==arguments[3]?arguments[3]:new Map;N(e,o,n,t.size>0?_(q,t):q)},e}({});
{
"name": "@adguard/css-tokenizer",
"version": "0.0.1",
"version": "1.0.0-alpha.0",
"description": "CSS / Extended CSS tokenizer",

@@ -9,3 +9,3 @@ "keywords": [

],
"author": "AdGuard Software Ltd.",
"author": "Adguard Software Ltd.",
"license": "MIT",

@@ -22,22 +22,18 @@ "repository": {

"main": "dist/csstokenizer.js",
"browser": "dist/csstokenizer.iife.min.js",
"module": "dist/csstokenizer.esm.mjs",
"browser": "dist/csstokenizer.umd.min.js",
"types": "dist/csstokenizer.d.ts",
"exports": {
".": {
"types": "./dist/csstokenizer.d.ts",
"import": "./dist/csstokenizer.esm.mjs",
"require": "./dist/csstokenizer.js"
},
"./es": "./dist/csstokenizer.esm.mjs",
"./iife": "./dist/csstokenizer.iife.min.js",
"./umd": "./dist/csstokenizer.umd.min.js"
},
"files": [
"dist"
],
"scripts": {
"build": "yarn clean && yarn build-types && yarn build-txt && yarn rollup --config rollup.config.ts --configPlugin @rollup/plugin-json --configPlugin @rollup/plugin-typescript && yarn clean-types",
"build-txt": "yarn ts-node scripts/build-txt.ts",
"build-types": "tsc --declaration --emitDeclarationOnly --outdir dist/types",
"benchmark": "yarn build && node -r esbuild-register benchmark/index.ts",
"check-types": "tsc --noEmit",
"clean": "rimraf dist",
"clean-types": "rimraf dist/types",
"coverage": "jest --coverage",
"increment": "yarn version --patch --no-git-tag-version",
"lint": "yarn lint:ts && yarn lint:md",
"lint:md": "markdownlint .",
"lint:ts": "eslint . --cache --ext .ts",
"test": "jest --runInBand"
},
"devDependencies": {

@@ -84,2 +80,3 @@ "@babel/core": "^7.22.8",

"parse-css": "^0.1.0",
"rimraf": "^5.0.5",
"rollup": "^3.29.4",

@@ -93,3 +90,17 @@ "rollup-plugin-dts": "^6.0.2",

},
"dependencies": {}
}
"scripts": {
"build": "pnpm clean && pnpm build-types && pnpm build-txt && pnpm rollup --config rollup.config.ts --configPlugin @rollup/plugin-json --configPlugin @rollup/plugin-typescript && pnpm clean-types",
"build-txt": "pnpm ts-node scripts/build-txt.ts",
"build-types": "tsc --declaration --emitDeclarationOnly --outdir dist/types",
"benchmark": "pnpm build && node -r esbuild-register benchmark/index.ts",
"check-types": "tsc --noEmit",
"clean": "rimraf dist",
"clean-types": "rimraf dist/types",
"coverage": "jest --coverage",
"increment": "pnpm version patch --no-git-tag-version",
"lint": "pnpm lint:ts && pnpm lint:md",
"lint:md": "markdownlint .",
"lint:ts": "eslint . --cache --ext .ts",
"test": "jest --runInBand"
}
}

@@ -23,2 +23,13 @@ <!-- omit in toc -->

- [API](#api)
- [Tokenizer functions](#tokenizer-functions)
- [`tokenize`](#tokenize)
- [`tokenizeExtended`](#tokenizeextended)
- [Utilities](#utilities)
- [`TokenizerContext`](#tokenizercontext)
- [`decodeIdent`](#decodeident)
- [`CSS_TOKENIZER_VERSION`](#css_tokenizer_version)
- [Token types](#token-types)
- [`TokenType`](#tokentype)
- [`getBaseTokenName`](#getbasetokenname)
- [`getFormattedTokenName`](#getformattedtokenname)
- [Benchmark results](#benchmark-results)

@@ -48,5 +59,5 @@ - [Ideas \& Questions](#ideas--questions)

<!--markdownlint-disable MD013-->
- <img src="https://cdn.adguard.com/website/github.com/AGLint/adg_logo.svg" width="14px"> [AdGuard: *Extended CSS capabilities*][adg-ext-css]
- <img src="https://cdn.adguard.com/website/github.com/AGLint/ubo_logo.svg" width="14px"> [uBlock Origin: *Procedural cosmetic filters*][ubo-procedural]
- <img src="https://cdn.adguard.com/website/github.com/AGLint/abp_logo.svg" width="14px"> [Adblock Plus: *Extended CSS selectors*][abp-ext-css]
- <img src="https://cdn.adguard.com/website/github.com/AGLint/adg_logo.svg" alt="AdGuard logo" width="14px"> [AdGuard: *Extended CSS capabilities*][adg-ext-css]
- <img src="https://cdn.adguard.com/website/github.com/AGLint/ubo_logo.svg" alt="uBlock Origin logo" width="14px"> [uBlock Origin: *Procedural cosmetic filters*][ubo-procedural]
- <img src="https://cdn.adguard.com/website/github.com/AGLint/abp_logo.svg" alt="Adblock Plus logo" width="14px"> [Adblock Plus: *Extended CSS selectors*][abp-ext-css]
<!--markdownlint-enable MD013-->

@@ -139,21 +150,169 @@

Tokenization is accomplished by calling the tokenize or tokenizeExtended function. Both functions accept the following
arguments:
### Tokenizer functions
- `source`: The CSS source string to tokenize.
- `onToken`: A callback function invoked for each token found in the source string, with the following arguments:
<!-- TODO: Add link -->
- `token`: The token type (you can see token types here).
- `start`: The starting index of the token in the source string.
- `end`: The ending index of the token in the source string.
- `onError`: A callback function called when an error occurs during tokenization. Errors do not break the tokenization
process, as the tokenizer is tolerant and attempts to recover from errors in line with the CSS Syntax Level 3
specification. The callback function accepts the following arguments:
- `message`: The error message.
- `start`: The starting index of the error in the source string.
- `end`: The ending index of the error in the source string.
- `functionHandlers`: This allows for the customized handling of functions. Map keys correspond to function names,
while the values are void callback functions serving as "tokenizer context" functions. These functions can be used to
manage pseudo-classes and have only one argument: the shared tokenizer context object.
#### `tokenize`
```ts
/**
* CSS tokenizer function
*
* @param source Source code to tokenize
* @param onToken Tokenizer callback which is called for each token found in source code
* @param onError Error callback which is called when a parsing error is found (optional)
* @param functionHandlers Custom function handlers (optional)
*/
function tokenize(
source: string,
onToken: OnTokenCallback,
onError: OnErrorCallback = () => {},
functionHandlers?: Map<number, TokenizerContextFunction>,
): void;
```
where
```ts
/**
* Callback which is called when a token is found
*
* @param type Token type
* @param start Token start offset
* @param end Token end offset
* @param props Other token properties (if any)
* @note Hash tokens have a type flag set to either "id" or "unrestricted". The type flag defaults to "unrestricted" if
* not otherwise set
*/
type OnTokenCallback = (type: TokenType, start: number, end: number, props?: Record<string, unknown>) => void;
```
```ts
/**
* Callback which is called when a parsing error is found. According to the spec, parsing errors are not fatal and
* therefore the tokenizer is quite permissive, but if needed, the error callback can be used.
*
* @param message Error message
* @param start Error start offset
* @param end Error end offset
* @see {@link https://www.w3.org/TR/css-syntax-3/#error-handling}
*/
type OnErrorCallback = (message: string, start: number, end: number) => void;
```
```ts
/**
* Function handler
*
* @param context Reference to the tokenizer context instance
* @param ...args Additional arguments (if any)
*/
type TokenizerContextFunction = (context: TokenizerContext, ...args: any[]) => void;
```
#### `tokenizeExtended`
`tokenizeExtended` is an extended version of the `tokenize` function that supports custom function handlers. This
function is designed to handle special pseudo-classes like `:contains()` and `:xpath()`.
```ts
/**
* Extended CSS tokenizer function
*
* @param source Source code to tokenize
* @param onToken Tokenizer callback which is called for each token found in source code
* @param onError Error callback which is called when a parsing error is found (optional)
* @param functionHandlers Custom function handlers (optional)
* @note If you specify custom function handlers, they will be merged with the default function handlers. If you
* duplicate a function handler, the custom one will be used instead of the default one, so you can override the default
* function handlers this way, if you want to.
*/
function tokenizeExtended(
source: string,
onToken: OnTokenCallback,
onError: OnErrorCallback = () => {},
functionHandlers: Map<number, TokenizerContextFunction> = new Map(),
): void
```
### Utilities
#### `TokenizerContext`
A class that represents the tokenizer context. It is used to manage the tokenizer state and provides access to the
source code, current position, and other relevant information.
#### `decodeIdent`
```ts
/**
* Decodes a CSS identifier according to the CSS Syntax Module Level 3 specification.
*
* @param ident CSS identifier to decode.
*
* @example
* ```ts
* decodeIdent(String.raw`\00075\00072\0006C`); // 'url'
* decodeIdent('url'); // 'url'
* ```
*
* @returns Decoded CSS identifier.
*/
function decodeIdent(ident: string): string;
```
### `CSS_TOKENIZER_VERSION`
```ts
/**
* @adguard/css-tokenizer version
*/
const CSS_TOKENIZER_VERSION: string;
```
### Token types
#### `TokenType`
An enumeration of token types recognized by the tokenizer.
They are strictly based on the CSS Syntax Level 3 specification.
See https://www.w3.org/TR/css-syntax-3/#tokenization for more details.
#### `getBaseTokenName`
```ts
/**
* Get base token name by token type
*
* @param type Token type
*
* @example
* ```ts
* getBaseTokenName(TokenType.Ident); // 'ident'
* getBaseTokenName(-1); // 'unknown'
* ```
*
* @returns Base token name or 'unknown' if token type is unknown
*/
function getBaseTokenName(type: TokenType): string;
```
#### `getFormattedTokenName`
```ts
/**
* Get formatted token name by token type
*
* @param type Token type
*
* @example
* ```ts
* getFormattedTokenName(TokenType.Ident); // '<ident-token>'
* getFormattedTokenName(-1); // '<unknown-token>'
* ```
*
* @returns Formatted token name or `'<unknown-token>'` if token type is unknown
*/
function getFormattedTokenName(type: TokenType): string;
```
> [!NOTE]

@@ -193,5 +352,5 @@ > Our API and token list is also compatible with the [CSSTree][css-tree-repo]'s tokenizer API, and in the long term, we

[npm-url]: https://www.npmjs.com/package/@adguard/css-tokenizer
[pnpm-pkg-manager-url]: https://pnpm.js.org/
[pnpm-pkg-manager-url]: https://pnpm.io/
[ubo-procedural]: https://github.com/gorhill/uBlock/wiki/Procedural-cosmetic-filters
[xpath-mdn]: https://developer.mozilla.org/en-US/docs/Web/XPath
[yarn-pkg-manager-url]: https://yarnpkg.com/en/docs/install

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc