Source for file css_selector.php
Documentation is available at css_selector.php
* @subpackage DomTestCase
* @author Perrick Penet <perrick@noparking.net>
* @version $Id: css_selector.php 1538 2007-06-08 20:37:35Z pp11 $
* Allow to navigate a DOM with CSS selector.
* based on getElementsBySelector version 0.4 - Simon Willison, 2003-03-25
* http://simon.incutio.com/archive/2003/03/25/getElementsBySelector
* derived from sfDomCssSelector Id 3053 (Symfony version 1.0.2) - Fabien Potencier, 2006-12-16
* http://www.symfony-project.com/api/symfony/util/sfDomCssSelector.html
* @param DomDocument $dom
$texts[] =
$element->nodeValue;
$nodes =
array($this->dom);
foreach ($this->tokenize($selector) as $token)
$combinator =
$token['combinator'];
$token =
trim($token['name']);
// Token is an ID selector
$tagName =
substr($token, 0, $pos);
$id =
substr($token, $pos +
1);
$xpath =
new DomXPath($this->dom);
$element =
$xpath->query(sprintf("//*[@id = '%s']", $id))->item(0);
if (!$element ||
($tagName &&
strtolower($element->nodeName) !=
$tagName))
// tag with that ID not found
// Set nodes to contain just this element
$nodes =
array($element);
continue; // Skip to next token
// Token contains a class selector
$tagName =
substr($token, 0, $pos);
$className =
substr($token, $pos +
1);
// Get elements matching tag, filter them for class selector
foreach ($founds as $found)
if (preg_match('/\b'.
$className.
'\b/', $found->getAttribute('class')))
continue; // Skip to next token
// Code to deal with attribute selectors
if (preg_match('/^(\w*)(\[.+\])$/', $token, $matches))
$tagName =
$matches[1] ?
$matches[1] :
'*';
([=~\|\^\$\*]?) # modifier (optional)
"([^"]*)" # quoted value (optional)
([^\]]*) # non quoted value (optional)
/x', $matches[2], $matches, PREG_SET_ORDER);
// Grab all of the tagName elements within current node
foreach ($founds as $found)
foreach ($matches as $match)
$attrOperator =
$match[2];
$ok =
$found->getAttribute($attrName) ==
$attrValue;
case '~':
// Match one of space seperated words
case '|':
// Match start with value followed by optional hyphen
case '^':
// Match starts with value
$ok =
0 ===
strpos($found->getAttribute($attrName), $attrValue);
case '$':
// Match ends with value
$ok =
$attrValue ==
substr($found->getAttribute($attrName), -
strlen($attrValue));
case '*':
// Match ends with value
$ok =
false !==
strpos($found->getAttribute($attrName), $attrValue);
// Just test for existence of attribute
$ok =
$found->hasAttribute($attrName);
continue; // Skip to next token
if (preg_match('/^(\w*)(:first-child)$/', $token, $matches)) {
$token =
$matches[1] ?
$matches[1] :
'*';
$combinator =
$matches[2] ?
$matches[2] :
'';
// If we get here, token is JUST an element (not a class or ID selector)
foreach ($nodes as $node)
if (!$node->getAttribute('sf_matched'))
$node->setAttribute('sf_matched', true);
foreach ($all_nodes as $node)
$node->removeAttribute('sf_matched');
foreach ($nodes as $node)
foreach ($node->getElementsByTagName($tagName) as $element)
foreach ($node->childNodes as $element)
if ($tagName ==
$element->nodeName)
$element =
$node->nextSibling;
if ($element->nodeName ==
"#text") {
$element =
$element->nextSibling;
if ($element &&
$tagName ==
$element->nodeName) {
foreach ($node->getElementsByTagName($tagName) as $element) {
if (count($founds) ==
0) {
// split tokens by , except in an attribute selector
for ($i =
0, $max =
strlen($selector); $i <
$max; $i++
)
if (',' ==
$selector[$i] &&
!$quoted)
$tokens[] =
trim($token);
else if ('"' ==
$selector[$i])
$quoted =
$quoted ?
false :
true;
$tokens[] =
trim($token);
// split tokens by space except if space is in an attribute selector
$combinators =
array(' ', '>', '+');
$token =
array('combinator' =>
' ', 'name' =>
'');
for ($i =
0, $max =
strlen($selector); $i <
$max; $i++
)
if (in_array($selector[$i], $combinators) &&
!$quoted)
// remove all whitespaces around the combinator
$combinator =
$selector[$i];
while (in_array($selector[$i +
1], $combinators))
if (' ' !=
$selector[++
$i])
$combinator =
$selector[$i];
$token =
array('combinator' =>
$combinator, 'name' =>
'');
else if ('"' ==
$selector[$i])
$token['name'] .=
$selector[$i];
$quoted =
$quoted ?
false :
true;
$token['name'] .=
$selector[$i];
Documentation generated on Sun, 04 May 2008 09:21:24 -0500 by phpDocumentor 1.3.0