CSS / 扩展 CSS 调试器
这个库提供了两种不同的 CSS 符号化器:
- 标准CSS 切换器: 此标识符严格遵循 CSS 语法 3 规格, 由 : W3C 战车。 。 。 .
- 扩展 CSS 调试器: 设计以扩展标准示标器的能力,此组件引入
支持特殊伪类,例如
:contains()财务报告和审定财务报表:xpath()。 。 。 .
目录 :
安装
您可以使用
- 雅伦 (建议):
yarn add @adguard/css-tokenizer - 国家预防机制数字 :
npm install @adguard/css-tokenizer - 菲律宾数字 :
pnpm add @adguard/css-tokenizer
动机
为了理解定制标志剂的必要性,必须理解扩展CSS的概念,认识到 并发现我们如何能够有效地解决这些问题.
什么是扩展CSS?
扩展CSS(英語:Extended CSS)是被阻塞器用来提供更强大的过滤能力的一款CSS的超级集. 实际上, 扩展CSS引入了CSS规格中没有定义的额外伪类. 有关更多信息, 请参考以下资源:
为什么我们需要定制的装饰剂?
标准的 CSS 指示器无法处理扩展 CSS 的伪类 在所有情况下。例如 :contains()
伪类可以有下列语法:
div:contains(i'm a parameter)
标准 CSS 标注器解释单引号(')作为字符串分隔符,由于
缺乏结束 ) 字符键。 这种偏离预期的语法导致解析问题.
这个 :xpath() 伪类对标准的 CSS 代号器构成类似的挑战,因为它可以有这样的语法:
div:xpath(//*...)
标准标识符错误地识别 /* 序列作为注释的起始,导致不正确的解析,
不过 /* 顺序是 XPath 表达式。 。 。 .
解决方案: 自定义函数处理器
我们设计了标准的 CSS 指示器 来严格遵循 CSS 语法三级规格. 然而,我们
还引入了以自定义方式处理某些伪类的能力,类似于 <url-token> 实值
cSS 规格管理。 当标识器遇到函数符( 模式 : function-name(,它搜索一个
操作器函数在 functionHandlers 基于函数名的映射,如果自定义处理器存在,则使用它.
自定义处理器收到一个单一的参数: 共享指示器上下文对象,可用于管理 函数,类似于库中处理其他符号的方式.
这种方法使我们能够保持一个符合规格的本地CSS标识器,其管理费用最低,同时 以自定义的方式提供管理特殊伪类的灵活性.
从本质上讲,扩展 CSS 代码化器是标准 CSS 代码化器,具有特殊功能处理器 伪等相.
没有新的符号类型
必须强调,我们的执行仍然致力于CSS W3C规定的象征性类型 标准。 我们不推出新的标志类型,确保我们的标致器与官方CSS保持和谐 语法三级规格. 我们致力于遵守行业标准和最佳做法,这保证了我们 库与CSS相关的工具和工作流程保持相容性和一致性.
通过保留标准CSS标志类型,我们的目标是为用户提供可靠而无缝的经验,同时 与CSS合作,维护W3C定义的语言完整性.
示例用途
以下是一个如何使用图书馆的简单例子:
// `tokenize` is a regular CSS tokenizer (and doesn't support Extended CSS)
// `tokenizeExtended` is an Extended CSS tokenizer
const { tokenize, tokenizeExtended, getFormattedTokenName } = require('@adguard/css-tokenizer');
// Input to tokenize
const CSS_SOURCE = `div:contains(aa'bb) { display: none !important; }`;
const COLUMNS = Object.freeze({
TOKEN: 'Token',
START: 'Start',
END: 'End',
FRAGMENT: 'Fragment'
});
// Prepare the data array
const data = [];
// Tokenize the input - feel free to try `tokenize` and `tokenizeExtended`
tokenizeExtended(CSS_SOURCE, (token, start, end) => {
data.push({
[COLUMNS.TOKEN]: getFormattedTokenName(token),
[COLUMNS.START]: start,
[COLUMNS.END]: end,
[COLUMNS.FRAGMENT]: CSS_SOURCE.substring(start, end),
});
});
// Print the tokenization result as a table
console.table(data, Object.values(COLUMNS));
API 密码
切换器函数
tokenize
/**
* 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;
地点
/**
* 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)
* @param stop Function to halt the tokenization process
* @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> | undefined,
stop: () => void
);
/**
* 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;
/**
* 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 是扩展版本 tokenize 函数,用于支持自定义函数处理器。 这个
函数用于处理特殊伪类,如 :contains() 财务报告和审定财务报表 :xpath()。 。 。 .
/**
* 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
公用事业
hasToken
/**
* Checks if the given raw string contains any of the specified tokens.
*
* @param raw - The raw string to be tokenized and checked.
* @param tokens - A set of token types to check for in the raw string.
* @param tokenizer - The tokenizer function to use. Defaults to `tokenizeExtended`.
*
* @example hasToken('div:contains("foo")', new Set([TokenType.Function]), tokenizeExtended); // true
*
* @returns `true` if any of the specified tokens are found in the raw string, otherwise `false`.
*/
function hasToken = (
raw: string,
tokens: Set<TokenType>,
tokenizer: TokenizerFunction = tokenizeExtended,
): boolean
TokenizerContext
代表标致上下文的类 。 用于管理标致器状态,并提供访问 源代码,当前位置等相关信息.
decodeIdent
/**
* 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
/**
* @adguard/css-tokenizer version
*/
const CSS_TOKENIZER_VERSION: string;
托肯类型
TokenType
描述器确认的标志类型. 它们严格基于CSS语法三级规格.
见 https://www.w3.org/TR/css-syntax-3/#tokenization (中文(简体) ) 更多细节.
getBaseTokenName
/**
* 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
/**
* 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;
[注] 我们的API和令牌列表也符合 CSSTree (英语)从长远来看,我们 计划通过我们把这个图书馆并入CSSTree ECSSTree 图书馆,参见 这个问题 更多细节.
基准结果
您可以在 基准/成果 文档.
想法和问题
如果您有任何问题或想法 新的功能,请 打开一个问题 或一个 讨论情况我们很乐意跟你讨论.
许可证
这个项目根据麻省理工学院的许可证获得许可。 见 自由主义 详细文件.