From 0b4ffca58e63d16d0f31d67c70eb18fa4a38500f Mon Sep 17 00:00:00 2001 From: Ivo Petkov Date: Mon, 29 Aug 2016 19:19:54 +0300 Subject: [PATCH] Added 2 new querySelectors (tagName.className and tagName#id). --- src/HTML5DOMDocument.php | 23 +++++++++++++++++++++-- tests/Test.php | 14 +++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/HTML5DOMDocument.php b/src/HTML5DOMDocument.php index 3c99cd6..81e7808 100644 --- a/src/HTML5DOMDocument.php +++ b/src/HTML5DOMDocument.php @@ -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); diff --git a/tests/Test.php b/tests/Test.php index 71f208d..6fc088d 100644 --- a/tests/Test.php +++ b/tests/Test.php @@ -246,21 +246,29 @@ public function testQuerySelector() $dom = new HTML5DOMDocument(); $dom->loadHTML('' - . '
text1
' + . '
text1
' . '
text2
' . '
' - . '
text3
' + . '
text3
' . '
' + . 'text4' . ''); $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);