# selderee ![lint status badge](https://github.com/mxxii/selderee/workflows/lint/badge.svg) ![test status badge](https://github.com/mxxii/selderee/workflows/test/badge.svg) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/mxxii/selderee/blob/main/LICENSE) [![npm](https://img.shields.io/npm/dw/selderee?color=informational&logo=npm)](https://www.npmjs.com/package/selderee) **Sel**ectors **de**cision t**ree** - pick matching selectors, fast. ---- ## What is it for The problem statement: there are multiple CSS selectors with attached handlers, and a HTML DOM to process. For each HTML Element a matching handler has to be found and applied. The naive approach is to walk through the DOM and test each and every selector against each Element. This means *O(n\*m)* complexity. It is pretty clear though that if we have selectors that share something in common then we can reduce the number of checks. The main `selderee` package offers the selectors tree structure. Runnable decision functions for specific DOM implementations are built via plugins. ## Limitations - Pseudo-classes and pseudo-elements are not supported by the underlying library [parseley](https://github.com/mxxii/parseley) (yet?); - General siblings (`~`), descendants (` `) and same column combinators (`||`) are also not supported. ## `selderee` vs `css-select` [css-select](https://github.com/fb55/css-select) - a CSS selector compiler & engine. | Feature | `selderee` | `css-select` | | ------------------------------------- | :--------: | :----------: | | Support for `htmlparser2` DOM AST | plugin | + | | "Compiles" into a function | + | + | | Pick selector(s) for a given Element | + | | | Query Element(s) for a given selector | | + | ## Packages | Package | Version | Folder | Changelog | | --------- | --------- | --------- | --------- | | [selderee](https://www.npmjs.com/package/selderee) | [![npm](https://img.shields.io/npm/v/selderee?logo=npm)](https://www.npmjs.com/package/selderee) | [/packages/selderee](https://github.com/mxxii/selderee/tree/main/packages/selderee/) | [changelog](https://github.com/mxxii/selderee/blob/main/packages/selderee/CHANGELOG.md) | | [@selderee/plugin-htmlparser2](https://www.npmjs.com/package/@selderee/plugin-htmlparser2) | [![npm](https://img.shields.io/npm/v/@selderee/plugin-htmlparser2?logo=npm)](https://www.npmjs.com/package/@selderee/plugin-htmlparser2) | [/packages/plugin-htmlparser2](https://github.com/mxxii/selderee/tree/main/packages/plugin-htmlparser2/) | [changelog](https://github.com/mxxii/selderee/blob/main/packages/plugin-htmlparser2/CHANGELOG.md) | ## Install ```shell > npm i selderee @selderee/plugin-htmlparser2 ``` ## Documentation - [API](https://github.com/mxxii/selderee/blob/main/docs/index.md) ## Usage example ```js const htmlparser2 = require('htmlparser2'); const util = require('util'); const { DecisionTree, Treeify } = require('selderee'); const { hp2Builder } = require('@selderee/plugin-htmlparser2'); const selectorValuePairs = [ ['p', 'A'], ['p.foo[bar]', 'B'], ['p[class~=foo]', 'C'], ['div.foo', 'D'], ['div > p.foo', 'E'], ['div > p', 'F'], ['#baz', 'G'] ]; // Make a tree structure from all given selectors. const selectorsDecisionTree = new DecisionTree(selectorValuePairs); // `treeify` builder produces a string output for testing and debug purposes. // `treeify` expects string values attached to each selector. const prettyTree = selectorsDecisionTree.build(Treeify.treeify); console.log(prettyTree); const html = /*html*/`
second