Joyquery

Javascript library implementing emulation of CSS selectors lookup, as document.querySelector.

View the Project on GitHub jeremiah-shaulov/joyquery

Home
Features
Selectors
API reference
Adding extensions
Benchmark

See also:
Joyquery for PHP

This is PHP version of the joyquery library. It allows to make CSS queries on server side.

This version has the same feature set as regular joyquery except features that depend on browser. The following features are not included:

  1. :focus
  2. :hidden

Furthermore the following features respect only the source HTML/XML markup, but not the actual state:

  1. :disabled
  2. :enabled
  3. :checked

In other words, :checked will find only elements that have "checked" or "selected" attributes, but not elements that are checked by default according to browser rules.

The library contains class called JoyQuery with only one public static function:

public static function evaluate($css_selector, DOMNode $node, array $functions=null)

In case of error this function throws Exception. If no error, it returns DOMNodeList object.

Here is usage example:

require_once 'JoyQuery.class.php';

$doc = new DOMDocument;
$doc->loadHTML('<Div class=d hello=world><span>Hello</span></Div>');
//or: $doc->loadXML('<Div class="d" hello="world"><span>Hello</span></Div>');

$elements = JoyQuery::evaluate('.d span:last-child', $doc);
foreach ($elements as $elem)
{   echo $doc->saveXml($elem->cloneNode()), "\n\n";
}

Here is how to provide custom function:

require_once 'JoyQuery.class.php';

$doc = new DOMDocument;
$doc->loadHTML('<Div class=d hello=world><span>Hello</span></Div>');

$elements = JoyQuery::evaluate
(   '*:not(html):not(body):contains-word("Hello")',
    $doc,
    array
    (   'contains_word' => function(DOMElement $node, $word)
        {   return strpos($node->textContent, $word) !== false;
        }
    )
);
foreach ($elements as $elem)
{   echo $doc->saveXml($elem->cloneNode()), "\n\n";
}

Adding extension:

JoyQuery::$FUNCTIONS['my_custom_empty'] = function(DOMElement $node)
{   for ($e=$node->firstChild; $e; $e=$e->nextSibling)
    {   if ($e->nodeType!=XML_TEXT_NODE && $e->nodeType!=XML_CDATA_SECTION_NODE or $e->length>0)
        {   return false;
        }
    }
    return true;
};