diff -u b/composer.lock b/composer.lock --- b/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "38a1b76a4048e05502ddd122630dff3f", + "hash": "f42dce2268b1a6fcf8ffc8720c45f28f", "packages": [ { "name": "doctrine/annotations", @@ -2590,8 +2590,7 @@ "minimum-stability": "stable", "stability-flags": { "doctrine/common": 20, - "phpunit/phpunit-mock-objects": 20, - "masterminds/html5": 20 + "phpunit/phpunit-mock-objects": 20 }, "prefer-stable": false, "platform": { @@ -2660,7 +2659,8 @@ "minimum-stability": "stable", "stability-flags": { "doctrine/common": 20, - "phpunit/phpunit-mock-objects": 20 + "phpunit/phpunit-mock-objects": 20, + "masterminds/html5": 20 }, "prefer-stable": false, "prefer-lowest": false, diff -u b/core/lib/Drupal/Component/Utility/Html.php b/core/lib/Drupal/Component/Utility/Html.php --- b/core/lib/Drupal/Component/Utility/Html.php +++ b/core/lib/Drupal/Component/Utility/Html.php @@ -276,7 +276,7 @@ $document = << - + !html EOD; @@ -317,7 +317,7 @@ } $html5 = new HTML5(); foreach ($body_node->childNodes as $node) { - $html .= $html5->saveHTML($node, ['encode_entities' => FALSE]); + $html .= $html5->saveHTML($node); } return $html; } diff -u b/core/lib/Drupal/Component/XpathHelper/Lexer.php b/core/lib/Drupal/Component/XpathHelper/Lexer.php --- b/core/lib/Drupal/Component/XpathHelper/Lexer.php +++ b/core/lib/Drupal/Component/XpathHelper/Lexer.php @@ -71,7 +71,7 @@ * @param string $expression * An XPath expression. * - * @return []string + * @return array * A list of tokens from the XPath expression. */ public function lex($expression) { diff -u b/core/lib/Drupal/Component/XpathHelper/Namespacer.php b/core/lib/Drupal/Component/XpathHelper/Namespacer.php --- b/core/lib/Drupal/Component/XpathHelper/Namespacer.php +++ b/core/lib/Drupal/Component/XpathHelper/Namespacer.php @@ -7,6 +7,8 @@ namespace Drupal\Component\XpathHelper; +use Drupal\Component\XpathHelper\Lexer; + /** * XPath expressions namespacer. * diff -u b/core/modules/filter/src/Tests/FilterUnitTest.php b/core/modules/filter/src/Tests/FilterUnitTest.php --- b/core/modules/filter/src/Tests/FilterUnitTest.php +++ b/core/modules/filter/src/Tests/FilterUnitTest.php @@ -890,9 +890,8 @@ $f = Html::normalize('
'); $this->assertEqual($f, '
', "HTML corrector -- Do not transform empty tags to a single closed tag if the tag's content model is not EMPTY."); - // @todo Blocked on https://github.com/Masterminds/html5-php/issues/68 - //$f = Html::normalize('

line1


line2

'); - //$this->assertEqual($f, '

line1


line2', 'HTML corrector -- Move non-inline elements outside of inline containers.'); + $f = Html::normalize('

line1


line2

'); + $this->assertEqual($f, '

line1


line2', 'HTML corrector -- Move non-inline elements outside of inline containers.'); $f = Html::normalize('

line1

line2

'); $this->assertEqual($f, '

line1

line2
', 'HTML corrector -- Move non-inline elements outside of inline containers.'); diff -u b/core/modules/simpletest/src/AssertContentTrait.php b/core/modules/simpletest/src/AssertContentTrait.php --- b/core/modules/simpletest/src/AssertContentTrait.php +++ b/core/modules/simpletest/src/AssertContentTrait.php @@ -218,14 +218,6 @@ protected function xpath($xpath, array $arguments = array()) { if ($this->parse()) { $xpath = $this->buildXPathQuery($xpath, $arguments); - - // Register the default namespace if it exists. - $namespaces = $this->elements->getDocNamespaces(); - if (!empty($namespaces[''])) { - $xpath = $this->prefixXpath($xpath); - $this->elements->registerXPathNamespace('x', $namespaces['']); - } - $result = $this->elements->xpath($xpath); // Some combinations of PHP / libxml versions return an empty array // instead of the documented FALSE. Forcefully convert any falsish values @@ -236,6 +228,14 @@ protected function xpath($xpath, array $arguments = array()) { if ($this->parse()) { $xpath = $this->buildXPathQuery($xpath, $arguments); + + // Register the default namespace if it exists. + $namespaces = $this->elements->getDocNamespaces(); + if (!empty($namespaces[''])) { + $xpath = $this->prefixXpath($xpath); + $this->elements->registerXPathNamespace('x', $namespaces['']); + } + $result = $this->elements->xpath($xpath); // Some combinations of PHP / libxml versions return an empty array // instead of the documented FALSE. Forcefully convert any falsish values diff -u b/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php --- b/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -1834,8 +1834,8 @@ ); // DOM can load HTML soup. But, HTML soup can throw warnings, suppress // them. - $html5 = new HTML5(); - $dom = $html5->loadHTML($content); + $dom = new \DOMDocument(); + @$dom->loadHTML($content); // XPath allows for finding wrapper nodes better than DOM does. $xpath = new \DOMXPath($dom); foreach ($ajax_response as $command) { @@ -1851,8 +1851,8 @@ ); // DOM can load HTML soup. But, HTML soup can throw warnings, suppress // them. - $dom = new \DOMDocument(); - @$dom->loadHTML($content); + $html5 = new HTML5(); + $dom = $html5->loadHTML($content); // XPath allows for finding wrapper nodes better than DOM does. $xpath = new \DOMXPath($dom); foreach ($ajax_response as $command) { @@ -1860,11 +1860,12 @@ // and 'body', since these are used by // \Drupal\Core\Ajax\AjaxResponse::ajaxRender(). elseif (in_array($command['selector'], array('head', 'body'))) { - $wrapperNode = $xpath->query($this->localizeXpath('//' . $command['selector']))->item(0); + $wrapperNode = $xpath->query('//' . $command['selector'])->item(0); } if ($wrapperNode) { // ajax.js adds an enclosing DIV to work around a Safari bug. - $newDom = $html5->loadHTML('
' . trim($command['data']) . '
'); + $newDom = new \DOMDocument(); + @$newDom->loadHTML('
' . $command['data'] . '
'); $newNode = $dom->importNode($newDom->documentElement->firstChild->firstChild, TRUE); $method = isset($command['method']) ? $command['method'] : $ajax_settings['method']; // The "method" is a jQuery DOM manipulation function. Emulate @@ -1876,12 +1877,11 @@ // and 'body', since these are used by // \Drupal\Core\Ajax\AjaxResponse::ajaxRender(). elseif (in_array($command['selector'], array('head', 'body'))) { - $wrapperNode = $xpath->query('//' . $command['selector'])->item(0); + $wrapperNode = $xpath->query($this->localizeXpath('//' . $command['selector']))->item(0); } if ($wrapperNode) { // ajax.js adds an enclosing DIV to work around a Safari bug. - $newDom = new \DOMDocument(); - @$newDom->loadHTML('
' . $command['data'] . '
'); + $newDom = $html5->loadHTML('
' . trim($command['data']) . '
'); $newNode = $dom->importNode($newDom->documentElement->firstChild->firstChild, TRUE); $method = isset($command['method']) ? $command['method'] : $ajax_settings['method']; // The "method" is a jQuery DOM manipulation function. Emulate @@ -1914,14 +1914,14 @@ case 'add_css': break; case 'update_build_id': - $buildId = $xpath->query($this->localizeXpath('//input[@name="form_build_id" and @value="' . $command['old'] . '"]'))->item(0); + $buildId = $xpath->query('//input[@name="form_build_id" and @value="' . $command['old'] . '"]')->item(0); if ($buildId) { $buildId->setAttribute('value', $command['new']); } break; } } - $content = $html5->saveHTML($dom); + $content = $dom->saveHTML(); $this->setRawContent($content); $this->setDrupalSettings($drupal_settings); } @@ -1931,14 +1931,14 @@ case 'add_css': break; case 'update_build_id': - $buildId = $xpath->query('//input[@name="form_build_id" and @value="' . $command['old'] . '"]')->item(0); + $buildId = $xpath->query($this->localizeXpath('//input[@name="form_build_id" and @value="' . $command['old'] . '"]'))->item(0); if ($buildId) { $buildId->setAttribute('value', $command['new']); } break; } } - $content = $dom->saveHTML(); + $content = $html5->saveHTML($dom); $this->setRawContent($content); $this->setDrupalSettings($drupal_settings); } @@ -2044,11 +2044,11 @@ */ protected function checkForMetaRefresh() { if (strpos($this->getRawContent(), 'parse()) { - preg_match('||', $this->getRawContent(), $matches); - if ($matches) { + $refresh = $this->xpath('//meta[@http-equiv="Refresh"]'); + if (!empty($refresh)) { // Parse the content attribute of the meta tag for the format: // "[delay]: URL=[page_to_redirect_to]". - if (preg_match('/\d+;\s*URL=(?.*)/i', $matches[1], $match)) { + if (preg_match('/\d+;\s*URL=(?.*)/i', $refresh[0]['content'], $match)) { return $this->drupalGet($this->getAbsoluteUrl(String::decodeEntities($match['url']))); } } @@ -2061,11 +2061,11 @@ */ protected function checkForMetaRefresh() { if (strpos($this->getRawContent(), 'parse()) { - $refresh = $this->xpath('//meta[@http-equiv="Refresh"]'); - if (!empty($refresh)) { + preg_match('||', $this->getRawContent(), $matches); + if ($matches) { // Parse the content attribute of the meta tag for the format: // "[delay]: URL=[page_to_redirect_to]". - if (preg_match('/\d+;\s*URL=(?.*)/i', $refresh[0]['content'], $match)) { + if (preg_match('/\d+;\s*URL=(?.*)/i', $matches[1], $match)) { return $this->drupalGet($this->getAbsoluteUrl(String::decodeEntities($match['url']))); } } @@ -2106,7 +2106,7 @@ */ protected function handleForm(&$post, &$edit, &$upload, $submit, $form) { // Retrieve the form elements. - $elements = $form->xpath($this->localizeXpath('.//input[not(@disabled)]|.//textarea[not(@disabled)]|.//select[not(@disabled)]')); + $elements = $form->xpath('.//input[not(@disabled)]|.//textarea[not(@disabled)]|.//select[not(@disabled)]'); $submit_matches = FALSE; foreach ($elements as $element) { // SimpleXML objects need string casting all the time. @@ -2123,7 +2123,7 @@ */ protected function handleForm(&$post, &$edit, &$upload, $submit, $form) { // Retrieve the form elements. - $elements = $form->xpath('.//input[not(@disabled)]|.//textarea[not(@disabled)]|.//select[not(@disabled)]'); + $elements = $form->xpath($this->localizeXpath('.//input[not(@disabled)]|.//textarea[not(@disabled)]|.//select[not(@disabled)]')); $submit_matches = FALSE; foreach ($elements as $element) { // SimpleXML objects need string casting all the time. diff -u b/core/tests/Drupal/Tests/Component/XpathHelper/LexerTest.php b/core/tests/Drupal/Tests/Component/XpathHelper/LexerTest.php --- b/core/tests/Drupal/Tests/Component/XpathHelper/LexerTest.php +++ b/core/tests/Drupal/Tests/Component/XpathHelper/LexerTest.php @@ -11,19 +11,21 @@ /** * @covers \Drupal\Component\XpathHelper\Lexer - * @group Namespacer + * @group XpathHelper */ class LexerTest extends \PHPUnit_Framework_TestCase { /** - * @dataProvider xpathProvider + * @dataProvider providerLexer + * @param $expected + * @param $input */ - public function test($input, $output) { + public function testLexer($expected, $input) { $lexer = new Lexer(); - $this->assertSame($output, $lexer->lex($input)); + $this->assertSame($input, $lexer->lex($expected)); } - public function xpathProvider() { + public function providerLexer() { return [ ['cat', ['cat']], ['/cow/barn', ['/', 'cow', '/', 'barn']], diff -u b/core/tests/Drupal/Tests/Component/XpathHelper/NamespacerTest.php b/core/tests/Drupal/Tests/Component/XpathHelper/NamespacerTest.php --- b/core/tests/Drupal/Tests/Component/XpathHelper/NamespacerTest.php +++ b/core/tests/Drupal/Tests/Component/XpathHelper/NamespacerTest.php @@ -11,26 +11,26 @@ /** * @covers \Drupal\Component\XpathHelper\Namespacer - * @group Namespacer + * @group XpathHelper */ class NamespacerTest extends \PHPUnit_Framework_TestCase { /** - * @dataProvider xpathProvider + * @dataProvider providerNamespacer + * @param $expected + * @param $input */ - public function test($input, $output) { - $this->assertSame($output, Namespacer::prefix($input)); + public function testNamespacer($expected, $input) { + $this->assertSame($input, Namespacer::prefix($expected)); } public function testCache() { $this->assertSame('x:a', Namespacer::prefix('a')); - $this->assertSame('x:a', Namespacer::prefix('a')); $this->assertSame('*[local-name() = "a"]', Namespacer::localize('a')); - $this->assertSame('*[local-name() = "a"]', Namespacer::localize('a')); } - public function xpathProvider() { + public function providerNamespacer() { $tests = [ ['cow', 'x:cow'], ['/cow/barn', '/x:cow/x:barn'], reverted: --- b/core/vendor/composer/ClassLoader.php +++ a/core/vendor/composer/ClassLoader.php @@ -56,7 +56,10 @@ public function getPrefixes() { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + return array(); - return call_user_func_array('array_merge', $this->prefixesPsr0); } public function getPrefixesPsr4() diff -u b/core/vendor/composer/installed.json b/core/vendor/composer/installed.json --- b/core/vendor/composer/installed.json +++ b/core/vendor/composer/installed.json @@ -2604,71 +2604,4 @@ "description": "Symfony Yaml Component", "homepage": "http://symfony.com" - }, - { - "name": "masterminds/html5", - "version": "dev-master", - "version_normalized": "9999999-dev", - "source": { - "type": "git", - "url": "https://github.com/Masterminds/html5-php.git", - "reference": "b39dd885966dea2d3d33509af505f4ecef2f6343" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/b39dd885966dea2d3d33509af505f4ecef2f6343", - "reference": "b39dd885966dea2d3d33509af505f4ecef2f6343", - "shasum": "" - }, - "require": { - "ext-libxml": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "4.*", - "sami/sami": "~2.0", - "satooshi/php-coveralls": "0.6.*" - }, - "time": "2014-12-02 02:51:14", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Masterminds\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matt Butcher", - "email": "technosophos@gmail.com" - }, - { - "name": "Asmir Mustafic", - "email": "goetas@gmail.com" - }, - { - "name": "Matt Farina", - "email": "matt@mattfarina.com" - } - ], - "description": "An HTML5 parser and serializer.", - "homepage": "http://masterminds.github.io/html5-php", - "keywords": [ - "HTML5", - "dom", - "html", - "parser", - "querypath", - "serializer", - "xml" - ] } ] @@ -2742,4 +2675,71 @@ "zf2" ] + }, + { + "name": "masterminds/html5", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "b39dd885966dea2d3d33509af505f4ecef2f6343" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/b39dd885966dea2d3d33509af505f4ecef2f6343", + "reference": "b39dd885966dea2d3d33509af505f4ecef2f6343", + "shasum": "" + }, + "require": { + "ext-libxml": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "sami/sami": "~2.0", + "satooshi/php-coveralls": "0.6.*" + }, + "time": "2014-12-02 02:51:14", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ] } ]