Keyboard input suppression should extend to subframes
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 May 2017 18:30:57 +0000 (18:30 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 May 2017 18:30:57 +0000 (18:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=171880
<rdar://problem/31201793>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Test: http/tests/navigation/keyboard-events-during-provisional-subframe-navigation.html

* dom/EventDispatcher.cpp:
(WebCore::shouldSuppressEventDispatchInDOM): Changed to call shouldSuppressKeyboardInput()
on the main frame's loader.
* editing/Editor.cpp:
(WebCore::Editor::shouldInsertText): Ditto.

LayoutTests:

* http/tests/navigation/keyboard-events-during-provisional-navigation-expected.txt:
* http/tests/navigation/keyboard-events-during-provisional-navigation.html:
* http/tests/navigation/keyboard-events-during-provisional-subframe-navigation-expected.txt: Copied from LayoutTests/http/tests/navigation/keyboard-events-during-provisional-navigation-expected.txt.
* http/tests/navigation/keyboard-events-during-provisional-subframe-navigation.html: Copied from LayoutTests/http/tests/navigation/keyboard-events-during-provisional-navigation.html.
* http/tests/navigation/resources/keyboard-events-after-navigation.html:
* http/tests/navigation/resources/keyboard-events-test.js:
(runTest):
(waitForProvisionalNavigation.xhr.onreadystatechange):
(waitForProvisionalNavigation):

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

LayoutTests/ChangeLog
LayoutTests/http/tests/navigation/keyboard-events-during-provisional-navigation-expected.txt
LayoutTests/http/tests/navigation/keyboard-events-during-provisional-navigation.html
LayoutTests/http/tests/navigation/keyboard-events-during-provisional-subframe-navigation-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/navigation/keyboard-events-during-provisional-subframe-navigation.html [new file with mode: 0644]
LayoutTests/http/tests/navigation/resources/keyboard-events-after-navigation.html
LayoutTests/http/tests/navigation/resources/keyboard-events-test.js
Source/WebCore/ChangeLog
Source/WebCore/dom/EventDispatcher.cpp
Source/WebCore/editing/Editor.cpp

index 0656ed3..f44bb5f 100644 (file)
@@ -1,3 +1,21 @@
+2017-05-10  Andy Estes  <aestes@apple.com>
+
+        Keyboard input suppression should extend to subframes
+        https://bugs.webkit.org/show_bug.cgi?id=171880
+        <rdar://problem/31201793>
+
+        Reviewed by Ryosuke Niwa.
+
+        * http/tests/navigation/keyboard-events-during-provisional-navigation-expected.txt:
+        * http/tests/navigation/keyboard-events-during-provisional-navigation.html:
+        * http/tests/navigation/keyboard-events-during-provisional-subframe-navigation-expected.txt: Copied from LayoutTests/http/tests/navigation/keyboard-events-during-provisional-navigation-expected.txt.
+        * http/tests/navigation/keyboard-events-during-provisional-subframe-navigation.html: Copied from LayoutTests/http/tests/navigation/keyboard-events-during-provisional-navigation.html.
+        * http/tests/navigation/resources/keyboard-events-after-navigation.html:
+        * http/tests/navigation/resources/keyboard-events-test.js:
+        (runTest):
+        (waitForProvisionalNavigation.xhr.onreadystatechange):
+        (waitForProvisionalNavigation):
+
 2017-05-10  Matt Lewis  <jlewis3@apple.com>
 
         Unreviewed, rolling out r216563.
index 1a9ba91..e74fe69 100644 (file)
@@ -1,40 +1,40 @@
-CONSOLE MESSAGE: line 30: Provisional navigation started.
-CONSOLE MESSAGE: line 31: No trusted events should be logged and the input element should have the value "".
-CONSOLE MESSAGE: line 18: Dispatching untrusted keypress event.
+CONSOLE MESSAGE: line 14: Provisional navigation started.
+CONSOLE MESSAGE: line 15: No trusted events should be logged and the input element should have the value "".
+CONSOLE MESSAGE: line 20: Dispatching untrusted keypress event.
 CONSOLE MESSAGE: line 5: keypressevent dispatched (isTrusted: false).
-CONSOLE MESSAGE: line 26: Pressing tab.
-CONSOLE MESSAGE: line 28: Active element after pressing tab: [object HTMLInputElement].
-CONSOLE MESSAGE: line 30: Pressing "a".
-CONSOLE MESSAGE: line 33: Setting marked text to "b".
-CONSOLE MESSAGE: line 36: Inserting text "c".
-CONSOLE MESSAGE: line 39: Input element value after text input events: "".
-CONSOLE MESSAGE: line 34: Pressing "z" with access key modifiers should navigate to resources/keyboard-events-after-navigation.html.
+CONSOLE MESSAGE: line 28: Pressing tab.
+CONSOLE MESSAGE: line 30: Active element after pressing tab: [object HTMLInputElement].
+CONSOLE MESSAGE: line 32: Pressing "a".
+CONSOLE MESSAGE: line 42: Setting marked text to "b".
+CONSOLE MESSAGE: line 45: Inserting text "c".
+CONSOLE MESSAGE: line 48: Input element value after text input events: "".
+CONSOLE MESSAGE: line 18: Pressing "z" with access key modifiers should navigate to resources/keyboard-events-after-navigation.html.
 CONSOLE MESSAGE: line 6: Finished navigating to resources/keyboard-events-after-navigation.html.
 CONSOLE MESSAGE: line 7: Trusted events should be logged and the input element should have the value "ac".
-CONSOLE MESSAGE: line 18: Dispatching untrusted keypress event.
+CONSOLE MESSAGE: line 20: Dispatching untrusted keypress event.
 CONSOLE MESSAGE: line 5: keypressevent dispatched (isTrusted: false).
-CONSOLE MESSAGE: line 26: Pressing tab.
+CONSOLE MESSAGE: line 28: Pressing tab.
 CONSOLE MESSAGE: line 5: keydownevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: keyupevent dispatched (isTrusted: true).
-CONSOLE MESSAGE: line 28: Active element after pressing tab: [object HTMLInputElement].
-CONSOLE MESSAGE: line 30: Pressing "a".
+CONSOLE MESSAGE: line 30: Active element after pressing tab: [object HTMLInputElement].
+CONSOLE MESSAGE: line 32: Pressing "a".
 CONSOLE MESSAGE: line 5: keydownevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: keypressevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: textInputevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: keyupevent dispatched (isTrusted: true).
-CONSOLE MESSAGE: line 33: Setting marked text to "b".
+CONSOLE MESSAGE: line 42: Setting marked text to "b".
 CONSOLE MESSAGE: line 5: compositionstartevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: compositionupdateevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
-CONSOLE MESSAGE: line 36: Inserting text "c".
+CONSOLE MESSAGE: line 45: Inserting text "c".
 CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: textInputevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
 CONSOLE MESSAGE: line 5: compositionendevent dispatched (isTrusted: true).
-CONSOLE MESSAGE: line 39: Input element value after text input events: "ac".
+CONSOLE MESSAGE: line 48: Input element value after text input events: "ac".
 
index c3d8fbd..1855d0e 100644 (file)
             internals.settings.setShouldSuppressKeyboardInputDuringProvisionalNavigation(true);
         }
 
-        function waitForProvisionalNavigation(completionHandler)
-        {
-            var xhr = new XMLHttpRequest();
-            xhr.onreadystatechange = function() {
-                if (this.readyState !== this.DONE)
-                    return;
-                window.setTimeout(function() {
-                    completionHandler();
-                }, 0);
-            };
-            xhr.open("GET", "resources/never-respond.php");
-            xhr.send();
-
-            window.location = "resources/never-respond.php";
-        }
-
         waitForProvisionalNavigation(function() {
             console.log("Provisional navigation started.");
             console.log("No trusted events should be logged and the input element should have the value \"\".");
-            runTest();
+            runTest(window);
 
             console.log("Pressing \"z\" with access key modifiers should navigate to resources/keyboard-events-after-navigation.html.");
             eventSender.keyDown("z", internals.accessKeyModifiers());
diff --git a/LayoutTests/http/tests/navigation/keyboard-events-during-provisional-subframe-navigation-expected.txt b/LayoutTests/http/tests/navigation/keyboard-events-during-provisional-subframe-navigation-expected.txt
new file mode 100644 (file)
index 0000000..55e4fed
--- /dev/null
@@ -0,0 +1,76 @@
+CONSOLE MESSAGE: line 16: Provisional navigation started.
+CONSOLE MESSAGE: line 17: No trusted events should be logged and the input element should have the value "".
+CONSOLE MESSAGE: line 20: Dispatching untrusted keypress event.
+CONSOLE MESSAGE: line 5: keypressevent dispatched (isTrusted: false).
+CONSOLE MESSAGE: line 28: Pressing tab.
+CONSOLE MESSAGE: line 30: Active element after pressing tab: [object HTMLInputElement].
+CONSOLE MESSAGE: line 32: Pressing "a".
+CONSOLE MESSAGE: line 38: Input element value after text input events: "".
+CONSOLE MESSAGE: line 20: Pressing "z" with access key modifiers should navigate to resources/keyboard-events-after-navigation.html.
+CONSOLE MESSAGE: line 6: Finished navigating to resources/keyboard-events-after-navigation.html.
+CONSOLE MESSAGE: line 7: Trusted events should be logged and the input element should have the value "ac".
+CONSOLE MESSAGE: line 20: Dispatching untrusted keypress event.
+CONSOLE MESSAGE: line 5: keypressevent dispatched (isTrusted: false).
+CONSOLE MESSAGE: line 28: Pressing tab.
+CONSOLE MESSAGE: line 5: keydownevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: keyupevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 30: Active element after pressing tab: [object HTMLInputElement].
+CONSOLE MESSAGE: line 32: Pressing "a".
+CONSOLE MESSAGE: line 5: keydownevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: keypressevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: textInputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: keyupevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 42: Setting marked text to "b".
+CONSOLE MESSAGE: line 5: compositionstartevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: compositionupdateevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 45: Inserting text "c".
+CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: textInputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: compositionendevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 48: Input element value after text input events: "ac".
+
+CONSOLE MESSAGE: line 16: Provisional navigation started.
+CONSOLE MESSAGE: line 17: No trusted events should be logged and the input element should have the value "".
+CONSOLE MESSAGE: line 20: Dispatching untrusted keypress event.
+CONSOLE MESSAGE: line 5: keypressevent dispatched (isTrusted: false).
+CONSOLE MESSAGE: line 28: Pressing tab.
+CONSOLE MESSAGE: line 30: Active element after pressing tab: [object HTMLInputElement].
+CONSOLE MESSAGE: line 32: Pressing "a".
+CONSOLE MESSAGE: line 38: Input element value after text input events: "".
+CONSOLE MESSAGE: line 20: Pressing "z" with access key modifiers should navigate to resources/keyboard-events-after-navigation.html.
+CONSOLE MESSAGE: line 6: Finished navigating to resources/keyboard-events-after-navigation.html.
+CONSOLE MESSAGE: line 7: Trusted events should be logged and the input element should have the value "ac".
+CONSOLE MESSAGE: line 20: Dispatching untrusted keypress event.
+CONSOLE MESSAGE: line 5: keypressevent dispatched (isTrusted: false).
+CONSOLE MESSAGE: line 28: Pressing tab.
+CONSOLE MESSAGE: line 5: keydownevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: keyupevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 30: Active element after pressing tab: [object HTMLInputElement].
+CONSOLE MESSAGE: line 32: Pressing "a".
+CONSOLE MESSAGE: line 5: keydownevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: keypressevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: textInputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: keyupevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 42: Setting marked text to "b".
+CONSOLE MESSAGE: line 5: compositionstartevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: compositionupdateevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 45: Inserting text "c".
+CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: textInputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: beforeinputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: inputevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 5: compositionendevent dispatched (isTrusted: true).
+CONSOLE MESSAGE: line 48: Input element value after text input events: "ac".
+
diff --git a/LayoutTests/http/tests/navigation/keyboard-events-during-provisional-subframe-navigation.html b/LayoutTests/http/tests/navigation/keyboard-events-during-provisional-subframe-navigation.html
new file mode 100644 (file)
index 0000000..a40a4bb
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<body>
+    <iframe id="subframe"></iframe>
+    <a href="resources/keyboard-events-after-navigation.html" accesskey="z"></a>
+    <script src="resources/keyboard-events-test.js"></script>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.dumpChildFramesAsText();
+            testRunner.waitUntilDone();
+            internals.settings.setShouldSuppressKeyboardInputDuringProvisionalNavigation(true);
+        }
+
+        waitForProvisionalNavigation(function () {
+            console.log("Provisional navigation started.");
+            console.log("No trusted events should be logged and the input element should have the value \"\".");
+            runTest(document.getElementById("subframe").contentWindow);
+
+            console.log("Pressing \"z\" with access key modifiers should navigate to resources/keyboard-events-after-navigation.html.");
+            window.focus();
+            eventSender.keyDown("z", internals.accessKeyModifiers());
+        });
+    </script>
+</body>
+</html>
+<!DOCTYPE html>
+<html>
+<body>
+    <iframe id="subframe"></iframe>
+    <a href="resources/keyboard-events-after-navigation.html" accesskey="z"></a>
+    <script src="resources/keyboard-events-test.js"></script>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.dumpChildFramesAsText();
+            testRunner.waitUntilDone();
+            internals.settings.setShouldSuppressKeyboardInputDuringProvisionalNavigation(true);
+        }
+
+        waitForProvisionalNavigation(function() {
+            console.log("Provisional navigation started.");
+            console.log("No trusted events should be logged and the input element should have the value \"\".");
+            runTest(document.getElementById("subframe").contentWindow);
+
+            console.log("Pressing \"z\" with access key modifiers should navigate to resources/keyboard-events-after-navigation.html.");
+            window.focus();
+            eventSender.keyDown("z", internals.accessKeyModifiers());
+        });
+    </script>
+</body>
+</html>
index 20c0f4b..e5a801c 100644 (file)
@@ -5,7 +5,7 @@
     <script>
         console.log("Finished navigating to resources/keyboard-events-after-navigation.html.");
         console.log("Trusted events should be logged and the input element should have the value \"ac\".");
-        runTest();
+        runTest(window);
         testRunner.notifyDone();
     </script>
 </body>
index 2236276..33a9969 100644 (file)
@@ -1,4 +1,4 @@
-function runTest()
+function runTest(window)
 {
     function eventHandler(event)
     {
@@ -15,6 +15,8 @@ function runTest()
     window.addEventListener("beforeinput", eventHandler, true);
     window.addEventListener("input", eventHandler, true);
 
+    var document = window.document;
+
     console.log("Dispatching untrusted keypress event.");
     var keyPressEvent = new KeyboardEvent("keypress");
     document.body.dispatchEvent(keyPressEvent);
@@ -30,6 +32,13 @@ function runTest()
     console.log("Pressing \"a\".");
     eventSender.keyDown("a");
 
+    // FIXME: Composition events trigger assertions when performed in subframes.
+    // See <https://webkit.org/b/132297>.
+    if (window !== window.top) {
+        console.log("Input element value after text input events: \"" + textInput.value + "\".");
+        return;
+    }
+
     console.log("Setting marked text to \"b\".");
     textInputController.setMarkedText("b", 0, 1);
 
@@ -38,3 +47,17 @@ function runTest()
 
     console.log("Input element value after text input events: \"" + textInput.value + "\".");
 }
+
+function waitForProvisionalNavigation(completionHandler)
+{
+    // This exploits the fact that XHRs are cancelled when a location change begins.
+    var xhr = new XMLHttpRequest();
+    xhr.onreadystatechange = function() {
+        if (this.readyState === this.DONE)
+            window.setTimeout(completionHandler, 0);
+    };
+    xhr.open("GET", "resources/never-respond.php");
+    xhr.send();
+
+    window.location = "resources/never-respond.php";
+}
index 5c22d28..6deed96 100644 (file)
@@ -1,3 +1,19 @@
+2017-05-10  Andy Estes  <aestes@apple.com>
+
+        Keyboard input suppression should extend to subframes
+        https://bugs.webkit.org/show_bug.cgi?id=171880
+        <rdar://problem/31201793>
+
+        Reviewed by Ryosuke Niwa.
+
+        Test: http/tests/navigation/keyboard-events-during-provisional-subframe-navigation.html
+
+        * dom/EventDispatcher.cpp:
+        (WebCore::shouldSuppressEventDispatchInDOM): Changed to call shouldSuppressKeyboardInput()
+        on the main frame's loader.
+        * editing/Editor.cpp:
+        (WebCore::Editor::shouldInsertText): Ditto.
+
 2017-05-10  Matt Lewis  <jlewis3@apple.com>
 
         Unreviewed, rolling out r216563.
index a673f09..0c3facc 100644 (file)
@@ -34,6 +34,7 @@
 #include "HTMLInputElement.h"
 #include "InputEvent.h"
 #include "KeyboardEvent.h"
+#include "MainFrame.h"
 #include "MouseEvent.h"
 #include "NoEventDispatchAssertion.h"
 #include "ScopedEventQueue.h"
@@ -115,7 +116,7 @@ static bool shouldSuppressEventDispatchInDOM(Node& node, Event& event)
     if (!frame)
         return false;
 
-    if (!frame->loader().shouldSuppressKeyboardInput())
+    if (!frame->mainFrame().loader().shouldSuppressKeyboardInput())
         return false;
 
     if (is<TextEvent>(event)) {
index 652eee4..8ab0977 100644 (file)
@@ -577,7 +577,7 @@ bool Editor::tryDHTMLPaste()
 
 bool Editor::shouldInsertText(const String& text, Range* range, EditorInsertAction action) const
 {
-    if (m_frame.loader().shouldSuppressKeyboardInput() && action == EditorInsertAction::Typed)
+    if (m_frame.mainFrame().loader().shouldSuppressKeyboardInput() && action == EditorInsertAction::Typed)
         return false;
 
     return client() && client()->shouldInsertText(text, range, action);