diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index 5600995786c3..fc2583bcb921 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -14,7 +14,7 @@ use Symfony\Component\CssSelector\CssSelectorConverter; /** - * Crawler eases navigation of a list of \DOMElement objects. + * Crawler eases navigation of a list of \DOMNode objects. * * @author Fabien Potencier */ @@ -295,10 +295,6 @@ public function addNode(\DOMNode $node) $node = $node->documentElement; } - if (!$node instanceof \DOMElement) { - throw new \InvalidArgumentException(sprintf('Nodes set in a Crawler must be DOMElement or DOMDocument instances, "%s" given.', get_class($node))); - } - if (null !== $this->document && $this->document !== $node->ownerDocument) { throw new \InvalidArgumentException('Attaching DOM nodes from multiple documents in the same crawler is forbidden.'); } @@ -696,7 +692,7 @@ public function selectButton($value) * * @return Link A Link instance * - * @throws \InvalidArgumentException If the current node list is empty + * @throws \InvalidArgumentException If the current node list is empty or contains non-DOMElement instances */ public function link($method = 'get') { @@ -706,6 +702,10 @@ public function link($method = 'get') $node = $this->getNode(0); + if (!$node instanceof \DOMElement) { + throw new \InvalidArgumentException(sprintf('The current node list should contain only DOMElement instances, "%s" found.', get_class($node))); + } + return new Link($node, $this->baseHref, $method); } @@ -713,11 +713,17 @@ public function link($method = 'get') * Returns an array of Link objects for the nodes in the list. * * @return Link[] An array of Link instances + * + * @throws \InvalidArgumentException If the current node list contains non-DOMElement instances */ public function links() { $links = array(); foreach ($this->nodes as $node) { + if (!$node instanceof \DOMElement) { + throw new \InvalidArgumentException(sprintf('The current node list should contain only DOMElement instances, "%s" found.', get_class($node))); + } + $links[] = new Link($node, $this->baseHref, 'get'); } @@ -732,7 +738,7 @@ public function links() * * @return Form A Form instance * - * @throws \InvalidArgumentException If the current node list is empty + * @throws \InvalidArgumentException If the current node list is empty or contains non-DOMElement instances */ public function form(array $values = null, $method = null) { @@ -740,7 +746,13 @@ public function form(array $values = null, $method = null) throw new \InvalidArgumentException('The current node list is empty.'); } - $form = new Form($this->getNode(0), $this->uri, $method, $this->baseHref); + $node = $this->getNode(0); + + if (!$node instanceof \DOMElement) { + throw new \InvalidArgumentException(sprintf('The current node list should contain only DOMElement instances, "%s" found.', get_class($node))); + } + + $form = new Form($node, $this->uri, $method, $this->baseHref); if (null !== $values) { $form->setValues($values); @@ -832,12 +844,7 @@ private function filterRelativeXPath($xpath) foreach ($this->nodes as $node) { $domxpath = $this->createDOMXPath($node->ownerDocument, $prefixes); - - foreach ($domxpath->query($xpath, $node) as $subNode) { - if ($subNode->nodeType === 1) { - $crawler->add($subNode); - } - } + $crawler->add($domxpath->query($xpath, $node)); } return $crawler; diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php index 13b92fa610c7..7cc647327d17 100755 --- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php @@ -47,7 +47,7 @@ public function testAdd() $crawler = new Crawler(); $crawler->add($this->createNodeList()->item(0)); - $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->add() adds nodes from a \DOMElement'); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->add() adds nodes from a \DOMNode'); $crawler = new Crawler(); $crawler->add('Foo'); @@ -63,16 +63,6 @@ public function testAddInvalidType() $crawler->add(1); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Nodes set in a Crawler must be DOMElement or DOMDocument instances, "DOMNode" given. - */ - public function testAddInvalidNode() - { - $crawler = new Crawler(); - $crawler->add(new \DOMNode()); - } - /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Attaching DOM nodes from multiple documents in the same crawler is forbidden. @@ -274,7 +264,7 @@ public function testAddNode() $crawler = new Crawler(); $crawler->addNode($this->createNodeList()->item(0)); - $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addNode() adds nodes from a \DOMElement'); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addNode() adds nodes from a \DOMNode'); } public function testClear() @@ -527,7 +517,7 @@ public function testFilterXPathWithAttributeAxis() public function testFilterXPathWithAttributeAxisAfterElementAxis() { - $this->assertCount(0, $this->createTestCrawler()->filterXPath('//form/button/attribute::*'), '->filterXPath() handles attribute axes properly when they are preceded by an element filtering axis'); + $this->assertCount(3, $this->createTestCrawler()->filterXPath('//form/button/attribute::*'), '->filterXPath() handles attribute axes properly when they are preceded by an element filtering axis'); } public function testFilterXPathWithChildAxis() @@ -745,6 +735,26 @@ public function testLink() } } + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The current node list should contain only DOMElement instances + */ + public function testInvalidLink() + { + $crawler = $this->createTestCrawler('http://example.com/bar/'); + $crawler->filterXPath('//li/text()')->link(); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The current node list should contain only DOMElement instances + */ + public function testInvalidLinks() + { + $crawler = $this->createTestCrawler('http://example.com/bar/'); + $crawler->filterXPath('//li/text()')->link(); + } + public function testSelectLinkAndLinkFiltered() { $html = <<createTestCrawler('http://example.com/bar/'); + $crawler->filterXPath('//li/text()')->form(); + } + public function testLast() { $crawler = $this->createTestCrawler()->filterXPath('//ul[1]/li');