Diff
Modified: trunk/LayoutTests/ChangeLog (208921 => 208922)
--- trunk/LayoutTests/ChangeLog 2016-11-19 07:35:47 UTC (rev 208921)
+++ trunk/LayoutTests/ChangeLog 2016-11-19 08:02:03 UTC (rev 208922)
@@ -1,3 +1,21 @@
+2016-11-19 Ryosuke Niwa <[email protected]>
+
+ REGRESSION(r200964): Tab focus navigation is broken on results.en.voyages-sncf.com
+ https://bugs.webkit.org/show_bug.cgi?id=164888
+
+ Reviewed by Antti Koivisto.
+
+ Add regression tests for moving the focus across a shadow tree and a SVG use element
+ and the one that moves out of a slot element.
+
+ * fast/shadow-dom/focus-navigation-out-of-slot-expected.txt: Added.
+ * fast/shadow-dom/focus-navigation-out-of-slot.html: Added.
+ * fast/shadow-dom/focus-navigation-passes-shadow-host-expected.txt: Added.
+ * fast/shadow-dom/focus-navigation-passes-shadow-host.html: Added.
+ * fast/shadow-dom/focus-navigation-passes-svg-use-element-expected.txt: Added.
+ * fast/shadow-dom/focus-navigation-passes-svg-use-element.html: Added.
+ * platform/ios-simulator/TestExpectations: Skip the newly added tests on iOS.
+
2016-11-18 Simon Fraser <[email protected]>
[iOS WK2] Eliminate a source of flakiness in layout tests by forcing WebPage into "responsive" mode for all tests, with an internals override
Added: trunk/LayoutTests/fast/shadow-dom/copy-shadow-tree.html-disabled (0 => 208922)
--- trunk/LayoutTests/fast/shadow-dom/copy-shadow-tree.html-disabled (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/copy-shadow-tree.html-disabled 2016-11-19 08:02:03 UTC (rev 208922)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests copying the content inside a shadow tree.<br>
+To manually test, copy the selected content and paste it below:</p>
+<style>
+#source, #destination {
+ border: solid 1px #666;
+ margin: 1rem 0;
+}
+</style>
+<div id="source">
+ <b>hello,
+ <span id="host"><span slot="webkit">WebKit</span> <span slot="others">and other engines</slot></span>
+ </b>
+ <i>rocks</i>
+</div>
+<div id="destination" contenteditable><br></div>
+<script>
+
+document.getElementById('host').attachShadow({mode: 'closed'}).innerHTML = 'world <slot name="webkit"></slot>';
+getSelection().selectAllChildren(document.getElementById('source'));
+
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/focus-navigation-out-of-slot-expected.txt (0 => 208922)
--- trunk/LayoutTests/fast/shadow-dom/focus-navigation-out-of-slot-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/focus-navigation-out-of-slot-expected.txt 2016-11-19 08:02:03 UTC (rev 208922)
@@ -0,0 +1,4 @@
+This tests moving a focus across slotted input elements. To test manually, press Tab key to move the focus from the first input element to the next.
+
+
+PASS
Added: trunk/LayoutTests/fast/shadow-dom/focus-navigation-out-of-slot.html (0 => 208922)
--- trunk/LayoutTests/fast/shadow-dom/focus-navigation-out-of-slot.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/focus-navigation-out-of-slot.html 2016-11-19 08:02:03 UTC (rev 208922)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests moving a focus across slotted input elements.
+To test manually, press Tab key to move the focus from the first input element to the next.</p>
+<div id="host">
+ <input id="first" slot="x">
+ <input id="second" slot="y">
+</div>
+<div id="result">FAIL</div>
+<script>
+
+document.getElementById('host').attachShadow({mode: 'closed'}).innerHTML = `
+<div><slot name=x></slot></div>
+<div><slot name=y></slot></div>`;
+
+document.getElementById('first').focus();
+const resultElement = document.getElementById('result');
+const secondInputElement = document.getElementById('second');
+
+if (window.eventSender) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+
+ eventSender.keyDown('\t');
+ setTimeout(() => {
+ resultElement.textContent = document.activeElement == secondInputElement ? 'PASS' : 'FAIL'
+ testRunner.notifyDone();
+ }, 1);
+}
+
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-shadow-host-expected.txt (0 => 208922)
--- trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-shadow-host-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-shadow-host-expected.txt 2016-11-19 08:02:03 UTC (rev 208922)
@@ -0,0 +1,5 @@
+This tests moving a focus across slotted input elements. To test manually, press Tab key to move the focus from the first input element to the next.
+
+
+
+PASS
Added: trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-shadow-host.html (0 => 208922)
--- trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-shadow-host.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-shadow-host.html 2016-11-19 08:02:03 UTC (rev 208922)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests moving a focus across slotted input elements.
+To test manually, press Tab key to move the focus from the first input element to the next.</p>
+<div>
+ <div><input id="first"> <span></span></div>
+ <div><input id="second"></div>
+</div>
+<div id="result">FAIL</div>
+<script>
+
+document.querySelector('span').attachShadow({mode: 'closed'}).innerHTML = '';
+
+document.getElementById('first').focus();
+const resultElement = document.getElementById('result');
+const secondInputElement = document.getElementById('second');
+
+if (window.eventSender) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+
+ eventSender.keyDown('\t');
+ setTimeout(() => {
+ resultElement.textContent = document.activeElement == secondInputElement ? 'PASS' : 'FAIL'
+ testRunner.notifyDone();
+ }, 1);
+}
+
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-svg-use-element-expected.txt (0 => 208922)
--- trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-svg-use-element-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-svg-use-element-expected.txt 2016-11-19 08:02:03 UTC (rev 208922)
@@ -0,0 +1,5 @@
+This tests moving a focus across slotted input elements. To test manually, press Tab key to move the focus from the first input element to the next.
+
+
+
+PASS
Added: trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-svg-use-element.html (0 => 208922)
--- trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-svg-use-element.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/focus-navigation-passes-svg-use-element.html 2016-11-19 08:02:03 UTC (rev 208922)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests moving a focus across slotted input elements.
+To test manually, press Tab key to move the focus from the first input element to the next.</p>
+<style> svg { width: 10px; height: 10px; } </style>
+<div>
+ <div><input id="first" value="hello"> <svg><use xlink:href=""
+ <div><input id="second" value="world"> <svg id="foo"><circle cx=5 cy=5 r=5></svg></div>
+</div>
+<div id="result">FAIL</div>
+<script>
+
+document.getElementById('first').focus();
+const resultElement = document.getElementById('result');
+const secondInputElement = document.getElementById('second');
+
+if (window.eventSender) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+
+ eventSender.keyDown('\t');
+ setTimeout(() => {
+ resultElement.textContent = document.activeElement == secondInputElement ? 'PASS' : 'FAIL'
+ testRunner.notifyDone();
+ }, 1);
+}
+
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (208921 => 208922)
--- trunk/LayoutTests/platform/ios-simulator/TestExpectations 2016-11-19 07:35:47 UTC (rev 208921)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations 2016-11-19 08:02:03 UTC (rev 208922)
@@ -328,6 +328,9 @@
fast/shadow-dom/focus-on-iframe.html [ Failure ]
webkit.org/b/116046 fast/events/sequential-focus-navigation-starting-point.html [ Skip ]
webkit.org/b/159240 fast/events/remove-focus-navigation-starting-point-crash.html [ Skip ]
+webkit.org/b/164888 fast/shadow-dom/focus-navigation-out-of-slot.html [ Skip ]
+webkit.org/b/164888 fast/shadow-dom/focus-navigation-passes-shadow-host.html [ Skip ]
+webkit.org/b/164888 fast/shadow-dom/focus-navigation-passes-svg-use-element.html [ Skip ]
# This test needs to be rewritten to use runUIScript to work on iOS
webkit.org/b/152993 http/tests/contentdispositionattachmentsandbox/form-submission-disabled.html [ Skip ]
Modified: trunk/Source/WebCore/ChangeLog (208921 => 208922)
--- trunk/Source/WebCore/ChangeLog 2016-11-19 07:35:47 UTC (rev 208921)
+++ trunk/Source/WebCore/ChangeLog 2016-11-19 08:02:03 UTC (rev 208922)
@@ -1,3 +1,21 @@
+2016-11-19 Ryosuke Niwa <[email protected]>
+
+ REGRESSION(r200964): Tab focus navigation is broken on results.en.voyages-sncf.com
+ https://bugs.webkit.org/show_bug.cgi?id=164888
+
+ Reviewed by Antti Koivisto.
+
+ The bug was caused by FocusNavigationScope::parentInScope incorrectly returning nullptr when moving out of
+ a user agent shadow tree of a SVG use element. Fixed the bug by explicitly checking against the focus scope's
+ root node or its slot element. Also removed a superfluous early return when the parent node is a focus scope.
+
+ Tests: fast/shadow-dom/focus-navigation-out-of-slot.html
+ fast/shadow-dom/focus-navigation-passes-shadow-host.html
+ fast/shadow-dom/focus-navigation-passes-svg-use-element.html
+
+ * page/FocusController.cpp:
+ (WebCore::FocusNavigationScope::parentInScope):
+
2016-11-18 Simon Fraser <[email protected]>
[iOS WK2] Eliminate a source of flakiness in layout tests by forcing WebPage into "responsive" mode for all tests, with an internals override
Modified: trunk/Source/WebCore/page/FocusController.cpp (208921 => 208922)
--- trunk/Source/WebCore/page/FocusController.cpp 2016-11-19 07:35:47 UTC (rev 208921)
+++ trunk/Source/WebCore/page/FocusController.cpp 2016-11-19 08:02:03 UTC (rev 208922)
@@ -130,17 +130,13 @@
Node* FocusNavigationScope::parentInScope(const Node& node) const
{
- if (is<Element>(node) && isFocusScopeOwner(downcast<Element>(node)))
+ if (m_rootTreeScope && &m_rootTreeScope->rootNode() == &node)
return nullptr;
if (UNLIKELY(m_slotElement && m_slotElement == node.assignedSlot()))
return nullptr;
- ContainerNode* parent = node.parentNode();
- if (parent && is<Element>(parent) && isFocusScopeOwner(downcast<Element>(*parent)))
- return nullptr;
-
- return parent;
+ return node.parentNode();
}
Node* FocusNavigationScope::nextSiblingInScope(const Node& node) const