Title: [238409] trunk
Revision
238409
Author
rn...@webkit.org
Date
2018-11-20 16:12:25 -0800 (Tue, 20 Nov 2018)

Log Message

Input element gains focus when a selectstart event listener on document prevents the default action
https://bugs.webkit.org/show_bug.cgi?id=191714
<rdar://problem/46174389>

Reviewed by Antti Koivisto.

Source/WebCore:

The bug was caused by WebKit keep firing selectstart upon mousemove after the drag had already started
when preventDefault had been called in the previous firings of selectstart event. Because input element
has its own editable element and fires selectstart on the input element itself, which won't be prevented
by selectstart on docuemnt, this allowed the selection to be set inside the input element even though
the mouse cursor was simply passing over the input element after the drag had already started.

Fixed the bug by not firing selectstart if the default action had been prevented by the initial firing
of selectstart by setting m_mouseDownMayStartDrag to false. This also matches the behaviors of Chrome
and Firefox.

Test: fast/events/selectstart-prevent-default-should-not-focus-input.html

* page/EventHandler.cpp:
(WebCore::EventHandler::updateSelectionForMouseDownDispatchingSelectStart):
(WebCore::EventHandler::updateSelectionForMouseDrag):

LayoutTests:

Added a regression test.

* fast/events/selectstart-prevent-default-should-not-focus-input-expected.txt: Added.
* fast/events/selectstart-prevent-default-should-not-focus-input.html: Added.
* platform/ios/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (238408 => 238409)


--- trunk/LayoutTests/ChangeLog	2018-11-20 23:46:23 UTC (rev 238408)
+++ trunk/LayoutTests/ChangeLog	2018-11-21 00:12:25 UTC (rev 238409)
@@ -1,3 +1,17 @@
+2018-11-20  Ryosuke Niwa  <rn...@webkit.org>
+
+        Input element gains focus when a selectstart event listener on document prevents the default action
+        https://bugs.webkit.org/show_bug.cgi?id=191714
+        <rdar://problem/46174389>
+
+        Reviewed by Antti Koivisto.
+
+        Added a regression test.
+
+        * fast/events/selectstart-prevent-default-should-not-focus-input-expected.txt: Added.
+        * fast/events/selectstart-prevent-default-should-not-focus-input.html: Added.
+        * platform/ios/TestExpectations:
+
 2018-11-19  Ryosuke Niwa  <rn...@webkit.org>
 
         Click on node assigned to slot in button's shadow cause loss of button focus

Added: trunk/LayoutTests/fast/events/selectstart-prevent-default-should-not-focus-input-expected.txt (0 => 238409)


--- trunk/LayoutTests/fast/events/selectstart-prevent-default-should-not-focus-input-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/selectstart-prevent-default-should-not-focus-input-expected.txt	2018-11-21 00:12:25 UTC (rev 238409)
@@ -0,0 +1,6 @@
+This tests that the input element does not get the focus when dragging mouse over it even when document has a selectstart event listener which prevents default.
+To manually test, drag a mouse cursor over the input element. The input element should not gain focus.
+
+
+selectstart event
+PASS - input element was not focused

Added: trunk/LayoutTests/fast/events/selectstart-prevent-default-should-not-focus-input.html (0 => 238409)


--- trunk/LayoutTests/fast/events/selectstart-prevent-default-should-not-focus-input.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/selectstart-prevent-default-should-not-focus-input.html	2018-11-21 00:12:25 UTC (rev 238409)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests that the input element does not get the focus when dragging mouse over it
+even when document has a selectstart event listener which prevents default.<br>
+To manually test, drag a mouse cursor over the input element.
+The input element should not gain focus.</p>
+<input type="text">
+<pre id="log"></pre>
+<script>
+
+document.addEventListener('selectstart', (event) => {
+    log.textContent += 'selectstart event\n';
+    event.preventDefault();
+});
+
+const input = document.querySelector('input');
+let inputElementWasFocused = false;
+input.addEventListener('focus', () => {
+    inputElementWasFocused = true;
+    log.textContent += 'FAIL - the input element was focused\n';
+});
+
+if (window.eventSender) {
+    testRunner.dumpAsText();
+
+    let x = input.offsetLeft + 5;
+    eventSender.mouseMoveTo(x, input.offsetTop - 5);
+    eventSender.mouseDown();
+    eventSender.leapForward(100);
+    eventSender.mouseMoveTo(x, input.offsetTop + 5);
+    eventSender.leapForward(100);
+    eventSender.mouseMoveTo(x, input.offsetTop + 100);
+    eventSender.mouseUp();
+
+    if (!inputElementWasFocused)
+        log.textContent += 'PASS - input element was not focused';
+
+} else
+    document.write('This test requires eventSender drag & drop support');
+
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/ios/TestExpectations (238408 => 238409)


--- trunk/LayoutTests/platform/ios/TestExpectations	2018-11-20 23:46:23 UTC (rev 238408)
+++ trunk/LayoutTests/platform/ios/TestExpectations	2018-11-21 00:12:25 UTC (rev 238409)
@@ -529,6 +529,7 @@
 fast/events/selectstart-by-drag.html [ Skip ]
 fast/events/selectstart-by-single-click-with-shift.html [ Skip ]
 fast/events/selectstart-prevent-selection-on-right-click.html [ Skip ]
+fast/events/selectstart-prevent-default-should-not-focus-input.html [ Skip ]
 fast/events/shadow-event-path-2.html [ Skip ]
 fast/events/shadow-event-path.html [ Skip ]
 fast/events/shift-drag-selection-on-image-triggers-drag-n-drop.html [ Skip ]

Modified: trunk/Source/WebCore/ChangeLog (238408 => 238409)


--- trunk/Source/WebCore/ChangeLog	2018-11-20 23:46:23 UTC (rev 238408)
+++ trunk/Source/WebCore/ChangeLog	2018-11-21 00:12:25 UTC (rev 238409)
@@ -1,3 +1,27 @@
+2018-11-20  Ryosuke Niwa  <rn...@webkit.org>
+
+        Input element gains focus when a selectstart event listener on document prevents the default action
+        https://bugs.webkit.org/show_bug.cgi?id=191714
+        <rdar://problem/46174389>
+
+        Reviewed by Antti Koivisto.
+
+        The bug was caused by WebKit keep firing selectstart upon mousemove after the drag had already started
+        when preventDefault had been called in the previous firings of selectstart event. Because input element
+        has its own editable element and fires selectstart on the input element itself, which won't be prevented
+        by selectstart on docuemnt, this allowed the selection to be set inside the input element even though
+        the mouse cursor was simply passing over the input element after the drag had already started.
+
+        Fixed the bug by not firing selectstart if the default action had been prevented by the initial firing
+        of selectstart by setting m_mouseDownMayStartDrag to false. This also matches the behaviors of Chrome
+        and Firefox.
+
+        Test: fast/events/selectstart-prevent-default-should-not-focus-input.html
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::updateSelectionForMouseDownDispatchingSelectStart):
+        (WebCore::EventHandler::updateSelectionForMouseDrag):
+
 2018-11-20  Christopher Reid  <chris.r...@sony.com>
 
         Remove the need for LocalizedStringsWPE.cpp

Modified: trunk/Source/WebCore/page/EventHandler.cpp (238408 => 238409)


--- trunk/Source/WebCore/page/EventHandler.cpp	2018-11-20 23:46:23 UTC (rev 238408)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2018-11-21 00:12:25 UTC (rev 238409)
@@ -510,8 +510,10 @@
     if (Position::nodeIsUserSelectNone(targetNode))
         return false;
 
-    if (!dispatchSelectStart(targetNode))
+    if (!dispatchSelectStart(targetNode)) {
+        m_mouseDownMayStartSelect = false;
         return false;
+    }
 
     if (selection.isRange())
         m_selectionInitiationState = ExtendedSelection;
@@ -953,14 +955,20 @@
 
     // Special case to limit selection to the containing block for SVG text.
     // FIXME: Isn't there a better non-SVG-specific way to do this?
-    if (Node* selectionBaseNode = newSelection.base().deprecatedNode())
-        if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer())
-            if (selectionBaseRenderer->isSVGText())
+    if (Node* selectionBaseNode = newSelection.base().deprecatedNode()) {
+        if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer()) {
+            if (selectionBaseRenderer->isSVGText()) {
                 if (target->renderer()->containingBlock() != selectionBaseRenderer->containingBlock())
                     return;
+            }
+        }
+    }
 
-    if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target))
+
+    if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target)) {
+        m_mouseDownMayStartSelect = false;
         return;
+    }
 
     if (m_selectionInitiationState != ExtendedSelection) {
         // Always extend selection here because it's caused by a mouse drag
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to