Skip to content

Commit

Permalink
Added 2 new querySelectors (tagName.className and tagName#id).
Browse files Browse the repository at this point in the history
  • Loading branch information
ivopetkov committed Aug 29, 2016
1 parent a1d5d99 commit 0b4ffca
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
23 changes: 21 additions & 2 deletions src/HTML5DOMDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,31 @@ public function querySelectorAll($selector)
{
if ($selector === '*') { // all
return $this->getElementsByTagName('*');
} elseif (preg_match('/^[a-z]*$/', $selector) === 1) { // tagname
} elseif (preg_match('/^[a-z]+$/', $selector) === 1) { // tagname
return $this->getElementsByTagName($selector);
} elseif (preg_match('/^[a-z]+#.+$/', $selector) === 1) { // tagname#id
$parts = explode('#', $selector, 2);
$element = $this->getElementById($parts[1]);
if ($element && $element->tagName === $parts[0]) {
return new \IvoPetkov\HTML5DOMNodeList([$element]);
}
return new \IvoPetkov\HTML5DOMNodeList();
} elseif (preg_match('/^[a-z]+\..+$/', $selector) === 1) { // tagname.classname
$parts = explode('.', $selector, 2);
$result = [];
$selectorClass = $parts[1];
$elements = $this->getElementsByTagName($parts[0]);
foreach ($elements as $element) {
$classAttribute = $element->getAttribute('class');
if ($classAttribute === $selectorClass || strpos($classAttribute, $selectorClass . ' ') === 0 || substr($classAttribute, -(strlen($selectorClass) + 1)) === ' ' . $selectorClass || strpos($classAttribute, ' ' . $selectorClass . ' ') !== false) {
$result[] = $element;
}
}
return new \IvoPetkov\HTML5DOMNodeList($result);
} elseif (substr($selector, 0, 1) === '#') { // id
$element = $this->getElementById(substr($selector, 1));
return $element !== null ? new \IvoPetkov\HTML5DOMNodeList([$element]) : new \IvoPetkov\HTML5DOMNodeList();
} elseif (substr($selector, 0, 1) === '.') { // classname
} elseif (substr($selector, 0, 1) === '.') { // .classname
$elements = $this->getElementsByTagName('*');
$result = [];
$selectorClass = substr($selector, 1);
Expand Down
14 changes: 11 additions & 3 deletions tests/Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,21 +246,29 @@ public function testQuerySelector()

$dom = new HTML5DOMDocument();
$dom->loadHTML('<html><body>'
. '<div id="text1">text1</div>'
. '<div id="text1" class="class1">text1</div>'
. '<div>text2</div>'
. '<div>'
. '<div class="text3">text3</div>'
. '<div class="text3 class1">text3</div>'
. '</div>'
. '<span id="text4" class="class1 class2">text4</div>'
. '</body></html>');

$this->assertTrue($dom->querySelector('#text1')->innerHTML === 'text1');

$this->assertTrue($dom->querySelectorAll('*')->length === 6); // html + body + 4 divs
$this->assertTrue($dom->querySelectorAll('*')->length === 7); // html + body + 4 divs + 1 span
$this->assertTrue($dom->querySelectorAll('div')->length === 4); // 4 divs
$this->assertTrue($dom->querySelectorAll('#text1')->length === 1);
$this->assertTrue($dom->querySelectorAll('#text1')->item(0)->innerHTML === 'text1');
$this->assertTrue($dom->querySelectorAll('.text3')->length === 1);
$this->assertTrue($dom->querySelectorAll('.text3')->item(0)->innerHTML === 'text3');
$this->assertTrue($dom->querySelectorAll('div#text1')->item(0)->innerHTML === 'text1');
$this->assertTrue($dom->querySelectorAll('span#text4')->item(0)->innerHTML === 'text4');
$this->assertTrue($dom->querySelectorAll('div#text4')->length === 0);
$this->assertTrue($dom->querySelectorAll('div.class1')->length === 2);
$this->assertTrue($dom->querySelectorAll('.class1')->length === 3);
$this->assertTrue($dom->querySelectorAll('div.class2')->length === 0);
$this->assertTrue($dom->querySelectorAll('span.class2')->length === 1);

$this->assertTrue($dom->querySelectorAll('unknown')->length === 0);
$this->assertTrue($dom->querySelectorAll('unknown')->item(0) === null);
Expand Down

0 comments on commit 0b4ffca

Please sign in to comment.