Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@asamuzakjp/dom-selector

Package Overview
Dependencies
Maintainers
1
Versions
191
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@asamuzakjp/dom-selector

A CSS selector engine.

  • 3.0.3
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
340K
increased by6.31%
Maintainers
1
Weekly downloads
 
Created
Source

DOM Selector

build CodeQL npm (scoped)

A CSS selector engine.

Install

npm i @asamuzakjp/dom-selector

Usage

import {
  matches, closest, querySelector, querySelectorAll
} from '@asamuzakjp/dom-selector';

matches(selector, node, opt)

matches - same functionality as Element.matches()

Parameters
  • selector string CSS selector
  • node object Element node
  • opt object? options
    • opt.noexcept boolean? no exception
    • opt.warn boolean? console warn e.g. unsupported pseudo-class

Returns boolean true if matched, false otherwise

closest(selector, node, opt)

closest - same functionality as Element.closest()

Parameters
  • selector string CSS selector
  • node object Element node
  • opt object? options
    • opt.noexcept boolean? no exception
    • opt.warn boolean? console warn e.g. unsupported pseudo-class

Returns object? matched node

querySelector(selector, node, opt)

querySelector - same functionality as Document.querySelector(), DocumentFragment.querySelector(), Element.querySelector()

Parameters
  • selector string CSS selector
  • node object Document, DocumentFragment or Element node
  • opt object? options
    • opt.noexcept boolean? no exception
    • opt.warn boolean? console warn e.g. unsupported pseudo-class

Returns object? matched node

querySelectorAll(selector, node, opt)

querySelectorAll - same functionality as Document.querySelectorAll(), DocumentFragment.querySelectorAll(), Element.querySelectorAll()
NOTE: returns Array, not NodeList

Parameters
  • selector string CSS selector
  • node object Document, DocumentFragment or Element node
  • opt object? options
    • opt.noexcept boolean? no exception
    • opt.warn boolean? console warn e.g. unsupported pseudo-class

Returns Array<(object | undefined)> array of matched nodes

Supported CSS selectors

PatternSupportedNote
*
ns|E
*|E
|E
E
E:not(s1, s2, …)
E:is(s1, s2, …)
E:where(s1, s2, …)
E:has(rs1, rs2, …)
E.warning
E#myid
E[foo]
E[foo="bar"]
E[foo="bar" i]
E[foo="bar" s]
E[foo~="bar"]
E[foo^="bar"]
E[foo$="bar"]
E[foo*="bar"]
E[foo|="en"]
E:definedUnsupported
E:dir(ltr)
E:lang(en)Partially supportedComma-separated list of language codes, e.g. :lang(en, fr), is not yet supported.
E:any‑link
E:link
E:visitedReturns false or null to prevent fingerprinting.
E:local‑link
E:target
E:target‑within
E:scope
E:currentUnsupported
E:current(s)Unsupported
E:pastUnsupported
E:futureUnsupported
E:activeUnsupported
E:hoverUnsupported
E:focus
E:focus‑within
E:focus‑visibleUnsupported
E:enabled
E:disabled
E:read‑write
E:read‑only
E:placeholder‑shown
E:default
E:checked
E:indeterminate
E:valid
E:invalid
E:required
E:optional
E:blankUnsupported
E:user‑invalidUnsupported
E:root
E:empty
E:nth‑child(n [of S]?)
E:nth‑last‑child(n [of S]?)
E:first‑child
E:last‑child
E:only‑child
E:nth‑of‑type(n)
E:nth‑last‑of‑type(n)
E:first‑of‑type
E:last‑of‑type
E:only‑of‑type
E F
E > F
E + F
E ~ F
F || EUnsupported
E:nth‑col(n)Unsupported
E:nth‑last‑col(n)Unsupported
:host
:host(s)
:host‑context(s)

Monkey patch jsdom

import { JSDOM } from 'jsdom';
import {
  closest, matches, querySelector, querySelectorAll
} from '@asamuzakjp/dom-selector';

const dom = new JSDOM('', {
  runScripts: 'dangerously',
  url: 'http://localhost/',
  beforeParse: window => {
    window.Element.prototype.matches = function (...args) {
      if (!args.length) {
        throw new window.TypeError('1 argument required, but only 0 present.');
      }
      const [selector] = args;
      return matches(selector, this);
    };
    window.Element.prototype.closest = function (...args) {
      if (!args.length) {
        throw new window.TypeError('1 argument required, but only 0 present.');
      }
      const [selector] = args;
      return closest(selector, this);
    };
    window.Document.prototype.querySelector = function (...args) {
      if (!args.length) {
        throw new window.TypeError('1 argument required, but only 0 present.');
      }
      const [selector] = args;
      return querySelector(selector, this);
    };
    window.DocumentFragment.prototype.querySelector = function (...args) {
      if (!args.length) {
        throw new window.TypeError('1 argument required, but only 0 present.');
      }
      const [selector] = args;
      return querySelector(selector, this);
    };
    window.Element.prototype.querySelector = function (...args) {
      if (!args.length) {
        throw new window.TypeError('1 argument required, but only 0 present.');
      }
      const [selector] = args;
      return querySelector(selector, this);
    };
    window.Document.prototype.querySelectorAll = function (...args) {
      if (!args.length) {
        throw new window.TypeError('1 argument required, but only 0 present.');
      }
      const [selector] = args;
      return querySelectorAll(selector, this);
    };
    window.DocumentFragment.prototype.querySelectorAll = function (...args) {
      if (!args.length) {
        throw new window.TypeError('1 argument required, but only 0 present.');
      }
      const [selector] = args;
      return querySelectorAll(selector, this);
    };
    window.Element.prototype.querySelectorAll = function (...args) {
      if (!args.length) {
        throw new window.TypeError('1 argument required, but only 0 present.');
      }
      const [selector] = args;
      return querySelectorAll(selector, this);
    };
  }
});

Performance

matches()

Selectorjsdom v24.0.0 (nwsapi)happy-domlinkeDompatched-jsdom (dom-selector)Result
simple selector:
matches('.content')
2,730,719 ops/sec ±0.80%1,669,966 ops/sec ±0.28%657,226 ops/sec ±1.30%191,661 ops/sec ±0.17%jsdom is the fastest and 14.2 times faster than patched-jsdom.
compound selector:
matches('p.content[id]:only-child')
1,153,187 ops/sec ±0.26%470,767 ops/sec ±0.85%309,344 ops/sec ±0.18%89,231 ops/sec ±0.70%jsdom is the fastest and 12.9 times faster than patched-jsdom.
complex selector:
matches('.box:first-child ~ .box:nth-of-type(4n+1) + .box[id] .block.inner > .content')
165,982 ops/sec ±0.46%N/A72,727 ops/sec ±0.25%21,674 ops/sec ±1.35%jsdom is the fastest and 7.7 times faster than patched-jsdom.

closest()

Selectorjsdom v24.0.0 (nwsapi)happy-domlinkeDompatched-jsdom (dom-selector)Result
simple selector:
closest('.container')
578,462 ops/sec ±1.64%361,946 ops/sec ±2.15%397,660 ops/sec ±1.70%66,355 ops/sec ±1.68%jsdom is the fastest and 8.7 times faster than patched-jsdom.
compound selector:
closest('div.container[id]:not(.box)')
216,725 ops/sec ±1.66%79,273 ops/sec ±1.88%169,185 ops/sec ±1.81%33,135 ops/sec ±0.98%jsdom is the fastest and 6.5 times faster than patched-jsdom.
complex selector:
closest('.box:first-child ~ .box:nth-of-type(4n+1) + .box[id] .block.inner > .content')
159,848 ops/sec ±0.29%N/A72,070 ops/sec ±1.68%17,559 ops/sec ±2.09%jsdom is the fastest and 9.1 times faster than patched-jsdom.

querySelector()

Selectorjsdom v24.0.0 (nwsapi)happy-domlinkeDompatched-jsdom (dom-selector)Result
simple selector:
querySelector('.content')
3,326 ops/sec ±1.31%342,846 ops/sec ±1.70%322,199 ops/sec ±2.38%70,933 ops/sec ±1.88%happydom is the fastest and 4.8 times faster than patched-jsdom.
compound selector:
querySelector('p.content[id]:only-child')
1,309 ops/sec ±1.19%382,636 ops/sec ±1.56%252,823 ops/sec ±2.03%47,759 ops/sec ±1.44%happydom is the fastest and 8.0 times faster than patched-jsdom.
complex selector:
querySelector('.box:first-child ~ .box:nth-of-type(4n+1) + .box[id] .block.inner > .content')
242 ops/sec ±0.16%N/A1,342 ops/sec ±0.37%911 ops/sec ±1.80%linkedom is the fastest and 1.5 times faster than patched-jsdom.

querySelectorAll()

Selectorjsdom v24.0.0 (nwsapi)happy-domlinkeDompatched-jsdom (dom-selector)Result
simple selector:
querySelectorAll('.content')
3,090 ops/sec ±1.08%778 ops/sec ±1.56%1,203 ops/sec ±1.37%2,483 ops/sec ±0.90%jsdom is the fastest and 1.2 times faster than patched-jsdom.
compound selector:
querySelectorAll('p.content[id]:only-child')
1,280 ops/sec ±0.96%915 ops/sec ±1.57%1,029 ops/sec ±0.89%151 ops/sec ±0.91%jsdom is the fastest and 8.5 times faster than patched-jsdom.
complex selector:
querySelectorAll('.box:first-child ~ .box:nth-of-type(4n+1) + .box[id] .block.inner > .content')
245 ops/sec ±0.26%N/A438 ops/sec ±1.42%904 ops/sec ±1.49%patched-jsdom is the fastest.

Acknowledgments

The following resources have been of great help in the development of the DOM Selector.


Copyright (c) 2023 asamuzaK (Kazz)

FAQs

Package last updated on 31 Jan 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

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