Click on node assigned to slot in button's shadow cause loss of button focus
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Nov 2018 08:53:57 +0000 (08:53 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Nov 2018 08:53:57 +0000 (08:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191694
<rdar://problem/46107920>

Reviewed by Wenson Hsieh.

Source/WebCore:

Fixed the bug by traversing the parent in the composed tree when looking for an element to focus.

Test: fast/shadow-dom/focus-slot-parent.html

* page/EventHandler.cpp:
(WebCore::EventHandler::dispatchMouseEvent): Fixed the bug. Also use RefPtr instead of a raw pointer.

LayoutTests:

Added a regression test.

* fast/shadow-dom/focus-slot-parent-expected.txt: Added.
* fast/shadow-dom/focus-slot-parent.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238393 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/shadow-dom/focus-slot-parent-expected.txt [new file with mode: 0644]
LayoutTests/fast/shadow-dom/focus-slot-parent.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/EventHandler.cpp

index b98fba2..5537332 100644 (file)
@@ -1,3 +1,16 @@
+2018-11-19  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Click on node assigned to slot in button's shadow cause loss of button focus
+        https://bugs.webkit.org/show_bug.cgi?id=191694
+        <rdar://problem/46107920>
+
+        Reviewed by Wenson Hsieh.
+
+        Added a regression test.
+
+        * fast/shadow-dom/focus-slot-parent-expected.txt: Added.
+        * fast/shadow-dom/focus-slot-parent.html: Added.
+
 2018-11-19  Justin Fan  <justin_fan@apple.com>
 
         [WebGPU] Begin implementing WebGPUTexture, WebGPUTextureView, and WebGPUTextureFormatEnum, and WebGPUSwapChain::configure upgrades
diff --git a/LayoutTests/fast/shadow-dom/focus-slot-parent-expected.txt b/LayoutTests/fast/shadow-dom/focus-slot-parent-expected.txt
new file mode 100644 (file)
index 0000000..f21ef72
--- /dev/null
@@ -0,0 +1,11 @@
+This tests clicking on a slotted content would focus the ancestor of the slot element it belongs.
+To manaully test, click on "Click here" below.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS focusEventTarget is focusableSlotParent
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/shadow-dom/focus-slot-parent.html b/LayoutTests/fast/shadow-dom/focus-slot-parent.html
new file mode 100644 (file)
index 0000000..bd54462
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="host"><span onclick="checkFocusFired()">Click here</span></div>
+<script src="../../resources/js-test.js"></script>
+<script src="../../resources/ui-helper.js"></script>
+<script>
+
+description(`This tests clicking on a slotted content would focus the ancestor of the slot element it belongs.<br>
+To manaully test, click on "Click here" below.`);
+
+const shadowRoot = host.attachShadow({mode: 'closed'});
+shadowRoot.innerHTML = '<span tabindex="0"><slot></slot></span>';
+
+window.focusableSlotParent = shadowRoot.querySelector('[tabindex]');
+window.focusEventTarget = null;
+focusableSlotParent.addEventListener('focus', (event) => {
+    window.focusEventTarget = event.target;
+});
+
+function checkFocusFired()
+{
+    shouldBe('focusEventTarget', 'focusableSlotParent');
+    host.remove();
+    finishJSTest();
+}
+
+if (window.testRunner && !window.eventSender)
+    document.write('This test requires eventSender');
+else {
+    if (window.eventSender)
+        window.onload = async () => await UIHelper.activateAt(host.offsetLeft + 5, host.offsetTop + 5);
+    jsTestIsAsync = true;
+}
+
+</script>
+</body>
+</html>
index baed877..8b683e8 100644 (file)
@@ -1,3 +1,18 @@
+2018-11-19  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Click on node assigned to slot in button's shadow cause loss of button focus
+        https://bugs.webkit.org/show_bug.cgi?id=191694
+        <rdar://problem/46107920>
+
+        Reviewed by Wenson Hsieh.
+
+        Fixed the bug by traversing the parent in the composed tree when looking for an element to focus.
+
+        Test: fast/shadow-dom/focus-slot-parent.html
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::dispatchMouseEvent): Fixed the bug. Also use RefPtr instead of a raw pointer.
+
 2018-11-19  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         REGRESSION(r238350) [curl] CertificateInfo.h: error: template specialization requires 'template<>'
index b9c65dd..4d4eab5 100644 (file)
@@ -2598,8 +2598,8 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
     // from the user interface of Windows, where pushing a button moves focus to the button.
 
     // Walk up the DOM tree to search for an element to focus.
-    Element* element;
-    for (element = m_elementUnderMouse.get(); element; element = element->parentOrShadowHostElement()) {
+    RefPtr<Element> element;
+    for (element = m_elementUnderMouse.get(); element; element = element->parentElementInComposedTree()) {
         if (element->isMouseFocusable())
             break;
     }
@@ -2622,7 +2622,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
 
     // If focus shift is blocked, we eat the event.
     auto* page = m_frame.page();
-    if (page && !page->focusController().setFocusedElement(element, m_frame))
+    if (page && !page->focusController().setFocusedElement(element.get(), m_frame))
         return false;
 
     return true;