Revert "bug #10207 [DomCrawler] Fixed filterXPath() chaining (robbertkl)"

This reverts commit c11c5888f3, reversing
changes made to e453c4589d.
This commit is contained in:
Fabien Potencier 2014-02-18 17:26:04 +01:00
parent 2637e5555c
commit 8f379217b8
4 changed files with 34 additions and 20 deletions

View File

@ -441,7 +441,7 @@ class Crawler extends \SplObjectStorage
$nodes = array(); $nodes = array();
while ($node = $node->parentNode) { while ($node = $node->parentNode) {
if (1 === $node->nodeType) { if (1 === $node->nodeType && '_root' !== $node->nodeName) {
$nodes[] = $node; $nodes[] = $node;
} }
} }
@ -584,13 +584,15 @@ class Crawler extends \SplObjectStorage
*/ */
public function filterXPath($xpath) public function filterXPath($xpath)
{ {
$crawler = new static(null, $this->uri); $document = new \DOMDocument('1.0', 'UTF-8');
$root = $document->appendChild($document->createElement('_root'));
foreach ($this as $node) { foreach ($this as $node) {
$domxpath = new \DOMXPath($node->ownerDocument); $root->appendChild($document->importNode($node, true));
$crawler->add($domxpath->query($xpath, $node));
} }
return $crawler; $domxpath = new \DOMXPath($document);
return new static($domxpath->query($xpath), $this->uri);
} }
/** /**

View File

@ -52,7 +52,13 @@ abstract class FormField
{ {
$this->node = $node; $this->node = $node;
$this->name = $node->getAttribute('name'); $this->name = $node->getAttribute('name');
$this->xpath = new \DOMXPath($node->ownerDocument);
$this->document = new \DOMDocument('1.0', 'UTF-8');
$this->node = $this->document->importNode($this->node, true);
$root = $this->document->appendChild($this->document->createElement('_root'));
$root->appendChild($this->node);
$this->xpath = new \DOMXPath($this->document);
$this->initialize(); $this->initialize();
} }

View File

@ -378,7 +378,9 @@ class Form extends Link implements \ArrayAccess
{ {
$this->fields = new FormFieldRegistry(); $this->fields = new FormFieldRegistry();
$xpath = new \DOMXPath($this->node->ownerDocument); $document = new \DOMDocument('1.0', 'UTF-8');
$xpath = new \DOMXPath($document);
$root = $document->appendChild($document->createElement('_root'));
// add submitted button if it has a valid name // add submitted button if it has a valid name
if ('form' !== $this->button->nodeName && $this->button->hasAttribute('name') && $this->button->getAttribute('name')) { if ('form' !== $this->button->nodeName && $this->button->hasAttribute('name') && $this->button->getAttribute('name')) {
@ -388,33 +390,39 @@ class Form extends Link implements \ArrayAccess
// temporarily change the name of the input node for the x coordinate // temporarily change the name of the input node for the x coordinate
$this->button->setAttribute('name', $name.'.x'); $this->button->setAttribute('name', $name.'.x');
$this->set(new Field\InputFormField($this->button)); $this->set(new Field\InputFormField($document->importNode($this->button, true)));
// temporarily change the name of the input node for the y coordinate // temporarily change the name of the input node for the y coordinate
$this->button->setAttribute('name', $name.'.y'); $this->button->setAttribute('name', $name.'.y');
$this->set(new Field\InputFormField($this->button)); $this->set(new Field\InputFormField($document->importNode($this->button, true)));
// restore the original name of the input node // restore the original name of the input node
$this->button->setAttribute('name', $name); $this->button->setAttribute('name', $name);
} else { }
$this->set(new Field\InputFormField($this->button)); else {
$this->set(new Field\InputFormField($document->importNode($this->button, true)));
} }
} }
// find form elements corresponding to the current form // find form elements corresponding to the current form
if ($this->node->hasAttribute('id')) { if ($this->node->hasAttribute('id')) {
// traverse through the whole document
$node = $document->importNode($this->node->ownerDocument->documentElement, true);
$root->appendChild($node);
// corresponding elements are either descendants or have a matching HTML5 form attribute // corresponding elements are either descendants or have a matching HTML5 form attribute
$formId = Crawler::xpathLiteral($this->node->getAttribute('id')); $formId = Crawler::xpathLiteral($this->node->getAttribute('id'));
$fieldNodes = $xpath->query(sprintf('descendant::input[@form=%s] | descendant::button[@form=%s] | descendant::textarea[@form=%s] | descendant::select[@form=%s] | //form[@id=%s]//input[not(@form)] | //form[@id=%s]//button[not(@form)] | //form[@id=%s]//textarea[not(@form)] | //form[@id=%s]//select[not(@form)]', $formId, $formId, $formId, $formId, $formId, $formId, $formId, $formId), $root);
// do the xpath query without $this->node as the context node (i.e. traverse through the whole document)
$fieldNodes = $xpath->query(sprintf('descendant::input[@form=%s] | descendant::button[@form=%s] | descendant::textarea[@form=%s] | descendant::select[@form=%s] | //form[@id=%s]//input[not(@form)] | //form[@id=%s]//button[not(@form)] | //form[@id=%s]//textarea[not(@form)] | //form[@id=%s]//select[not(@form)]', $formId, $formId, $formId, $formId, $formId, $formId, $formId, $formId));
foreach ($fieldNodes as $node) { foreach ($fieldNodes as $node) {
$this->addField($node); $this->addField($node);
} }
} else { } else {
// do the xpath query with $this->node as the context node, to only find descendant elements // parent form has no id, add descendant elements only
// however, descendant elements with form attribute are not part of this form $node = $document->importNode($this->node, true);
$fieldNodes = $xpath->query('descendant::input[not(@form)] | descendant::button[not(@form)] | descendant::textarea[not(@form)] | descendant::select[not(@form)]', $this->node); $root->appendChild($node);
// descendant elements with form attribute are not part of this form
$fieldNodes = $xpath->query('descendant::input[not(@form)] | descendant::button[not(@form)] | descendant::textarea[not(@form)] | descendant::select[not(@form)]', $root);
foreach ($fieldNodes as $node) { foreach ($fieldNodes as $node) {
$this->addField($node); $this->addField($node);
} }

View File

@ -378,10 +378,8 @@ EOF
$this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->filterXPath() returns a new instance of a crawler'); $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->filterXPath() returns a new instance of a crawler');
$crawler = $this->createTestCrawler()->filterXPath('//ul'); $crawler = $this->createTestCrawler()->filterXPath('//ul');
$this->assertCount(6, $crawler->filterXPath('//li'), '->filterXPath() filters the node list with the XPath expression');
$crawler = $this->createTestCrawler(); $this->assertCount(6, $crawler->filterXPath('//li'), '->filterXPath() filters the node list with the XPath expression');
$this->assertCount(3, $crawler->filterXPath('//body')->filterXPath('//button')->parents(), '->filterXpath() preserves parents when chained');
} }
/** /**