# zest **Repository Path**: mirrors_jfromaniello/zest ## Basic Information - **Project Name**: zest - **Description**: An absurdly fast CSS selector engine. - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-09-25 - **Last Updated**: 2026-05-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Zest __zest.js__ is a fast, lightweight, and extensible CSS selector engine. Zest was designed to be very concise while still supporting CSS3/CSS4 selectors and remaining fast. ## Usage ``` js zest('section! > div[title="hello" i] > :local-link /href/ h1'); ``` ## Benchmarks Each selector run 1000 times on Google Chrome 13 beta (ms): benchmarking: `header > h1` 1000 times. zest: 13 sizzle: 24 native: 13 benchmarking: `body > header > h1` 1000 times. zest: 16 sizzle: 26 native: 13 benchmarking: `html a` 1000 times. zest: 45 sizzle: 55 native: 12 benchmarking: `:first-child` 1000 times. zest: 44 sizzle: 68 native: 11 benchmarking: `:only-child` 1000 times. zest: 49 sizzle: 66 native: 12 benchmarking: `:not(a)` 1000 times. zest: 51 sizzle: 125 native: 12 benchmarking: `h1 + time:last-child` 1000 times. zest: 15 sizzle: 32 native: 13 benchmarking: `h1 + time[datetime]:last-child` 1000 times. zest: 21 sizzle: 45 native: 14 benchmarking: `header > h1, :not(a)` 1000 times. zest: 72 sizzle: 212 native: 17 benchmarking: `a[rel~="section"]` 1000 times. zest: 41 sizzle: 54 native: 11 benchmarking: `a, h1` 1000 times. zest: 25 sizzle: 55 native: 11 benchmarking: `:nth-child(2n+1)` 1000 times. zest: 82 sizzle: 97 native: 13 __NOTE:__ If you want to run these benchmarks yourself make sure to turn off Sizzle's (and Zest's) `document.querySelectorAll` delegation mechanism, otherwise you will be benchmarking against `document.querySelectorAll`. Zest will cache compiled selectors if it can't delegate to `document.querySelectorAll`, `document.getElementById`, or `document.getElementsByClassName` (depending). __The benchmark tests you see above were performed with the caching mechanism disabled. If caching were enabled, Zest would be faster than the native `document.querySelectorAll`.__ ## Install ``` bash $ npm install zest.js ``` ## Notes Zest currently includes support for ender.js, Prototype, and jQuery. __Unsupported Selectors:__ `:hover`, `:active`, `:link`, `:visited`, all pseudo elements, and namespaces. `:link`, `:visited`, and pseudo elements are unsupported for obvious reasons (they don't work). `:hover` and `:active` aren't supported because they examine a dynamic state, you should be binding to events for this (`:focus` is supported, but there is no fallback for legacy browsers). ## Extension Zest doesn't support (m)any non-standard selectors, but it is possible to add your own. ### Adding a simple selector Adding simple selectors is fairly straight forward. Only the addition of pseudo classes and attribute operators is possible. (Adding your own "style" of selector would require changes to the core logic.) Here is an example of a custom `:name` selector which will match for an element's `name` attribute: e.g. `h1:name(foo)`. Effectively an alias for `h1[name=foo]`. ``` js // if there was a parameter, // it gets closured as `param` zest.selectors[':name'] = function(param) { return function(el) { if (el.name === param) return true; }; }; ``` __NOTE__: if you're pseudo-class does not take a parameter, there will be no closure. ### Adding an attribute operator ``` js // `attr` is the attribute // `val` is the value to match zest.operators['!='] = function(attr, val) { return attr !== val; }; ``` ### Adding a combinator Adding a combinator is a bit trickier. It may seem confusing at first because the logic is upside-down. Zest interprets selectors from right to left. Here is an example how a parent combinator could be implemented: ``` js zest.combinators['<'] = function(test) { return function(el) { // `el` is the current element el = el.firstChild; while (el) { // return the relevant element // if it passed the test if (el.nodeType === 1 && test(el)) { return el; } el = el.nextSibling; } }; }; ``` The `test` function tests whatever simple selectors it needs to look for, but it isn't important what it does. The most important part is that you return the relevant element once it's found. ## License (c) Copyright 2011-2012, Christopher Jeffrey (MIT Licensed). See LICENSE for more info.