Skip to content

koal44/selectlet

Repository files navigation

selectlet

A TypeScript CSS selector engine for JavaScript DOM implementations.

selectlet provides selector APIs such as matches(), closest(), querySelector(), and querySelectorAll() for DOM environments outside browser engines. It is developed against browser-oracle tests for Chromium, Firefox, and WebKit, including translated WPT cases and jsdom integration scenarios.

Installation

npm install selectlet

Usage

ESM

import { createSelectlet } from "selectlet";

const sx = createSelectlet(document);

const items = sx.select(".item[data-active]");
const first = sx.first("main article");
const ok = sx.matches(":is(button, input)", element);
const closest = sx.closest("section", element);

CommonJS

const { createSelectlet } = require("selectlet");

const sx = createSelectlet(document);

const items = sx.select(".item");

Browser/global build

The browser build exposes createSelectlet on the global object.

<script src="selectlet.js"></script>
<script>
  const sx = createSelectlet(document);
  const buttons = sx.select("button");
</script>

API

const sx = createSelectlet(document, options);
type Selectlet = {
  version: string;

  byId(id: string, ctx?: QueryContext): Element | null;
  byTag(tag: string, ctx?: QueryContext): ElementList;
  byTagNs(ns: string | null, local: string, ctx?: QueryContext): ElementList;
  byClass(cls: string, ctx?: QueryContext): ElementList;

  matches(sel: string, el: Element): boolean;
  select(sel: string, ctx?: QueryContext): ElementList;
  first(sel: string, ctx?: QueryContext): Element | null;
  closest(sel: string, el: Element): Element | null;

  registerPseudo(name: string, predicate: CustomPseudoPredicate): void;
};

QueryContext may be a Document, Element, or DocumentFragment.

By default, multi-element APIs return arrays. With NODE_LIST enabled, they return a NodeList-like indexed object.

DOM implementation hooks

selectlet can use DOM-internal hooks for lower wrapper overhead and faster implementation-owned lookup paths.

const sx = createSelectlet(documentImpl, {
  errors: {
    syntax: err => createSyntaxError(err)
  },

  caps: {
    tree: {
      treeVersion: node => getTreeVersion(node)
    },

    doc: {
      cachedIds: (doc, id) => getElementsByIdFromCache(doc, id)
    },

    el: {
      getId: el => getInternalId(el),
      getClass: el => getInternalClass(el),
      getLocalName: el => getInternalLocalName(el),
      getNamespaceURI: el => getInternalNamespace(el),
      getAttribute: (el, name) => getInternalAttribute(el, name),
      hasAttribute: (el, name) => hasInternalAttribute(el, name)
    }
  }
});

Status

selectlet is under active development. Current work is focused on jsdom integration, browser/WPT conformance coverage, shadow DOM selector behavior, and selector API performance.

Development

npm test
npm run build

The repository includes unit tests, browser-oracle scenario tests, jsdom-oriented scenarios, and benchmark tests. See package.json for the current scripts.

License

MIT

About

CSS selector 4 engine for javascript/typescript

Topics

Resources

License

Stars

Watchers

Forks

Contributors