Title: [246570] trunk
Revision
246570
Author
dba...@webkit.org
Date
2019-06-18 14:50:20 -0700 (Tue, 18 Jun 2019)

Log Message

REGRESSION (r240757): Cannot dismiss the keyboard on http://apple.com/apple-tv-plus
https://bugs.webkit.org/show_bug.cgi?id=198922
<rdar://problem/50300056>

Reviewed by Wenson Hsieh.

Source/WebKit:

Actually dismiss the keyboard as intended in r240757. Do not wait for the round-trip
to the WebProcess to run through the -elementDidBlur steps in the UIProcess and hide
the keyboard when a person explicitly dismisses the keyboard via the Done button (iPhone)
or hide keyboard button (iPad).

Note that r240757 revealed another bug in this code, <https://bugs.webkit.org/show_bug.cgi?id=198928>.
I am unclear of the implications of that bug, but it is clear for this bug that it
never makes sense to round-trip to the WebProcess when the keyboard is dismissed by
a user gesture.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView endEditingAndUpdateFocusAppearanceWithReason:]): Invoke -_elementDidBlur
to blur the element in the UIProcess and hide the keyboard.
(-[WKContentView _elementDidBlur]): Prevent duplicate invocations of -didEndFormControlInteraction
and setIsShowingInputViewForFocusedElement messages by only doing these actions when
editablity changes. This covers the case where -_elementDidBlur may be invoked a second
time (the reply in the round-trip). In that case we don't need to do these actions.

LayoutTests:

Add a test to ensure that pressing Done hides the keyboard after tapping outside the focused
element's frame.

* fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field-expected.txt: Added.
* fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field.html: Added.
* resources/ui-helper.js:
(window.UIHelper.dismissFormAccessoryView): Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (246569 => 246570)


--- trunk/LayoutTests/ChangeLog	2019-06-18 21:40:27 UTC (rev 246569)
+++ trunk/LayoutTests/ChangeLog	2019-06-18 21:50:20 UTC (rev 246570)
@@ -1,3 +1,19 @@
+2019-06-18  Daniel Bates  <daba...@apple.com>
+
+        REGRESSION (r240757): Cannot dismiss the keyboard on http://apple.com/apple-tv-plus
+        https://bugs.webkit.org/show_bug.cgi?id=198922
+        <rdar://problem/50300056>
+
+        Reviewed by Wenson Hsieh.
+
+        Add a test to ensure that pressing Done hides the keyboard after tapping outside the focused
+        element's frame.
+
+        * fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field-expected.txt: Added.
+        * fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field.html: Added.
+        * resources/ui-helper.js:
+        (window.UIHelper.dismissFormAccessoryView): Added.
+
 2019-06-18  Alexey Shvayka  <shvaikal...@gmail.com>
 
         [ESNExt] String.prototype.matchAll

Added: trunk/LayoutTests/fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field-expected.txt (0 => 246570)


--- trunk/LayoutTests/fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field-expected.txt	2019-06-18 21:50:20 UTC (rev 246570)
@@ -0,0 +1,13 @@
+This test focuses the text field in the iframe, taps outside the iframe and then presses the Done button. The keyboard should hide.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+dispatched blur to main frame
+dispatched focus to <input>
+dispatched focus to main frame
+PASS dismissed form accessory
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field.html (0 => 246570)


--- trunk/LayoutTests/fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field.html	2019-06-18 21:50:20 UTC (rev 246570)
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="viewport" content="width=device-width">
+<script src=""
+<script src=""
+</head>
+<body>
+<iframe id="frame" srcdoc="<style>body { margin: 0; padding: 0 }</style><input placeholder='Tap here'><script>window.parent.runTest()</script>"></iframe>
+<script>
+window.jsTestIsAsync = true;
+
+description("This test focuses the text field in the iframe, taps outside the iframe and then presses the Done button. The keyboard should hide.")
+
+async function runTest()
+{
+    let frame = document.getElementById("frame");
+    let inputElementInFrame = frame.contentDocument.querySelector("input");
+
+    // 1. Add listeners
+    window.addEventListener("focus", () => debug("dispatched focus to main frame"), { once: true });
+    window.addEventListener("blur", () => debug("dispatched blur to main frame"), { once: true });
+    inputElementInFrame.addEventListener("focus", () => debug("dispatched focus to &lt;input&gt;"), { once: true });
+    inputElementInFrame.addEventListener("blur", () => debug("dispatched blur to &lt;input&gt;"), { once: true });
+
+    if (!window.testRunner)
+        return;
+
+    // 2. Focus the <input> in the <iframe>.
+    let x = frame.offsetLeft + inputElementInFrame.offsetLeft + Math.floor(inputElementInFrame.offsetWidth / 2);
+    let y = frame.offsetTop + inputElementInFrame.offsetTop + Math.floor(inputElementInFrame.offsetHeight / 2);
+    await UIHelper.activateAndWaitForInputSessionAt(x, y);
+
+    // 3. Tap somewhere in the main frame, then press the Done button.
+    await UIHelper.activateAt(0, 0);
+    await UIHelper.dismissFormAccessoryView(); // Press the Done button; ends the input session.
+    await UIHelper.waitForKeyboardToHide();
+
+    testPassed("dismissed form accessory");
+    document.body.removeChild(document.getElementById("frame"));
+    finishJSTest();
+}
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/resources/ui-helper.js (246569 => 246570)


--- trunk/LayoutTests/resources/ui-helper.js	2019-06-18 21:40:27 UTC (rev 246569)
+++ trunk/LayoutTests/resources/ui-helper.js	2019-06-18 21:50:20 UTC (rev 246570)
@@ -351,6 +351,20 @@
         });
     }
 
+    static dismissFormAccessoryView()
+    {
+        if (!this.isWebKit2() || !this.isIOSFamily())
+            return Promise.resolve();
+
+        return new Promise(resolve => {
+            testRunner.runUIScript(`
+                (function() {
+                    uiController.dismissFormAccessoryView();
+                    uiController.uiScriptComplete();
+                })()`, resolve);
+        });
+    }
+
     static isShowingKeyboard()
     {
         return new Promise(resolve => {

Modified: trunk/Source/WebKit/ChangeLog (246569 => 246570)


--- trunk/Source/WebKit/ChangeLog	2019-06-18 21:40:27 UTC (rev 246569)
+++ trunk/Source/WebKit/ChangeLog	2019-06-18 21:50:20 UTC (rev 246570)
@@ -1,3 +1,29 @@
+2019-06-18  Daniel Bates  <daba...@apple.com>
+
+        REGRESSION (r240757): Cannot dismiss the keyboard on http://apple.com/apple-tv-plus
+        https://bugs.webkit.org/show_bug.cgi?id=198922
+        <rdar://problem/50300056>
+
+        Reviewed by Wenson Hsieh.
+
+        Actually dismiss the keyboard as intended in r240757. Do not wait for the round-trip
+        to the WebProcess to run through the -elementDidBlur steps in the UIProcess and hide
+        the keyboard when a person explicitly dismisses the keyboard via the Done button (iPhone)
+        or hide keyboard button (iPad).
+
+        Note that r240757 revealed another bug in this code, <https://bugs.webkit.org/show_bug.cgi?id=198928>.
+        I am unclear of the implications of that bug, but it is clear for this bug that it
+        never makes sense to round-trip to the WebProcess when the keyboard is dismissed by
+        a user gesture.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView endEditingAndUpdateFocusAppearanceWithReason:]): Invoke -_elementDidBlur
+        to blur the element in the UIProcess and hide the keyboard.
+        (-[WKContentView _elementDidBlur]): Prevent duplicate invocations of -didEndFormControlInteraction
+        and setIsShowingInputViewForFocusedElement messages by only doing these actions when
+        editablity changes. This covers the case where -_elementDidBlur may be invoked a second
+        time (the reply in the round-trip). In that case we don't need to do these actions.
+
 2019-06-18  Alex Christensen  <achristen...@webkit.org>
 
         NetworkSession::networkStorageSession can return null

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (246569 => 246570)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-06-18 21:40:27 UTC (rev 246569)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-06-18 21:50:20 UTC (rev 246570)
@@ -1226,8 +1226,12 @@
     if (!_webView._retainingActiveFocusedState) {
         // We need to complete the editing operation before we blur the element.
         [self _endEditing];
-        if ((reason == EndEditingReasonAccessoryDone && !currentUserInterfaceIdiomIsPad()) || _keyboardDidRequestDismissal)
+        if ((reason == EndEditingReasonAccessoryDone && !currentUserInterfaceIdiomIsPad()) || _keyboardDidRequestDismissal) {
             _page->blurFocusedElement();
+            // Don't wait for WebPageProxy::blurFocusedElement() to round-trip back to us to hide the keyboard
+            // because we know that the user explicitly requested us to do so.
+            [self _elementDidBlur];
+        }
     }
 
     [self _cancelInteraction];
@@ -5282,12 +5286,13 @@
         [self removeFocusedFormControlOverlay];
 #endif
 
-    // The custom fixed position rect behavior is affected by -isFocusingElement, so if that changes we need to recompute rects.
-    if (editableChanged)
+    if (editableChanged) {
+        // The custom fixed position rect behavior is affected by -isFocusingElement, so if that changes we need to recompute rects.
         [_webView _scheduleVisibleContentRectUpdate];
 
-    [_webView didEndFormControlInteraction];
-    _page->setIsShowingInputViewForFocusedElement(false);
+        [_webView didEndFormControlInteraction];
+        _page->setIsShowingInputViewForFocusedElement(false);
+    }
 
     if (!_isChangingFocus)
         _didAccessoryTabInitiateFocus = NO;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to