NWSAPI CSS Selector Engine

2.2.23 · active · verified Tue Apr 21

NWSAPI is a high-performance CSS selector engine, serving as a continuation and significant rework of the earlier `nwmatcher` project, currently at version 2.2.23. Its primary goal is to provide comprehensive and fast support for the latest CSS Level 4 Selectors, while also meticulously emulating native browser APIs such as `querySelector()`, `querySelectorAll()`, `matches()`, and `closest()`. The library is actively maintained, with a focus on continuous bug fixes and feature enhancements, and is intended to replace `nwmatcher` in environments like `jsdom`. NWSAPI differentiates itself through a unique architecture that employs regular expressions to parse CSS selector strings and metaprogramming to transform these into memoized JavaScript function resolvers, a process executed only once per selector for 'unmatched performances'. It ships with no external dependencies and supports both browser environments (via a global `NW.Dom` object) and headless environments like Node.js (as a CommonJS module).

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates how to install `nwsapi` in a Node.js environment using `jsdom` to simulate a browser DOM, and then how to configure and bind its selector methods (`querySelector`, `querySelectorAll`, `matches`, `closest`) to the `JSDOM` document and `Element` prototype for a familiar API experience.

const { JSDOM } = require('jsdom');
const nwsapi = require('nwsapi');

// Create a JSDOM instance to simulate a browser environment
const dom = new JSDOM(`
  <!DOCTYPE html>
  <html>
    <body>
      <div id="app">
        <header>
          <h1>My Title</h1>
          <nav>
            <ul>
              <li><a href="#home">Home</a></li>
              <li><a href="#about" class="active">About</a></li>
            </ul>
          </nav>
        </header>
        <main>
          <section class="content">
            <p>Some text here.</p>
            <button id="myButton">Click Me</button>
          </section>
          <section class="footer-content">
            <p>More text.</p>
          </section>
        </main>
      </div>
    </body>
  </html>
`);

// Get the document object from the JSDOM instance
const document = dom.window.document;

// Configure NWSAPI to work with the JSDOM document context
// The library's functions need to be bound to a context that behaves like a DOM element/document.
const engine = nwsapi.configure({
  // Example configuration: allow duplicate IDs (default is true)
  IDS_DUPES: true
});

// Manually bind NWSAPI methods to the JSDOM document and Element prototype
// This makes it behave like a polyfilled native API.
document.querySelector = (selector) => engine.first(selector, document);
document.querySelectorAll = (selector) => engine.select(selector, document);
dom.window.Element.prototype.matches = function(selector) { return engine.match(selector, this); };
dom.window.Element.prototype.closest = function(selector) { return engine.ancestor(selector, this); };

// --- Using the NWSAPI-enhanced JSDOM document --- 

// Find the first element matching a selector
const mainTitle = document.querySelector('h1');
console.log('Main title:', mainTitle ? mainTitle.textContent : 'Not found');

// Find all elements matching a selector
const allParagraphs = document.querySelectorAll('p');
console.log('Number of paragraphs:', allParagraphs.length);
allParagraphs.forEach((p, i) => console.log(`Paragraph ${i + 1}:`, p.textContent));

// Check if an element matches a selector
const aboutLink = document.querySelector('a.active');
if (aboutLink) {
  console.log('Is "About" link active?', aboutLink.matches('.active'));
  console.log('Is "About" link a button?', aboutLink.matches('button'));
}

// Find the closest ancestor
const myButton = document.getElementById('myButton');
if (myButton) {
  const closestSection = myButton.closest('section');
  console.log('Closest section to button:', closestSection ? closestSection.className : 'Not found');
}

view raw JSON →