npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

zest

v0.1.3

Published

Fast, lightweight, extensible css selector engine.

Downloads

92

Readme

Zest

zest 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

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

$ npm install zest

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].

// 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

// `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:

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.

Contribution and License Agreement

If you contribute code to this project, you are implicitly allowing your code to be distributed under the MIT license. You are also implicitly verifying that all code is your original work. </legalese>

License

(c) Copyright 2011-2012, Christopher Jeffrey (MIT Licensed). See LICENSE for more info.