### Install Project Dependencies Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Install all project dependencies using pnpm. All dependencies are devDependencies. ```bash pnpm install ``` -------------------------------- ### ExtendedCss Configuration Examples Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/types.md Demonstrates how to initialize ExtendedCss using different configuration options. Examples include using a full stylesheet, an array of individual CSS rules, and enabling the debug mode with a pre-apply callback. ```typescript // Using stylesheet new ExtendedCss({ styleSheet: ` div.banner { display: none !important; } p:contains(ad) { visibility: hidden !important; } ` }); ``` ```typescript // Using individual rules new ExtendedCss({ cssRules: [ 'div.popup:remove()', '#ad-container { display: none; }', ] }); ``` ```typescript // With callback and debug new ExtendedCss({ styleSheet: 'div.ad { display: none; }', beforeStyleApplied: (el) => { console.log('Applying to:', el.node); return el; }, debug: true, }); ``` -------------------------------- ### Install Playwright Browser Binaries Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Run this command if tests fail with 'Cannot find module "playwright"' to install necessary browser binaries. ```bash pnpm exec playwright install chromium ``` -------------------------------- ### Install ExtendedCSS Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/README.md Install the ExtendedCSS package using npm. This is the first step before using the library. ```bash npm install @adguard/extended-css ``` -------------------------------- ### Configure BrowserStack Environment Variables Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Copy the example environment file and fill in your BrowserStack credentials if needed for testing. ```bash cp .env-example .env ``` ```text BROWSERSTACK_USER= BROWSERSTACK_KEY= ``` -------------------------------- ### Example HTML for :matches-css() Backward Compatibility Source: https://github.com/adguardteam/extendedcss/blob/master/README.md This HTML includes a style for `#matched::before` which is targeted by the `[-ext-matches-css-before]` selector. ```html
``` -------------------------------- ### Apply and Dispose Stylesheet Example Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Demonstrates how to create an ExtendedCss instance, apply a stylesheet, and then dispose of it after a delay. This is useful for dynamically managing styles. ```js (function() { let styleSheet = 'div.wrapper > div:has(.banner) { display:none!important; }\n'; styleSheet += 'div.wrapper > div:contains(ads) { background:none!important; }'; const extendedCss = new ExtendedCss({ styleSheet }); // apply styleSheet extendedCss.apply(); // stop applying of this styleSheet setTimeout(function() { extendedCss.dispose(); }, 10 * 1000); })(); ``` -------------------------------- ### Example Usage of CssStyleMap Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/types.md Illustrates how to declare and initialize a CssStyleMap object with common CSS properties. ```typescript const styles: CssStyleMap = { 'display': 'none', 'visibility': 'hidden', 'background': 'transparent', }; ``` -------------------------------- ### HTML Structure for :empty-trimmed Examples Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Presents the HTML DOM structure used to illustrate the behavior of the :empty-trimmed and :not(:empty-trimmed) pseudo-classes. ```html

 

hello

world

``` -------------------------------- ### TimingStats Usage Example Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/HelperFunctions.md Demonstrates how to instantiate and use the TimingStats class to track selector application counts and performance metrics. Ensure the class is imported before use. ```typescript import { TimingStats } from '@adguard/extended-css'; const stats = new TimingStats(); stats.push(1.5); stats.push(2.3); stats.push(1.8); console.log(`Applied ${stats.appliesCount} times`); console.log(`Mean: ${stats.meanTiming}ms`); console.log(`Std Dev: ${stats.standardDeviation}`); ``` -------------------------------- ### Example: Selecting elements within a container Source: https://github.com/adguardteam/extendedcss/blob/master/README.md This example demonstrates how to select elements with the class 'inner' or 'footer' that are descendants of an element with the ID 'container'. It highlights the usage of :is() with compound selectors. ```html
``` -------------------------------- ### HTML Structure for :not() Example Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Provides the HTML structure used to demonstrate the :not() pseudo-class selecting a specific element. ```html

Header

text
``` -------------------------------- ### Example HTML for :has() Backward Compatibility Source: https://github.com/adguardteam/extendedcss/blob/master/README.md This HTML demonstrates how the `[-ext-has=".banner"]` attribute selects a div containing an element with the class 'banner'. ```html
Not selected
Selected
``` -------------------------------- ### Example Usage of StyleDeclaration Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/types.md Demonstrates how to create a StyleDeclaration object for a CSS property with the '!important' flag set. ```typescript const declaration: StyleDeclaration = { property: 'display', value: 'none', important: true }; ``` -------------------------------- ### Example: Workaround for :is() limitations with complex selectors Source: https://github.com/adguardteam/extendedcss/blob/master/README.md This example shows a workaround for limitations when using complex selectors within :is(). It demonstrates how to use :has() as an alternative to achieve a similar selection goal, targeting an element with the class 'banner' inside a specific div. ```html text
``` -------------------------------- ### Markdown Table Formatting Example Source: https://github.com/adguardteam/extendedcss/blob/master/AGENTS.md Illustrates the correct padding and alignment for Markdown tables within the 80-character line limit. Ensure columns are aligned with single spaces. ```markdown | Col1 | Col2 | | --- | --- | | Value1 | Value2 | ``` -------------------------------- ### Accessing Timing Stats for Debugging Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/types.md Example demonstrating how to enable debug mode and access performance timing statistics for applied CSS rules. Timing stats are populated when debug mode is enabled. ```typescript const extendedCss = new ExtendedCss({ styleSheet: 'div.ad { display: none; debug: true; }' }); extendedCss.apply(); // Access timing data via affected elements const affected = extendedCss.getAffectedElements(); affected.forEach(el => { el.rules.forEach(rule => { if (rule.timingStats) { console.log('Timing stats for', rule.selector, ':', rule.timingStats); } }); }); ``` -------------------------------- ### Example HTML for :contains() Backward Compatibility Source: https://github.com/adguardteam/extendedcss/blob/master/README.md This HTML shows how `[-ext-contains="banner"]` selects a div containing the text 'banner'. ```html
Not selected
Selected as it contains "banner"
``` -------------------------------- ### Extended CSS Pseudo-Classes Examples Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/README.md Examples of Extended CSS pseudo-classes for selecting elements based on various criteria like text content, computed styles, attributes, DOM properties, XPath, and ancestry. ```css p:contains(ad) ``` ```css div:matches-css(display: block) ``` ```css div:matches-attr("data-*") ``` ```css div:matches-property(isAd) ``` ```css :xpath(//*[@id="ad"]) ``` ```css span:nth-ancestor(2) ``` ```css span:upward(div[id]) ``` ```css div:has(.banner) ``` ```css div:is(.ad, .popup) ``` ```css div:not(.safe) ``` ```css p:empty-trimmed ``` ```css div.popup:remove() ``` -------------------------------- ### Querying Elements with ExtendedCss Source: https://github.com/adguardteam/extendedcss/blob/master/README.md An example demonstrating how to use the ExtendedCss.query() method to find elements matching a complex CSS selector that includes pseudo-classes like :has() and :matches-css(). ```js const selector = 'div.block:has(.header:matches-css(after, content: Ads))'; // array of HTMLElements matched the `selector` is to be returned ExtendedCss.query(selector); ``` -------------------------------- ### ExtendedCss Constructor Examples Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/ExtendedCss.md Demonstrates how to initialize the ExtendedCss class using different configuration options. Use 'styleSheet' for a single CSS string or 'cssRules' for an array of rules. The 'beforeStyleApplied' callback can be used to track or modify elements before styles are applied. ```typescript import ExtendedCss from '@adguard/extended-css'; // Using stylesheet const extendedCss = new ExtendedCss({ styleSheet: 'div.banner { display: none !important; }', }); ``` ```typescript import ExtendedCss from '@adguard/extended-css'; // Using individual CSS rules const extendedCss2 = new ExtendedCss({ cssRules: [ 'div:has(.ad) { display: none !important; }', 'p:contains(advertisement) { visibility: hidden !important; }', ], }); ``` ```typescript import ExtendedCss from '@adguard/extended-css'; // With callback for tracking affected elements const extendedCss3 = new ExtendedCss({ styleSheet: '#popup:remove()', beforeStyleApplied: (element) => { console.log('Applied style to element:', element.node); return element; }, }); ``` -------------------------------- ### Get Timing Information for Queries Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/README.md Use `ExtendedCss.query` to execute selectors and observe console logs for execution time. This helps in performance analysis. ```typescript const elements = ExtendedCss.query('complex:selector', false); // Logs execution time to console ``` -------------------------------- ### Log ExtendedCss Version Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/README.md Import and log the current version of the ExtendedCss library. Ensure the library is installed to access the EXTENDED_CSS_VERSION constant. ```typescript import { EXTENDED_CSS_VERSION } from '@adguard/extended-css'; console.log(`ExtendedCss v${EXTENDED_CSS_VERSION}`); ``` -------------------------------- ### Remove Elements Using :remove() Pseudo-Class Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/extended-pseudo-classes.md Example of the older :remove() pseudo-class syntax for removing elements. Note that this syntax has limitations and the pseudo-property is recommended. ```css div.popup:remove() ``` -------------------------------- ### Verify Node.js and pnpm Versions Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Check if your installed Node.js and pnpm versions meet the project's requirements. Node.js must be version 22 or higher, and pnpm must be between 10.33.4 and 11. ```bash node --version # must be 22 or higher pnpm --version # must be >=10.33.4 and <11 ``` -------------------------------- ### CSS :has() Pseudo-Class Examples Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/extended-pseudo-classes.md Demonstrates various ways to use the :has() pseudo-class in CSS to select elements based on their descendants or siblings. Includes descendant, child, and sibling selectors. ```css /* Any element containing .banner */ div:has(.banner) /* Direct child */ div:has(> .banner) /* Following sibling */ div:has(+ .banner) /* Selector list - all must match */ div:has(span, img) ``` -------------------------------- ### CSS :is() Pseudo-Class Examples Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/extended-pseudo-classes.md Illustrates the use of the :is() pseudo-class in CSS for matching elements against a list of selectors. Supports standard and extended compound selectors. ```css /* Standard selectors */ div:is(.ad, .banner, .popup) /* With target */ .container:is(.sidebar, .main) /* Extended selectors (compound only) */ div:is(:contains(ad), [data-ad]) ``` -------------------------------- ### ExtCssDocument Cache Strategy Example Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/QueryFunctions.md Demonstrates the caching mechanism of extCssDocument.getSelectorAst. The first call parses the selector and caches the result, while subsequent calls retrieve the cached Abstract Syntax Tree (AST) significantly faster. This cache is instance-specific and managed automatically. ```typescript import { extCssDocument } from '@adguard/extended-css'; // First call: parses and caches const start1 = performance.now(); const ast1 = extCssDocument.getSelectorAst('div:has(.item)'); const time1 = performance.now() - start1; // Second call: returns cached AST (much faster) const start2 = performance.now(); const ast2 = extCssDocument.getSelectorAst('div:has(.item)'); const time2 = performance.now() - start2; console.log(`Parse: ${time1}ms, Cache: ${time2}ms`); // Cache is typically 10-100x faster // Same object reference console.log(ast1 === ast2); // true ``` -------------------------------- ### CSS :not() Pseudo-Class Examples Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/extended-pseudo-classes.md Shows how to use the :not() pseudo-class in CSS to exclude elements that match a given list of selectors. Supports exclusion by class, attribute, and extended selectors. ```css /* Exclude classes */ div:not(.ad) div:not(.ad, .banner) /* Exclude attributes */ div:not([data-hidden]) /* Exclude extended selectors */ div:not(:contains(advertisement)) ``` -------------------------------- ### Select parent element using XPath with :xpath() Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Demonstrates selecting an element by targeting its parent using an XPath expression within the :xpath() pseudo-class. This example shows how to navigate the DOM tree using XPath. ```html
``` -------------------------------- ### Select nth ancestor using :nth-ancestor() Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Illustrates the usage of the :nth-ancestor() pseudo-class to select an element based on its position relative to a previously selected element. This example shows how to find specific ancestors in the DOM tree. ```html
``` -------------------------------- ### Internal Capture of Native textContent Getter Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/HelperFunctions.md An internal example showing how the native textContent getter is captured using setGetter(). This ensures that the :contains() pseudo-class works even if textContent is later mocked. ```typescript // This is handled internally by ExtendedCss.init() import { nativeTextContent } from '@adguard/extended-css'; nativeTextContent.setGetter(); // Capture native getter // Now safe to use :contains() even if textContent is mocked ``` -------------------------------- ### Build and Inspect Project Output Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Builds the project and lists the contents of the dist/ directory, which includes various bundle formats and type declarations. ```bash pnpm build ls dist/ ``` -------------------------------- ### Build All Output Formats Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Build all output formats for the project, generating bundles in the dist/ directory. ```bash pnpm build ``` -------------------------------- ### Run Full Verification Suite Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Execute linting, building, and local tests as part of the contribution workflow. ```bash pnpm lint pnpm build pnpm test local ``` -------------------------------- ### Element properties for :matches-property() example Source: https://github.com/adguardteam/extendedcss/blob/master/README.md An example JavaScript object representing properties of a div element. This is used to demonstrate how the :matches-property() pseudo-class can select elements based on their properties. ```javascript divProperties = { id: 1, check: { track: true, unit_2random1: true, }, memoizedProps: { key: null, tag: 12, _owner: { effectTag: 1, src: 'ad.com', }, }, }; ``` -------------------------------- ### Recommended ExtendedCss Initialization Order Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/configuration.md Demonstrates the recommended sequence for initializing ExtendedCss, including configuration, early initialization, applying styles on DOM readiness, and cleanup. ```typescript const extendedCss = new ExtendedCss({ styleSheet: '...', debug: false, beforeStyleApplied: callback, }); // Initialize as early as possible extendedCss.init(); // Apply when page is ready document.addEventListener('DOMContentLoaded', () => { extendedCss.apply(); }); // Cleanup when needed window.addEventListener('beforeunload', () => { extendedCss.dispose(); }); ``` -------------------------------- ### Basic ExtendedCSS Usage Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/README.md Demonstrates the basic workflow of creating an ExtendedCss instance, initializing it, applying styles, and disposing of the instance. Import the library and create an instance with your stylesheet. ```typescript import ExtendedCss from '@adguard/extended-css'; // Create instance with stylesheet const extendedCss = new ExtendedCss({ styleSheet: ` div.ad { display: none !important; } p:contains(sponsored) { visibility: hidden; } div:has(.banner):remove() ` }); // Initialize (call early) extendedCss.init(); // Apply styles extendedCss.apply(); // Later, stop applying extendedCss.dispose(); ``` -------------------------------- ### Run All Tests Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Execute both local and BrowserStack tests. ```bash pnpm test ``` -------------------------------- ### Get ExtendedCss Version Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/ExtendedCss.md Retrieves the version number of the ExtendedCss library. This is useful for logging or compatibility checks. ```typescript import { EXTENDED_CSS_VERSION } from '@adguard/extended-css'; console.log(`Using ExtendedCss v${EXTENDED_CSS_VERSION}`); // Output: Using ExtendedCss v2.2.0 ``` -------------------------------- ### Importing and Using ExtCssDocument Singleton Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/ExtCssDocument.md Demonstrates how to import the exported extCssDocument singleton or use the static ExtendedCss.query() method for querying elements. This is the typical way users interact with the query engine. ```typescript import { extCssDocument } from '@adguard/extended-css'; // Or use the static query method: import ExtendedCss from '@adguard/extended-css'; const elements = ExtendedCss.query('div.banner'); ``` -------------------------------- ### Run Performance Tests Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Execute performance benchmarks for ExtendedCss, comparing v1 and v2. ```bash pnpm test performance ``` -------------------------------- ### Get the first element of an array Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/HelperFunctions.md Retrieve the first element from an array using the getFirst function. This function is available after importing from '@adguard/extended-css'. ```typescript import { getFirst } from '@adguard/extended-css'; const items = [1, 2, 3]; const first = getFirst(items); // 1 ``` -------------------------------- ### Get Affected Elements by ExtendedCss Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/ExtendedCss.md Returns an array of all elements that have been affected by applied CSS rules. Primarily exposed for testing purposes. ```typescript const extendedCss = new ExtendedCss({ styleSheet: 'div.ad { display: none; }' }); extendedCss.apply(); const affected = extendedCss.getAffectedElements(); console.log(`${affected.length} elements were affected`); affected.forEach((el) => { console.log('Node:', el.node); console.log('Rules applied:', el.rules.length); }); ``` -------------------------------- ### Layered Architecture Overview Source: https://github.com/adguardteam/extendedcss/blob/master/AGENTS.md Illustrates the layered structure of the project, showing the flow of control from entry points down to utilities. ```text Entry Points (src/index.ts, src/index.default.ts) ↓ Orchestration (src/extended-css/ — ExtendedCss class, DOM helpers) ↓ Parsing (src/stylesheet/, src/css-rule/, src/style-block/, src/selector/) ↓ Tokenization (src/common/tokenizer.ts, src/selector/tokenizer.ts, src/style-block/tokenizer.ts) ↓ Utilities & Constants (src/common/constants.ts, src/common/utils/) ``` -------------------------------- ### Extended CSS Initialization Sequence Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/README.md Provides the recommended order for initializing and applying Extended CSS rules. This includes creating an instance, calling init(), applying rules on DOMContentLoaded, and disposing to clean up resources. ```typescript const extendedCss = new ExtendedCss({ styleSheet: '...' }); extendedCss.init(); document.addEventListener('DOMContentLoaded', () => { extendedCss.apply(); }); ``` -------------------------------- ### Validate Selector Example Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/types.md Demonstrates how to use ExtendedCss.validate() to check the validity of CSS selectors. Shows expected output for both valid and invalid selectors. ```typescript const valid = ExtendedCss.validate('div.banner'); // { ok: true, error: null } const invalid = ExtendedCss.validate('div[incomplete'); // { ok: false, error: "Error: Invalid selector: 'div[incomplete' -- ..." } ``` -------------------------------- ### Initialize Extended CSS and Capture Native textContent Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/HelperFunctions.md Demonstrates the usage pattern for initializing Extended CSS and capturing the native textContent getter. Call init() as early as possible in your application lifecycle. ```typescript import ExtendedCss from '@adguard/extended-css'; // Call init() as early as possible const extendedCss = new ExtendedCss({ ... }); extendedCss.init(); // Captures native textContent extendedCss.apply(); ``` -------------------------------- ### Public method init() Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Initializes ExtendedCss on a page. This method should be executed as early as possible to ensure correct functionality of the ':contains()' pseudo-class. ```APIDOC ## init() ### Description Initializes ExtendedCss on a page. It should be executed on page as soon as possible, even before the ExtendedCss instance is constructed, otherwise the ":contains()" pseudo-class may work incorrectly. ### Method `init()` ### Parameters None ### Request Example ```javascript ExtendedCss.init(); ``` ### Response None (initializes the library) ``` -------------------------------- ### Get Error Message Safely Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/HelperFunctions.md Safely extracts an error message from any thrown value. This utility provides a fallback to the string representation if a message is unavailable. ```typescript import { getErrorMessage } from '@adguard/extended-css'; try { // Some operation } catch (e) { const message = getErrorMessage(e); console.error('Error:', message); } ``` -------------------------------- ### Run BrowserStack Tests Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Run tests on BrowserStack. Requires BrowserStack credentials to be set in the .env file. ```bash pnpm test browserstack ``` -------------------------------- ### Select by matching element properties with :matches-property() Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Demonstrates various ways to use the :matches-property() pseudo-class to select elements based on their properties, including simple property checks, wildcard matching, and regular expressions for property names and values. ```css div:matches-property(check.track) ``` ```css div:matches-property("check./^unit_.{4,8}$") ``` ```css div:matches-property("check.unit_*"=true) ``` ```css div:matches-property(memoizedProps.key="null") ``` ```css div:matches-property(memoizedProps._owner.src=/ad/) ``` -------------------------------- ### Public methods apply() and dispose() Source: https://github.com/adguardteam/extendedcss/blob/master/README.md The `apply()` method applies the configured styles on the page, while the `dispose()` method stops the application and restores the original styles. ```APIDOC ## apply() and dispose() ### Description After the instance of ExtendedCss is created, it can be applied on the page by the `apply()` method. Its applying also can be stopped and styles are to be restored by the `dispose()` method. ### Methods * `apply()` * `dispose()` ### Parameters None for both methods. ### Request Example ```javascript // Assuming 'extendedCss' is an instance of ExtendedCss // Apply styles extendedCss.apply(); // To stop applying and restore styles after some time setTimeout(function() { extendedCss.dispose(); }, 10000); ``` ### Response None (modifies the page's applied styles) ``` -------------------------------- ### Extended CSS Performance Monitoring Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/configuration.md Enable performance monitoring by setting `debug: true` in your styles and initializing Extended CSS with `init()`. Timing statistics for rule application will be available for analysis. ```typescript const extendedCss = new ExtendedCss({ styleSheet: ` div.ad { display: none; debug: true; } p:contains(sponsored) { color: gray; debug: true; } `, beforeStyleApplied: (el) => { // Timing data is available in el.rules[].timingStats return el; } }); extendedCss.init(); extendedCss.apply(); // Check the browser console for timing statistics ``` -------------------------------- ### Backward Compatible Syntax for :matches-css() Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Use `[-ext-matches-css-before]` with string or regex patterns to match CSS properties for pseudo-elements like `::before`. ```css ! string pattern div[-ext-matches-css-before="content: block me"] ``` ```css ! regular expression pattern div[-ext-matches-css-before="content: /block me/"] ``` -------------------------------- ### Demonstrate AST Caching Performance Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/ExtCssDocument.md Compares the time taken to parse a selector the first time versus subsequent calls, demonstrating the performance benefit of the AST cache. Ensure the necessary imports are included. ```typescript import { extCssDocument, selectElementsByAst } from '@adguard/extended-css'; // First call parses and caches let start = performance.now(); const ast1 = extCssDocument.getSelectorAst('div:has(.ad):contains(/banner/)'); let time1 = performance.now() - start; // Second call returns cached AST (faster) start = performance.now(); const ast2 = extCssDocument.getSelectorAst('div:has(.ad):contains(/banner/)'); let time2 = performance.now() - start; console.log(`First parse: ${time1}ms, Cached: ${time2}ms`); // Cached query is significantly faster ``` -------------------------------- ### Recommended ExtendedCss Query API Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/ExtCssDocument.md The recommended approach for querying elements using the Extended CSS library. For advanced use cases, you can access the internal document to get an AST. ```typescript import ExtendedCss from '@adguard/extended-css'; // Recommended approach const elements = ExtendedCss.query('div.container:has(> .ad)'); // For advanced use cases, access the internal document: import { extCssDocument } from '@adguard/extended-css'; const ast = extCssDocument.getSelectorAst('complex:selector'); ``` -------------------------------- ### Configure with StyleSheet Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/configuration.md Use the `styleSheet` option to provide a complete CSS stylesheet as a single string. This is suitable for large, static stylesheets. Ensure rules are properly formatted and separated by closing braces. ```typescript new ExtendedCss({ styleSheet: ` div.banner { display: none !important; } div.popup:remove() p:contains(advertisement) { visibility: hidden !important; } div:has(img.ad) { height: 0 !important; overflow: hidden; } ` }); ``` -------------------------------- ### ThrottleWrapper Usage Example (Internal) Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/HelperFunctions.md Illustrates the internal use of ThrottleWrapper to prevent ExtendedCss from re-applying rules too frequently during multiple DOM mutations. The callback is scheduled and executed only once after a series of calls to throttle(). ```typescript // Used internally by ExtendedCss import { ThrottleWrapper } from '@adguard/extended-css'; const wrapper = new ThrottleWrapper(() => { applyRules(); }); // Multiple mutations trigger only one callback wrapper.throttle(); wrapper.throttle(); wrapper.throttle(); // Callback runs once (throttled) ``` -------------------------------- ### Initialize ExtendedCss with Configuration Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/errors.md Ensure a configuration object is provided to the ExtendedCss constructor. The configuration must include either 'styleSheet' or 'cssRules'. ```typescript const extendedCss = new ExtendedCss(); ``` ```typescript const extendedCss = new ExtendedCss({ styleSheet: 'div.ad { display: none; }' }); ``` -------------------------------- ### Query Elements Using :empty-trimmed Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/extended-pseudo-classes.md Demonstrates how to query elements using the :empty-trimmed pseudo-class in TypeScript. This allows for dynamic selection of elements based on their content. ```typescript const empty = ExtendedCss.query('p:empty-trimmed'); const nonEmpty = ExtendedCss.query('div:not(:empty-trimmed)'); ``` -------------------------------- ### Backward Compatible :matches-css() Syntax Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/extended-pseudo-classes.md Use this older syntax for :matches-css(), :matches-css-before(), and :matches-css-after() if backward compatibility is required. ```css target[-ext-matches-css="property: pattern"] ``` ```css target[-ext-matches-css-before="property: pattern"] ``` ```css target[-ext-matches-css-after="property: pattern"] ``` -------------------------------- ### Complex Matching with Extended CSS Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/README.md Combines multiple Extended CSS pseudo-classes and selectors for sophisticated element matching. This example targets elements that are ads, displayed as block, and contain specific text. ```typescript const ads = ExtendedCss.query(` div:is(.ad, .banner, .sponsored):matches-css(display: block):contains(/advertisement/) `); ``` -------------------------------- ### Add Content with Pseudo-elements in AdGuard Extended CSS Source: https://github.com/adguardteam/extendedcss/blob/master/test/test-files/performance.html Utilize pseudo-elements like '::before' in AdGuard Extended CSS to inject content. This example adds the text 'test' before elements matching the '.case6-marker' selector. ```css .case6-marker::before { content: "test" } ``` -------------------------------- ### Run Linting and Type Checking Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Execute ESLint for code linting and TypeScript for type checking. ```bash pnpm lint ``` -------------------------------- ### Using Public API of Extended CSS Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/HelperFunctions.md Demonstrates the recommended way to use the Extended CSS library for querying elements and validating selectors. Use the public API for most common scenarios. ```typescript import ExtendedCss from '@adguard/extended-css'; // ✅ Use public API const elements = ExtendedCss.query('div.banner'); const result = ExtendedCss.validate('selector'); ``` -------------------------------- ### Select element using XPath expression with :xpath() Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Example of using the :xpath() pseudo-class to select an HTML element based on a provided XPath expression. This is useful for selecting elements that are difficult to target with standard CSS selectors. ```html ``` -------------------------------- ### Block Elements with AdGuard Extended CSS Source: https://github.com/adguardteam/extendedcss/blob/master/test/test-files/performance.html Use AdGuard Extended CSS to block specific page elements by targeting their selectors. This example shows how to block elements with IDs 'case3-blocked' and 'case5' and apply a transparent background using a data URI. ```css #case3-blocked { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); } ``` ```css #case5 .target-banner { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); } ``` -------------------------------- ### createRawResultsMap() Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/ParsingFunctions.md Creates an empty map for storing raw parsing results. ```APIDOC ## createRawResultsMap() ### Description Creates an empty map for storing raw parsing results. ### Method Not applicable (TypeScript function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Returns Empty `RawResults` map (`Map`). ### Example ```typescript import { createRawResultsMap } from '@adguard/extended-css'; const results = createRawResultsMap(); // Now use results to store parsed rules ``` ``` -------------------------------- ### Configure with beforeStyleApplied Callback Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/configuration.md Implement the `beforeStyleApplied` callback to execute custom logic before styles are applied to matched elements. This callback receives element and rule information and must return the element object. ```typescript new ExtendedCss({ styleSheet: 'div.ad { display: none; }', beforeStyleApplied: (element) => { // Track matched elements const selector = element.rules[0]?.selector || 'unknown'; console.log(`Matched ${element.node.tagName}#${element.node.id} with rule: ${selector}`); // Optionally modify the element data // element.rules can be modified before application return element; } }); ``` -------------------------------- ### Project File Structure Overview Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/INDEX.md This snippet displays the directory structure and the main files within the AdGuard Team Extended CSS project. It helps understand the organization and scope of different documentation and code modules. ```text /output/ ├── README.md (405 lines) - Main overview ├── INDEX.md (this file) - Navigation ├── types.md (413 lines) - Type reference ├── configuration.md (383 lines) - Configuration guide ├── extended-pseudo-classes.md (650 lines) - Pseudo-class reference ├── errors.md (570 lines) - Error catalog └── api-reference/ ├── ExtendedCss.md (277 lines) - Main class ├── ExtCssDocument.md (237 lines) - Query engine ├── ParsingFunctions.md (435 lines) - Parser API ├── QueryFunctions.md (451 lines) - Query API └── HelperFunctions.md (600 lines) - Utilities Total: 10 files, 4,421 lines ``` -------------------------------- ### Run Local Tests Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Execute local tests using Vitest, including jsdom unit tests and browser mode tests. ```bash pnpm test local ``` -------------------------------- ### Query Functions Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/MANIFEST.txt Documentation for functions related to querying elements, including static methods and instance methods. ```APIDOC ## Query Functions ### Description Provides functions for querying elements within the document using ExtendedCss selectors. ### Functions - **ExtendedCss.query(selector, element)**: Static method to perform a query. - **ExtendedCss.validate(cssString)**: Static method to validate CSS. - **ExtCssDocument.querySelectorAll(selector)**: Instance method to find elements. - **selectElementsByAst(ast, element)**: Function to select elements based on an AST. ### Cache Strategy and Performance Information on how caching affects query performance. ``` -------------------------------- ### ExtCssDocument Class Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/MANIFEST.txt Documentation for the ExtCssDocument class, which handles the query engine. It includes methods for querying elements and retrieving the Abstract Syntax Tree (AST) of selectors. ```APIDOC ## ExtCssDocument Class ### Description Manages the query engine for ExtendedCss. This class provides methods to interact with the document's selectors and their underlying Abstract Syntax Tree (AST). ### Methods - **querySelectorAll(selector)**: Finds all elements matching the given selector. - **getSelectorAst(selector)**: Retrieves the Abstract Syntax Tree for a given selector. ### Cache Strategy Details on the caching mechanisms used for performance optimization. ``` -------------------------------- ### Manually Clean Build Output Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md If stale files are present after a build, manually clean the dist/ directory before rebuilding. ```bash rm -rf dist pnpm build ``` -------------------------------- ### ExtCssDocument Cache Strategy Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/QueryFunctions.md Demonstrates the caching mechanism for `extCssDocument.getSelectorAst`. The first call parses the selector and caches the result, while subsequent calls retrieve the cached Abstract Syntax Tree (AST) significantly faster. The cache is instance-specific and managed automatically. ```APIDOC ## ExtCssDocument Cache Strategy ### Description This section illustrates the query result caching behavior of `extCssDocument.getSelectorAst`. The first invocation parses a given CSS selector and stores its Abstract Syntax Tree (AST) in a cache. Subsequent calls with the same selector retrieve the AST directly from the cache, offering a substantial performance improvement. The cache is tied to the instance of `extCssDocument` and benefits from automatic garbage collection when the instance is no longer in use, eliminating the need for manual cache management. ### Usage ```typescript import { extCssDocument } from '@adguard/extended-css'; // First call: parses and caches the AST const start1 = performance.now(); const ast1 = extCssDocument.getSelectorAst('div:has(.item)'); const time1 = performance.now() - start1; // Second call: retrieves the cached AST (significantly faster) const start2 = performance.now(); const ast2 = extCssDocument.getSelectorAst('div:has(.item)'); const time2 = performance.now() - start2; console.log(`Parse: ${time1}ms, Cache: ${time2}ms`); // Expected output: Cache is typically 10-100x faster // Verifies that both calls return the same object reference console.log(ast1 === ast2); // true ``` ### Cache Benefits - Reduces parsing overhead for repeated selectors. - Cache is instance-specific, not global. - Automatic garbage collection is handled with the instance. - No manual cache management is required. ``` -------------------------------- ### ExtendedCss Constructor Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Creates an instance of ExtendedCss. Requires a configuration object that can include a stylesheet, CSS rules, a callback for style application, and a debug flag. ```APIDOC ## Constructor ### Description Creates an instance of ExtendedCss. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **configuration** (ExtCssConfiguration) - Required - Configuration object for ExtendedCss. ### Request Example ```javascript const config = { styleSheet: 'div.example { color: red; }', beforeStyleApplied: (element) => { console.log('Applying style to:', element); return element; }, debug: true }; const extendedCss = new ExtendedCss(config); ``` ### Response #### Success Response (Instance) An instance of ExtendedCss. #### Response Example ```javascript // Instance of ExtendedCss ``` ### ExtCssConfiguration Interface ```ts interface ExtCssConfiguration { // css stylesheet — css rules combined in one string styleSheet?: string; // css rules — array of separated css rules cssRules?: string; // the callback that handles affected elements beforeStyleApplied?: BeforeStyleAppliedCallback; // flag for applied selectors logging; equals to `debug: global` in `styleSheet` debug?: boolean; } ``` ### BeforeStyleAppliedCallback Type ```ts type BeforeStyleAppliedCallback = (x: IAffectedElement) => IAffectedElement; ``` ### IAffectedElement Interface ```ts interface IAffectedElement { rules: { style: { content?: string }} node: HTMLElement; } ``` ``` -------------------------------- ### Querying with :matches-css() in TypeScript Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/extended-pseudo-classes.md Demonstrates querying elements based on their computed CSS styles using the :matches-css() pseudo-class in TypeScript. ```typescript const blocks = ExtendedCss.query('div:matches-css(display: none)'); const images = ExtendedCss.query('img:matches-css(opacity: 0)'); const dataUrls = ExtendedCss.query('div:matches-css(background-image: url(data:*))'); ``` -------------------------------- ### ExtendedCss Constructor Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/ExtendedCss.md Initializes a new instance of the ExtendedCss class. It requires a configuration object that can include a stylesheet string, an array of CSS rules, or both. Optionally, a callback function can be provided to track elements before styles are applied. ```APIDOC ## ExtendedCss Constructor ### Description Creates a new instance of ExtendedCss. ### Method Constructor ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **configuration** (`ExtCssConfiguration`) - Required - Configuration object for ExtendedCss initialization. Must contain either `styleSheet` or `cssRules`. Can also include an optional `beforeStyleApplied` callback function. ### Throws - Error if `configuration` is not provided. - Error if neither `styleSheet` nor `cssRules` is defined in configuration. - Error if `styleSheet` contains invalid selector syntax (stylesheet parsing fails). - Error if `beforeStyleApplied` callback is not a function when provided. ### Example ```typescript import ExtendedCss from '@adguard/extended-css'; // Using stylesheet const extendedCss = new ExtendedCss({ styleSheet: 'div.banner { display: none !important; }', }); // Using individual CSS rules const extendedCss2 = new ExtendedCss({ cssRules: [ 'div:has(.ad) { display: none !important; }', 'p:contains(advertisement) { visibility: hidden !important; }', ], }); // With callback for tracking affected elements const extendedCss3 = new ExtendedCss({ styleSheet: '#popup:remove()', beforeStyleApplied: (element) => { console.log('Applied style to element:', element.node); return element; }, }); ``` ``` -------------------------------- ### TimingStats Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/HelperFunctions.md Accumulates timing statistics for selector execution, allowing for performance analysis of CSS rule applications. ```APIDOC ## TimingStats ### Description Accumulates timing statistics for selector execution. This class helps in analyzing the performance of CSS rule applications by tracking timings, counts, and statistical measures. ### Methods - `push(timing: number)`: Adds a new timing value in milliseconds to the statistics. - `appliesCount`: Returns the total count of times a selector has been applied. - `timingsSum`: Returns the sum of all recorded timing values. - `meanTiming`: Calculates and returns the average timing per application. - `standardDeviation`: Calculates and returns the statistical standard deviation of the timings. ### Example ```typescript import { TimingStats } from '@adguard/extended-css'; const stats = new TimingStats(); stats.push(1.5); stats.push(2.3); stats.push(1.8); console.log(`Applied ${stats.appliesCount} times`); console.log(`Mean: ${stats.meanTiming}ms`); console.log(`Std Dev: ${stats.standardDeviation}`); ``` ``` -------------------------------- ### Clone ExtendedCss Repository Source: https://github.com/adguardteam/extendedcss/blob/master/DEVELOPMENT.md Clone the ExtendedCss repository and navigate into the project directory. ```bash git clone https://github.com/AdguardTeam/ExtendedCss.git cd ExtendedCss ``` -------------------------------- ### Enable and Interpret Timing Information Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/api-reference/QueryFunctions.md Enable timing logs for debugging query performance by passing 'false' as the second argument to the query function. Observe the elapsed time in microseconds. ```typescript import ExtendedCss from '@adguard/extended-css'; // Enable timing logs for debugging const slow = ExtendedCss.query('div:matches-property(complexProp.nested.chain)', false); // Output: [ExtendedCss] Elapsed: 2500 μs. const fast = ExtendedCss.query('div.simple', false); // Output: [ExtendedCss] Elapsed: 50 μs. ``` -------------------------------- ### Extended CSS for Styling Elements Source: https://github.com/adguardteam/extendedcss/blob/master/test/browserstack/browserstack.html Shows how to apply styles to elements based on their CSS properties or pseudo-element content using Extended CSS. Useful for testing specific styling conditions. ```css #case6-blocked { opacity:0.9 } ``` ```css #case7-blocked::before { content: "sponsored" } ``` -------------------------------- ### ExtendedCss Class Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/MANIFEST.txt Documentation for the main ExtendedCss class, including its constructor, initialization, application, and disposal methods, as well as static query and validate methods. ```APIDOC ## ExtendedCss Class ### Description Provides the main interface for ExtendedCss functionality. Users can initialize, apply styles, and dispose of the instance. It also offers static methods for querying and validation. ### Constructor Initializes a new instance of ExtendedCss. ### Methods - **init()**: Initializes the ExtendedCss instance. - **apply()**: Applies the ExtendedCss styles. - **dispose()**: Cleans up and disposes of the ExtendedCss instance. ### Static Methods - **query(selector, element)**: Performs a query using ExtendedCss. - **validate(cssString)**: Validates a CSS string. ### Property Documentation Details on properties available for the ExtendedCss class. ``` -------------------------------- ### Public static method query() Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Returns a list of the document's elements that match the specified selector. It can optionally skip timing console logs. ```APIDOC ## query(selector, noTiming) ### Description Returns a list of the document's elements that match the specified selector. Throws an error if the argument is not a valid selector. ### Method `static query(selector: string, noTiming?: boolean): HTMLElement[]` ### Parameters #### Path Parameters None #### Query Parameters * **selector** (string) - Required - The CSS selector to query. * **noTiming** (boolean) - Optional - If true, do not print the timing to the console. Defaults to true. ### Request Example ```javascript const selector = 'div.content:has(p)'; const elements = ExtendedCss.query(selector); console.log(elements); ``` ### Response #### Success Response (200) * **HTMLElement[]** - A list of DOM elements that match the selector. #### Response Example ```javascript [HTMLElement, HTMLElement, ...] ``` ``` -------------------------------- ### Main Export and Version Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/INDEX.md Exports the main ExtendedCss class and the library version constant. Ensure these are imported for basic usage. ```typescript // Main export export { ExtendedCss } from './extended-css'; // Version export { EXTENDED_CSS_VERSION } from './common/constants'; ``` -------------------------------- ### Minimal Extended CSS Configuration Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/configuration.md Use this basic configuration to apply a single stylesheet directly. Ensure the ExtendedCss class is imported. ```typescript const extendedCss = new ExtendedCss({ styleSheet: 'div.ad { display: none !important; }' }); extendedCss.apply(); ``` -------------------------------- ### Enable Global Debugging via Configuration Source: https://github.com/adguardteam/extendedcss/blob/master/README.md Alternatively, global debugging can be enabled by setting the `debug` option to `true` in the `ExtendedCss` constructor. ```javascript const extendedCss = new ExtendedCss({ styleSheet, debug, }); ``` -------------------------------- ### Error-Tolerant Configuration with Fallback Source: https://github.com/adguardteam/extendedcss/blob/master/_autodocs/README.md Instantiate ExtendedCss with either a stylesheet string or CSS rules. This pattern demonstrates a fallback mechanism for handling potential errors during configuration. ```typescript try { const extendedCss = new ExtendedCss({ styleSheet: userCSS }); } catch (error) { // Fallback to cssRules for error tolerance const extendedCss = new ExtendedCss({ cssRules: rules }); } ```