A modern, context-aware, and extendable CSS selector engine built on top of querySelectorAll
JavaScript
Latest commit cb064bc Jan 18, 2017 @ryanmorr Build v0.2.2
Permalink
Failed to load latest commit information.
dist
src
test
.babelrc
.editorconfig
.eslintrc
.gitattributes
.gitignore
.travis.yml
README.md
UNLICENSE
gulpfile.babel.js
package.json

README.md

sonic

Version Badge Build Status Dependencies License File Size

A modern, context-aware, and extendable CSS selector engine built on top of querySelectorAll.

Usage

Find a single element:

// Returns the matching element or null if no match is found
const el = sonic.find('#container');

Query for multiple elements:

// Returns an array of all matching elements
const elements = sonic.query('.items');

Check if an element matches a selector string:

const isMatch = sonic.matches(element, 'div.class[attr=value]');

Provide an element or selector string as an optional second argument as the root of the query:

const el = sonic.find('[attr]', element);
const elements = sonic.query(':first-child', '#header');

Use leading combinators:

const divs = sonic.query('> div');
const blocks = sonic.query('+ .block');
const checked = sonic.query('~ :checked');

Extendable

Create custom pseudo-class selectors (must return a boolean):

sonic.pseudos.foo = (el) => {
    return el.hasAttribute('foo');
};

sonic.pseudos.bar = (el, value) => {
    return el.hasAttribute(value);
};

const el = sonic.find(':foo');
const elements = sonic.query(':bar(class)');

Context-Aware

Sonic addresses the long-standing flaw in querySelector and querySelectorAll that sees element-rooted queries search relative to the document and not the element itself:

<section id="container">
    <em>Level 1</em>
    <section>
        <em>Level 2</em>
    </section>
</section>
// Expected <em>Level 2</em>, but returns <em>Level 1</em>, doh!
document.querySelector('#container').querySelector('section em');

Apparently, this behavior is purported to be correct given how long it has endured. Sonic, on the other hand, abides by the principle of least surprise and gives you exactly what you expect.

// Returns <em>Level 2</em> as expected, hooray!
const elements = sonic.query('section em', '#container');

Installation

Sonic is CommonJS and AMD compatible with no dependencies. You can download the development or minified version, or install it in one of the following ways:

npm install ryanmorr/sonic

bower install ryanmorr/sonic

Tests

Run unit tests by issuing the following commands:

npm install
npm install -g gulp
gulp test

License

This project is dedicated to the public domain as described by the Unlicense.