diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php
index 50f00c1ff7..28e3cbee59 100644
--- a/src/Symfony/Component/DomCrawler/Crawler.php
+++ b/src/Symfony/Component/DomCrawler/Crawler.php
@@ -23,21 +23,27 @@ use Symfony\Component\CssSelector\CssSelector;
class Crawler extends \SplObjectStorage
{
/**
- * @var string The current URI or the base href value
+ * @var string The current URI
*/
protected $uri;
+ /**
+ * @var string The base href value
+ */
+ private $baseHref;
+
/**
* Constructor.
*
* @param mixed $node A Node to use as the base for the crawling
- * @param string $uri The current URI or the base href value
- *
+ * @param string $currentUri The current URI
+ * @param string $baseHref The base href value
* @api
*/
- public function __construct($node = null, $uri = null)
+ public function __construct($node = null, $currentUri = null, $baseHref = null)
{
- $this->uri = $uri;
+ $this->uri = $currentUri;
+ $this->baseHref = $baseHref ?: $currentUri;
$this->add($node);
}
@@ -176,13 +182,13 @@ class Crawler extends \SplObjectStorage
$baseHref = current($base);
if (count($base) && !empty($baseHref)) {
- if ($this->uri) {
+ if ($this->baseHref) {
$linkNode = $dom->createElement('a');
$linkNode->setAttribute('href', $baseHref);
- $link = new Link($linkNode, $this->uri);
- $this->uri = $link->getUri();
+ $link = new Link($linkNode, $this->baseHref);
+ $this->baseHref = $link->getUri();
} else {
- $this->uri = $baseHref;
+ $this->baseHref = $baseHref;
}
}
}
@@ -294,11 +300,11 @@ class Crawler extends \SplObjectStorage
{
foreach ($this as $i => $node) {
if ($i == $position) {
- return new static($node, $this->uri);
+ return new static($node, $this->uri, $this->baseHref);
}
}
- return new static(null, $this->uri);
+ return new static(null, $this->uri, $this->baseHref);
}
/**
@@ -323,7 +329,7 @@ class Crawler extends \SplObjectStorage
{
$data = array();
foreach ($this as $i => $node) {
- $data[] = $closure(new static($node, $this->uri), $i);
+ $data[] = $closure(new static($node, $this->uri, $this->baseHref), $i);
}
return $data;
@@ -344,12 +350,12 @@ class Crawler extends \SplObjectStorage
{
$nodes = array();
foreach ($this as $i => $node) {
- if (false !== $closure(new static($node, $this->uri), $i)) {
+ if (false !== $closure(new static($node, $this->uri, $this->baseHref), $i)) {
$nodes[] = $node;
}
}
- return new static($nodes, $this->uri);
+ return new static($nodes, $this->uri, $this->baseHref);
}
/**
@@ -391,7 +397,7 @@ class Crawler extends \SplObjectStorage
throw new \InvalidArgumentException('The current node list is empty.');
}
- return new static($this->sibling($this->getNode(0)->parentNode->firstChild), $this->uri);
+ return new static($this->sibling($this->getNode(0)->parentNode->firstChild), $this->uri, $this->baseHref);
}
/**
@@ -409,7 +415,7 @@ class Crawler extends \SplObjectStorage
throw new \InvalidArgumentException('The current node list is empty.');
}
- return new static($this->sibling($this->getNode(0)), $this->uri);
+ return new static($this->sibling($this->getNode(0)), $this->uri, $this->baseHref);
}
/**
@@ -427,7 +433,7 @@ class Crawler extends \SplObjectStorage
throw new \InvalidArgumentException('The current node list is empty.');
}
- return new static($this->sibling($this->getNode(0), 'previousSibling'), $this->uri);
+ return new static($this->sibling($this->getNode(0), 'previousSibling'), $this->uri, $this->baseHref);
}
/**
@@ -454,7 +460,7 @@ class Crawler extends \SplObjectStorage
}
}
- return new static($nodes, $this->uri);
+ return new static($nodes, $this->uri, $this->baseHref);
}
/**
@@ -474,7 +480,7 @@ class Crawler extends \SplObjectStorage
$node = $this->getNode(0)->firstChild;
- return new static($node ? $this->sibling($node) : array(), $this->uri);
+ return new static($node ? $this->sibling($node) : array(), $this->uri, $this->baseHref);
}
/**
@@ -601,7 +607,7 @@ class Crawler extends \SplObjectStorage
// If we dropped all expressions in the XPath while preparing it, there would be no match
if ('' === $xpath) {
- return new static(null, $this->uri);
+ return new static(null, $this->uri, $this->baseHref);
}
return $this->filterRelativeXPath($xpath);
@@ -687,7 +693,7 @@ class Crawler extends \SplObjectStorage
$node = $this->getNode(0);
- return new Link($node, $this->uri, $method);
+ return new Link($node, $this->baseHref, $method);
}
/**
@@ -701,7 +707,7 @@ class Crawler extends \SplObjectStorage
{
$links = array();
foreach ($this as $node) {
- $links[] = new Link($node, $this->uri, 'get');
+ $links[] = new Link($node, $this->baseHref, 'get');
}
return $links;
@@ -792,7 +798,7 @@ class Crawler extends \SplObjectStorage
*/
private function filterRelativeXPath($xpath)
{
- $crawler = new static(null, $this->uri);
+ $crawler = new static(null, $this->uri, $this->baseHref);
foreach ($this as $node) {
$domxpath = new \DOMXPath($node->ownerDocument);
diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
index 4d4c5ac2a1..e019ca95ef 100644
--- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
+++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
@@ -824,16 +824,33 @@ HTML;
}
}
- public function testBaseTag()
+ /**
+ * @dataProvider getBaseTagData
+ */
+ public function testBaseTag($baseValue, $linkValue, $expectedUri, $currentUri = null, $description = null)
{
- $crawler = new Crawler('