Ecsstree
Adblock Extended CSS supplement for CSSTree
Install / Use
npx skills add AdguardTeam/ecsstreeInstalls into whichever agent you are using.
README
ECSSTree
<!--markdownlint-disable MD013--> <!--markdownlint-enable MD013-->Adblock Extended CSS supplement for CSSTree. Our primary goal is to change the internal behavior of the CSSTree parser to support Extended CSS (ECSS) language elements, but we don't change the API or the AST structure. Therefore ECSSTree fully backwards compatible with CSSTree, so you can pass our AST to CSSTree functions and vice versa without any problems.
Note: This package is developed in AdGuardSoftwareLimited/ext-ecsstree. The AdguardTeam/ecsstree repository is a public mirror.
[!NOTE] If you are looking for a library that can parse CSS, but you don't know what is Adblock or Extended CSS, you should probably use CSSTree instead of this library :)
Table of contents
- Table of contents
- Installation
- Supported Extended CSS elements
- Motivation
- Handle problematic cases
- Examples
- Reporting problems / Requesting features
- License
- Acknowledgements
- References
Installation
You can install the library using
- PNPM:
pnpm add @adguard/ecss-tree - NPM:
npm install @adguard/ecss-tree - Yarn:
yarn add @adguard/ecss-tree
Or you can use it via esm.run: https://esm.run/@adguard/ecss-tree
Supported Extended CSS elements
Currently, the following Extended CSS pseudo classes are supported:
:-abp-contains(raw): [ABP reference]:-abp-has(selector list): [ABP reference]:contains(raw): [ADG reference]:has-text(raw): [uBO reference]:if-not(selector): [ADG reference]:matches-css-after(raw): [uBO reference]:matches-css-before(raw): [uBO reference]:matches-css(raw): [ADG reference], [uBO reference]:matches-media(media query list): [uBO reference]:min-text-length(number): [uBO reference]:nth-ancestor(number): [ADG reference]:style(declaration list): [uBO reference]:upward(selector list / number): [ADG reference], [uBO reference]:xpath(raw): [ADG reference], [uBO reference]
In addition, CSSTree supports the following pseudo classes by default:
:has(selector list): [W3C reference], [ADG reference], [uBO reference]:not(selector list): [W3C reference], [ADG reference], [uBO reference]:is(selector list): [W3C reference], [ADG reference], [uBO reference]
Also, CSSTree supports legacy Extended CSS elements by default (attribute selectors):
[-ext-name="value"], where name is the name of the Extended CSS element and value is its value.
For example, the following selector can be parsed by CSSTree:
[-ext-has="selector list"]
If a pseudo class is unknown to CSSTree, it tries to parse it as a Raw element
(if possible - see problematic cases).
The CSSTree library itself is quite flexible and error-tolerant, so it basically manages well the Extended CSS elements that are not (yet) included here.
Motivation
For example, the following selector
div:-abp-has(> section)
will be parsed by the default CSSTree as follows
{
"type": "Selector",
"loc": null,
"children": [
{
"type": "PseudoClassSelector",
"loc": null,
"name": "-abp-has",
"children": [
{
"type": "Raw",
"loc": null,
"value": "> section"
}
]
}
]
}
The problem with this is that the -abp-has parameter is parsed as Raw, not as a Selector,
since -abp-has is an unknown pseudo class in CSS / CSSTree.
This is where the ECSSTree library comes into play. It detects that -abp-has expects a selector as a parameter,
i.e. it parses the passed parameter as a Selector. This means that the selector above will be parsed as follows:
{
"type": "Selector",
"loc": null,
"children": [
{
"type": "PseudoClassSelector",
"loc": null,
"name": "-abp-has",
"children": [
{
"type": "Selector",
"loc": null,
"children": [
{
"type": "Combinator",
"loc": null,
"name": ">"
},
{
"type": "TypeSelector",
"loc": null,
"name": "section"
}
]
}
]
}
]
}
Combinator and similar Nodes are part of CSSTree, this fork simply specifies that the -abp-has parameter
should be parsed as a selector. The nodes themselves are part of the CSSTree.
Advanced validation
In addition, this approach enables a more advanced validation. For example, the default CSSTree does not throw an error when parsing the following selector:
div:-abp-has(42)
since it doesn't know what -abp-has is, it simply parses 42 as Raw. ECSSTree parses the parameter as a selector,
which will throw an error, since 42 is simply an invalid selector.
Handle problematic cases
The library also handles problematic selectors, such as the following:
div:contains(aaa'bbb)
This selector doesn't fully meet with CSS standards, so even if CSSTree is flexible, it will not be able to parse it properly, because it will tokenize it as follows:
| Token type | Start index | End index | Source part | | -------------- | ----------- | --------- | ----------- | | ident-token | 0 | 3 | div | | colon-token | 3 | 4 | : | | function-token | 4 | 13 | contains( | | ident-token | 13 | 16 | aaa | | string-token | 16 | 21 | 'bbb
Related Skills
node-connect
385.5kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
blender-python-addon
40.5kBlender Python add-on rules for operators, panels, properties, registration, testing, and API-safe scripting
flutter-development-guidelines-cursorrules-prompt-file
40.5kCursor rules for Flutter development with MVVM architecture, Riverpod state management, Material widgets, and Dart style guidelines.
commit-push-pr
140.6kCommit, push, and open a PR
