.../CurrentPathDestinationLinkResponseFilter.php | 1 + ...urrentPathDestinationLinkResponseFilterTest.php | 127 +++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/core/lib/Drupal/Core/EventSubscriber/CurrentPathDestinationLinkResponseFilter.php b/core/lib/Drupal/Core/EventSubscriber/CurrentPathDestinationLinkResponseFilter.php index 8feb9da..2569f1c 100644 --- a/core/lib/Drupal/Core/EventSubscriber/CurrentPathDestinationLinkResponseFilter.php +++ b/core/lib/Drupal/Core/EventSubscriber/CurrentPathDestinationLinkResponseFilter.php @@ -127,6 +127,7 @@ public static function setCurrentPathAsDestination($html_markup, $current_path) $url = $node->getAttribute('href'); $glue = (strpos($url, '?') === FALSE) ? '?' : '&'; $node->setAttribute('href', $url . $glue . $destination); + $node->removeAttribute('data-current-path-destination'); // Get the updated tag. $updated_tag = $dom->saveXML($node, LIBXML_NOEMPTYTAG); diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/CurrentPathDestinationLinkResponseFilterTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/CurrentPathDestinationLinkResponseFilterTest.php new file mode 100644 index 0000000..4ecfa4e --- /dev/null +++ b/core/tests/Drupal/Tests/Core/EventSubscriber/CurrentPathDestinationLinkResponseFilterTest.php @@ -0,0 +1,127 @@ + + + +'; + $html = [ + // Simple HTML. + 0 => ['prefix' => '

', 'suffix' => '

'], + // Tricky HTML5 example that's unsupported by PHP <=5.4's DOMDocument: + // https://www.drupal.org/comment/7938201#comment-7938201. + 1 => ['prefix' => '

', 'suffix' => '

' . $edge_case_html5 . '
'], + // Multi-byte content *before* the HTML that needs the "destination" query + // string. + 2 => ['prefix' => '

αβγδεζηθικλμνξοσὠ

', 'suffix' => '

'], + ]; + $tags = [ + // Of course, it must work on anchors. + 'a', + // … but it should work, on *any* tag, really. + 'foo', + ]; + $contents = [ + // Regular content. + 'test', + // Mix of UTF-8 and HTML entities, both must be retained. + '☆ 3 × 4 = €12 and 4 × 3 = €12 ☆', + // Multi-byte content. + 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', + ]; + $situations = [ + // Without a "data-current-path-destination" attribute present, nothing + // happens. + 0 => ['path' => 'foo', 'attributes' => ['href' => '/some/path'], 'expected href' => '/some/path'], + // With a "data-current-path-destination" attribute present, the + // "destination" query string is added. + 1 => ['path' => 'foo', 'attributes' => ['href' => '/some/path', 'data-current-path-destination' => TRUE], 'expected href' => '/some/path?destination=foo'], + // With a "data-current-path-destination" attribute present on a link that + // already has a "destination" query string, we just append it. We do not + // babysit broken code in CurrentPathDestinationLinkResponseFilter. + 2 => ['path' => 'foo', 'attributes' => ['href' => '/some/path?destination=/already/there', 'data-current-path-destination' => TRUE], 'expected href' => '/some/path?destination=/already/there&destination=foo'], + ]; + + // Loop over the surrounding HTML variations. + $data = []; + for ($h = 0; $h < count($html); $h++) { + $html_prefix = $html[$h]['prefix']; + $html_suffix = $html[$h]['suffix']; + // Loop over the tag variations. + for ($t = 0; $t < count($tags); $t++) { + $tag = $tags[$t]; + // Loop over the tag contents variations. + for ($c = 0; $c < count($contents); $c++) { + $tag_content = $contents[$c]; + + $create_markup = function (Attribute $attributes) use ($html_prefix, $html_suffix, $tag, $tag_content) { + return $html_prefix . '<' . $tag . $attributes . '>' . $tag_content . '' . $html_suffix; + }; + + // Loop over the situations. + for ($s = 0; $s < count($situations); $s++) { + $situation = $situations[$s]; + + // Build the source markup. + $source_markup = $create_markup(new Attribute($situation['attributes'])); + + // Build the target markup. + $active_attributes = $situation['attributes']; + $active_attributes['href'] = $situation['expected href']; + unset($active_attributes['data-current-path-destination']); + $target_markup = $create_markup(new Attribute($active_attributes)); + + $data[] = [$source_markup, $situation['path'], $target_markup]; + } + } + } + } + + return $data; + } + + /** + * Tests setCurrentPathAsDestination(). + * + * @param string $html_markup + * The original HTML markup. + * @param string $current_path + * The system path of the currently active page. + * @param string $expected_html_markup + * The expected updated HTML markup. + * + * @dataProvider providerTestSetCurrentPathAsDestination + * @covers ::setCurrentPathAsDestination + */ + public function testSetCurrentPathAsDestination($html_markup, $current_path, $expected_html_markup) { + $this->assertSame($expected_html_markup, CurrentPathDestinationLinkResponseFilter::setCurrentPathAsDestination($html_markup, $current_path)); + } + +}