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

css-selector-parser

Package Overview
Dependencies
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

css-selector-parser - npm Package Versions

23

3.0.5

Diff

Changelog

Source

3.0.5 (2024-03-02)

Bug Fixes

  • single hyphen is not a valid identifier, throwing an exception, closes #38 (2520a49)
mdevils
published 3.0.4 •

Changelog

Source

3.0.4 (2023-12-15)

Bug Fixes

  • align identifier and string parsing and rendering with CSS standards, closes #36, closes #37 (ac0dbc0)
mdevils
published 3.0.3 •

Changelog

Source

3.0.3 (2023-12-08)

Bug Fixes

  • align identifier parsing with CSS standards and browser behaviour (6087705)
mdevils
published 3.0.2 •

Changelog

Source

3.0.2 (2023-11-21)

Bug Fixes

  • identifier parsing for ids, classes, pseudo-classes and pseudo-elements (d222dfd)
mdevils
published 3.0.1 •

Changelog

Source

3.0.1 (2023-11-20)

Bug Fixes

mdevils
published 3.0.0 •

Changelog

Source

3.0.0 (2023-09-26)

⚠ BREAKING CHANGES

  • API is backwards incompatible.
Migrating from 2.x to 3.x
  1. Rule.tag was moved to Rule.items.

    Example selector: div.

    • Before: {type: 'Rule', tagName: {type: 'TagName', name: 'div'}}
    • After: {type: 'Rule', items: [{type: 'TagName', name: 'div'}]}
  2. Rule.classNames was converted to an AST entity and moved to Rule.items.

    Example selector: .user.hidden

    • Before: {type: 'Rule', classNames: ['user', 'hidden']}
    • After: {type: 'Rule', items: [{type: 'ClassName', name: 'user'}, {type: 'ClassName', name: 'hidden'}]}
  3. Rule.ids was converted to an AST entity and moved to Rule.items.

    Example selector: #root#user-1

    • Before: {type: 'Rule', ids: ['root', 'user-1']}
    • After: {type: 'Rule', items: [{type: 'Id', name: 'root'}, {type: 'Id', name: 'user-1'}]}
  4. Rule.attributes was moved to Rule.items.

    Example selector: [href^=/][role]

    • Before: {type: 'Rule', attributes: [{type: 'Attribute', name: 'href', operator: '^=', value: {type: 'String', value: '/'}}, {type: 'Attribute', name: 'role'}]}
    • After: {type: 'Rule', items: [{type: 'Attribute', name: 'href', operator: '^=', value: {type: 'String', value: '/'}}, {type: 'Attribute', name: 'role'}]}
  5. Rule.pseudoClasses was moved to Rule.items.

    Example selector: :hover:lang(en)

    • Before: {type: 'Rule', pseudoClasses: [{type: 'PseudoClass', name: 'hover'}, {type: 'PseudoClass', name: 'lang', value: {type: 'String', value: 'en'}}]}
    • After: {type: 'Rule', items: [{type: 'PseudoClass', name: 'hover'}, {type: 'PseudoClass', name: 'lang', value: {type: 'String', value: 'en'}}]}
  6. Rule.pseudoElement was converted to an AST entity and moved to Rule.items.

    Example selector: ::before

    • Before: {type: 'Rule', pseudoElement: 'before'}
    • After: {type: 'Rule', items: [{type: 'PseudoElement', name: 'before'}]}
New AST methods
  • ast.id and ast.isId to create and test ast nodes with type Id.
  • ast.className and ast.isClassName to create and test ast nodes with type ClassName.
  • ast.pseudoElement and ast.isPseudoElement to create and test ast nodes with type PseudoElement.
New Syntax Definition configuration
  • pseudoElements.definitions was updated to accept signatures in otder to support specifying pseudo-elements with an argument. Example: createParser({syntax: {pseudoElements: {definitions: {NoArgument: ['before'], String: ['highlight'], Selector: ['slotted']}}}}).
Migrating from 1.x to 3.x
CssSelectorParser -> createParser

In 1.x versions there was CssSelectorParser class which had to be contructed and then configured. In 3.x versions there is createParser() function which returns a parse() function. All the configutation is passed to createParser() params.

Before:

var CssSelectorParser = require('css-selector-parser').CssSelectorParser,
parser = new CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNumericPseudos('nth-child');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');

const selector = parser.parse('a[href^=/], .container:has(nav) > a[href]:lt($var):nth-child(5)');

After:

import {createParser} from 'css-selector-parser';

const parse = createParser({
    syntax: {
        pseudoClasses: {
            // In 1.x any pseudo-classes were accepted.
            // in 2.x parser only accepts known psuedo-classes unless `unknown: accept` was specified. 
            unknown: 'accept',
            definitions: {
                // This is a replacement for registerSelectorPseudos().
                Selector: ['has'],
                // This is a replacement for registerNumericPseudos().
                Formula: ['nth-child']
            }
        },
        // This is a replacement for registerNestingOperators().
        combinators: ['>', '+', '~'],
        attributes: {
            // This a replacement for registerAttrEqualityMods().
            // Note that equals sign ("=") is included into the operator definitions.
            operators: ['^=', '$=', '*=', '~=']
        }
    },
    // This is a replacement for enableSubstitutes()
    substitutes: true
});

const selector = parse('a[href^=/], .container:has(nav) > a[href]:lt($var):nth-child(5)');
Predefined CSS syntax definitions

You no longer need to make an extensive configuration of css-selector-parser in order to make it understand the necessary CSS standards. You can now just define CSS/CSS selectors version directly:

import {createParser} from 'css-selector-parser';

const parse = createParser({syntax: 'css3'});

const selector = parse('a[href^=/], .container:has(nav) > a[href]:nth-child(2n + 1)::before');

Here are the pre-defined CSS standards for your disposal:

  • css1: https://www.w3.org/TR/CSS1/
  • css2: https://www.w3.org/TR/CSS2/
  • css3/selectors-3: https://www.w3.org/TR/selectors-3/
  • selectors-4: https://www.w3.org/TR/selectors-4/
  • latest: refers to selectors-4
  • progressive: latest + accepts unknown psudo-classes, psudo-elements and attribute case sensitivity modifiers
Make sure you use proper strict value

CSS selector parser in modern browsers is very forgiving. For instance, it works fine with unclosed attribute selectors: "[attr=value". If you would like to mimic this behavior from browsers, set strict to false, i.e.:

import {createParser} from 'css-selector-parser';

const parse = createParser({syntax: 'css3', strict: false});

const selector = parse(':lang(en'); // doesn't crash
Render is now a separate export

render() method used to be a method of CssSelectorParser class. Now it can be imported directly and used.

Example:

import {createParser, render} from 'css-selector-parser';

const parse = createParser({syntax: 'progressive'});

const selector = parse('div#user-123.user:lang(en)::before');

console.log(render(selector)); // div#user-123.user:lang(en)::before
AST changes

AST had a lot of changes.

Selector

New type info.

  1. Type changed: selector -> Selector.
  2. Prop changed: selectors -> rules, also selectors contained ruleSet[], which in turn has rule field, and new rules contains Rule[] directly.

Before: {type: 'selector', selectors: [ {type: 'ruleSet', rule: {<RULE 1 DATA>}}, {type: 'ruleSet', rule: {<RULE 2 DATA>}} ]}.

After: {type: 'Selector', rules: [ {<RULE 1 DATA>}, {<RULE 2 DATA>} ]}.

Rule

New type info.

  1. Type changed: rule -> Rule.
  2. Prop changed: id: string -> items: [{type: 'Id', name: '<ID>'}, ...]. According to the CSS spec one rule may have more than 1 id, so #root#root is a valid selector.
  3. Prop renamed: nestingOperator -> combinator. A proper name according to CSS spec was chosen.
  4. Prop renamed: rule -> nestedRule. A proper name to indicate nesting was chosen.
  5. Prop changed: tagName: string -> items: [TagName | WildcardTag, ...]. Using explicit distinction between TagName (i.e. div) and WildcardTag (*), because tag name can also be * if escaped properly (\*).
  6. Prop changed: attrs -> items: [<ATTRIBUTE>, ...]. Attribute type was changed, see below.
  7. Prop changed: pseudos -> items: [<PSEUDO CLASS>, ...]. There are pseudo-elements and pseudo-classes, now they are separated properly (there is a separate pseudoElement type). Pseudo class type was changed, see below.

Before:

({
    type: 'rule',
    tagName: 'div',
    id: 'user-123',
    classNames: ['user'],
    attrs: [
        {name: 'role', operator: '$=', valueType: 'string', value: 'button'}
    ],
    pseudos: [
        {name: 'lang', valueType: 'string', value: 'en'}
    ],
    nestingOperator: '>'
})

After:

({
    type: 'Rule',
    items: [
       {type: 'TagName', name: 'div'},
       {type: 'Id', name: 'user-123'},
       {type: 'ClassName', name: 'user'},
       {type: 'Attribute', name: 'role', operator: '$=', value: {type: 'String', value: 'button'}},
       {type: 'PseudoClass', name: 'lang', value: {type: 'String', value: 'en'}}
    ],
    combinator: '>'
})
Attribute

New type info.

  1. Type introduced: Attribute.
  2. Prop value and valueType were combined to a single prop value with a field type.

All possible value types.

Example 1

Before: {name: 'role'}.

After: {type: 'Attribute', name: 'role'}.

Example 2

Before: {name: 'role', operator: '$=', valueType: 'string', value: 'button'}.

After: {type: 'Attribute', name: 'role', operator: '$=', value: {type: 'String', value: 'button'}}.

Example 3

Before: {name: 'role', operator: '=', valueType: 'substitute', value: 'var'}.

After: {type: 'Attribute', name: 'role', operator: '=', value: {type: 'Substitute', name: 'var'}}.

Pseudo Classes

New type info.

  1. Type introduced: PseudoClass.
  2. Prop value and valueType were combined to a single prop argument with a field type.

All possible argument types.

Example 1

Before: {name: 'visited'}.

After: {type: 'PseudoClass', name: 'visited'}.

Example 2

Before: {name: 'lang', valueType: 'string', value: 'en'}.

After: {type: 'PseudoClass', name: 'lang', argument: {type: 'String', value: 'en'}}.

Example 3

Before: {name: 'lang', valueType: 'substitute', value: 'var'}.

After: {type: 'PseudoClass', name: 'lang', argument: {type: 'Substitute', name: 'var'}}.

Example 4

Before: {name: 'has', valueType: 'selector', value: {type: 'selector', selectors: [{type: 'ruleSet', rule: {type: 'rule', tagName: 'div'}}]}}.

After: {type: 'PseudoClass', name: 'has', argument: {type: 'Selector', rules: [{type: 'Rule', tag: {type: 'TagName', name: 'div'}}]}}.

Pseudo Elements

New type info.

  1. Type introduced: PseudoElement.

All possible argument types.

Features

  • upgrade API in order to reflect upcoming complexity in CSS selectors (cece4df)
mdevils
published 2.3.2 •

Changelog

Source

2.3.2 (2023-06-25)

Bug Fixes

  • fix foruma parsing with negative A, closes #28 (824312f)
  • include js file extension into the mjs build, closes #22 (f50b350)
  • rendering nested selectors with combinators, closes #27 (40fb434)
mdevils
published 2.3.1 •

Changelog

Source

2.3.1 (2023-06-24)

Bug Fixes

mdevils
published 2.3.0 •

Changelog

Source

2.3.0 (2023-06-24)

Features

  • publish hybrid package: CommonJS and ESM modules (16fd8a1)
mdevils
published 2.2.3 •

Changelog

Source

2.3.0 (2023-06-24)

Features

  • publish hybrid package: CommonJS and ESM modules (16fd8a1)
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