Title: [249012] branches/safari-608-branch
Revision
249012
Author
[email protected]
Date
2019-08-22 09:20:34 -0700 (Thu, 22 Aug 2019)

Log Message

Cherry-pick r249006. rdar://problem/54600921

    Typing Korean in title field after typing in the body inserts extraneous characters on blog.naver.com
    https://bugs.webkit.org/show_bug.cgi?id=201023
    <rdar://problem/54294794>

    Reviewed by Ryosuke Niwa.

    Source/WebCore:

    Ensures that we recognize the blog editor on blog.naver.com to be a hidden editable area. This website places
    focus inside an editable body element of a subframe that is completely empty (width: 0 and border: 0). See the
    WebKit ChangeLog for more details.

    Test: editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html

    * rendering/RenderLayer.cpp:
    (WebCore::RenderLayer::calculateClipRects const):

    Source/WebKit:

    After r242833, we began to avoid sending redundant ElementDidFocus updates in the case where a focused element
    was blurred and refocused within the same runloop. This was done to prevent the input view from flickering due
    to input view reloading, as well as scrolling to reveal the focused element, when tapping to change selection on
    Microsoft Word online.

    However, on blog.naver.com, these ElementDidFocus messages were necessary in order to ensure that the platform
    input context changes when moving between the title and body fields, or when tapping to change selection. This
    is because blog.naver.com uses a hidden contenteditable area under a subframe (see WebCore ChangeLog for more
    detail here). While text is never directly inserted into this hidden contenteditable, the events are observed
    and used to "play back" editing in the main visible content area.

    Thus, when moving between the title and body fields (or when changing selection within either), the only hint we
    get is that the hidden editable element is blurred and immediately refocused. Since we no longer send
    ElementDidFocus updates in this scenario, UIKeyboardImpl and kbd are not aware that the page has effectively
    changed input contexts.

    Combined with the fact that Korean IME on iOS may insert additional text given the document context (i.e. text
    that the input manager, kbd, thinks we've previously inserted), this means that when typing several characters
    into the body field on naver and then switching to edit the title, initial keystrokes may insert unexpected
    text in the title field.

    To fix this, we add some hooks to notify the UI process when an element that was blurred has been immediately
    refocused. Upon receiving this message, the UI process then tells UIKeyboardImpl to re-retrieve its input
    context, which calls into -requestAutocorrectionContextWithCompletionHandler: in WKContentView. While notorious
    for being synchronous IPC, this is mitigated by (1) being limiting to only instances where we have a hidden
    editable area, and (2) being limited by a batching mechanism in the web process, such that if the focused
    element is blurred, refocused, re-blurred, and refocused many times in the same runloop, we'll only send a
    single UpdateInputContextAfterBlurringAndRefocusingElement message (as opposed to the many ElementDidFocus
    messages we would've sent in previous releases).

    * Platform/spi/ios/UIKitSPI.h:
    * UIProcess/PageClient.h:
    * UIProcess/WebPageProxy.h:
    * UIProcess/WebPageProxy.messages.in:

    Add a new mechanism to update the platform input context (on iOS, UIKeyboardImpl's document state) when focus
    moves away from and immediately returns to a hidden editable element.

    * UIProcess/ios/PageClientImplIOS.h:
    * UIProcess/ios/PageClientImplIOS.mm:
    (WebKit::PageClientImpl::updateInputContextAfterBlurringAndRefocusingElement):
    * UIProcess/ios/WKContentViewInteraction.h:
    * UIProcess/ios/WKContentViewInteraction.mm:
    (-[WKContentView _updateInputContextAfterBlurringAndRefocusingElement]):

    Tell the active UIKeyboardImpl to refetch document state from the WKContentView. While this does result in a new
    autocorrection context request (which, unfortunately, triggers synchronous IPC to the web process), this request
    would've still happened anyways in the case where we would previously have sent an ElementDidFocus message.

    * UIProcess/ios/WebPageProxyIOS.mm:
    (WebKit::WebPageProxy::updateInputContextAfterBlurringAndRefocusingElement):
    * WebProcess/WebPage/WebPage.cpp:
    (WebKit::WebPage::elementDidFocus):

    In the case where we avoid sending a full ElementDidFocus message to the UI process due to refocusing the same
    element, we should still notify the UI process so that it can synchronize state between the application process
    and kbd. See above for more details.

    (WebKit::WebPage::elementDidBlur):
    (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):
    * WebProcess/WebPage/WebPage.h:
    * WebProcess/WebPage/ios/WebPageIOS.mm:
    (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):

    LayoutTests:

    Add a new layout test to verify that we suppress text interactions when focusing an editable element inside an
    empty, borderless subframe.

    * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe-expected.txt: Added.
    * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html: Added.

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-608-branch/LayoutTests/ChangeLog (249011 => 249012)


--- branches/safari-608-branch/LayoutTests/ChangeLog	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/LayoutTests/ChangeLog	2019-08-22 16:20:34 UTC (rev 249012)
@@ -1,5 +1,117 @@
 2019-08-22  Kocsen Chung  <[email protected]>
 
+        Cherry-pick r249006. rdar://problem/54600921
+
+    Typing Korean in title field after typing in the body inserts extraneous characters on blog.naver.com
+    https://bugs.webkit.org/show_bug.cgi?id=201023
+    <rdar://problem/54294794>
+    
+    Reviewed by Ryosuke Niwa.
+    
+    Source/WebCore:
+    
+    Ensures that we recognize the blog editor on blog.naver.com to be a hidden editable area. This website places
+    focus inside an editable body element of a subframe that is completely empty (width: 0 and border: 0). See the
+    WebKit ChangeLog for more details.
+    
+    Test: editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html
+    
+    * rendering/RenderLayer.cpp:
+    (WebCore::RenderLayer::calculateClipRects const):
+    
+    Source/WebKit:
+    
+    After r242833, we began to avoid sending redundant ElementDidFocus updates in the case where a focused element
+    was blurred and refocused within the same runloop. This was done to prevent the input view from flickering due
+    to input view reloading, as well as scrolling to reveal the focused element, when tapping to change selection on
+    Microsoft Word online.
+    
+    However, on blog.naver.com, these ElementDidFocus messages were necessary in order to ensure that the platform
+    input context changes when moving between the title and body fields, or when tapping to change selection. This
+    is because blog.naver.com uses a hidden contenteditable area under a subframe (see WebCore ChangeLog for more
+    detail here). While text is never directly inserted into this hidden contenteditable, the events are observed
+    and used to "play back" editing in the main visible content area.
+    
+    Thus, when moving between the title and body fields (or when changing selection within either), the only hint we
+    get is that the hidden editable element is blurred and immediately refocused. Since we no longer send
+    ElementDidFocus updates in this scenario, UIKeyboardImpl and kbd are not aware that the page has effectively
+    changed input contexts.
+    
+    Combined with the fact that Korean IME on iOS may insert additional text given the document context (i.e. text
+    that the input manager, kbd, thinks we've previously inserted), this means that when typing several characters
+    into the body field on naver and then switching to edit the title, initial keystrokes may insert unexpected
+    text in the title field.
+    
+    To fix this, we add some hooks to notify the UI process when an element that was blurred has been immediately
+    refocused. Upon receiving this message, the UI process then tells UIKeyboardImpl to re-retrieve its input
+    context, which calls into -requestAutocorrectionContextWithCompletionHandler: in WKContentView. While notorious
+    for being synchronous IPC, this is mitigated by (1) being limiting to only instances where we have a hidden
+    editable area, and (2) being limited by a batching mechanism in the web process, such that if the focused
+    element is blurred, refocused, re-blurred, and refocused many times in the same runloop, we'll only send a
+    single UpdateInputContextAfterBlurringAndRefocusingElement message (as opposed to the many ElementDidFocus
+    messages we would've sent in previous releases).
+    
+    * Platform/spi/ios/UIKitSPI.h:
+    * UIProcess/PageClient.h:
+    * UIProcess/WebPageProxy.h:
+    * UIProcess/WebPageProxy.messages.in:
+    
+    Add a new mechanism to update the platform input context (on iOS, UIKeyboardImpl's document state) when focus
+    moves away from and immediately returns to a hidden editable element.
+    
+    * UIProcess/ios/PageClientImplIOS.h:
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::updateInputContextAfterBlurringAndRefocusingElement):
+    * UIProcess/ios/WKContentViewInteraction.h:
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView _updateInputContextAfterBlurringAndRefocusingElement]):
+    
+    Tell the active UIKeyboardImpl to refetch document state from the WKContentView. While this does result in a new
+    autocorrection context request (which, unfortunately, triggers synchronous IPC to the web process), this request
+    would've still happened anyways in the case where we would previously have sent an ElementDidFocus message.
+    
+    * UIProcess/ios/WebPageProxyIOS.mm:
+    (WebKit::WebPageProxy::updateInputContextAfterBlurringAndRefocusingElement):
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::elementDidFocus):
+    
+    In the case where we avoid sending a full ElementDidFocus message to the UI process due to refocusing the same
+    element, we should still notify the UI process so that it can synchronize state between the application process
+    and kbd. See above for more details.
+    
+    (WebKit::WebPage::elementDidBlur):
+    (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):
+    
+    LayoutTests:
+    
+    Add a new layout test to verify that we suppress text interactions when focusing an editable element inside an
+    empty, borderless subframe.
+    
+    * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe-expected.txt: Added.
+    * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249006 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-08-22  Wenson Hsieh  <[email protected]>
+
+            Typing Korean in title field after typing in the body inserts extraneous characters on blog.naver.com
+            https://bugs.webkit.org/show_bug.cgi?id=201023
+            <rdar://problem/54294794>
+
+            Reviewed by Ryosuke Niwa.
+
+            Add a new layout test to verify that we suppress text interactions when focusing an editable element inside an
+            empty, borderless subframe.
+
+            * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe-expected.txt: Added.
+            * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html: Added.
+
+2019-08-22  Kocsen Chung  <[email protected]>
+
         Cherry-pick r248977. rdar://problem/54599960
 
     Do not adjust viewport if editing selection is already visible

Added: branches/safari-608-branch/LayoutTests/editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe-expected.txt (0 => 249012)


--- branches/safari-608-branch/LayoutTests/editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe-expected.txt	                        (rev 0)
+++ branches/safari-608-branch/LayoutTests/editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe-expected.txt	2019-08-22 16:20:34 UTC (rev 249012)
@@ -0,0 +1,11 @@
+This test verifies that selection UI is suppressed when focusing an element inside an empty subframe. To run the test manually, tap the button and check that a blue selection caret is not visible.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS caretRect.width is 0
+PASS caretRect.height is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Focus the hidden frame

Added: branches/safari-608-branch/LayoutTests/editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html (0 => 249012)


--- branches/safari-608-branch/LayoutTests/editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html	                        (rev 0)
+++ branches/safari-608-branch/LayoutTests/editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html	2019-08-22 16:20:34 UTC (rev 249012)
@@ -0,0 +1,49 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <script src=""
+    <script src=""
+    <style>
+        iframe {
+            width: 0;
+            height: 100%;
+            position: fixed;
+            top: 0;
+            left: 0;
+            border: 0;
+        }
+
+        body, html {
+            width: 100%;
+            height: 100%;
+        }
+
+        button {
+            padding: 1em;
+        }
+    </style>
+</head>
+<body>
+    <iframe srcdoc="<body contenteditable>"></iframe>
+    <button id="focus">Focus the hidden frame</button>
+    <script>
+        jsTestIsAsync = true;
+        description("This test verifies that selection UI is suppressed when focusing an element inside an empty subframe. To run the test manually, tap the button and check that a blue selection caret is not visible.");
+
+        const focusButton = document.getElementById("focus");
+        focusButton.addEventListener("click", event => {
+            document.querySelector("iframe").contentDocument.body.focus();
+            event.preventDefault();
+        });
+
+        addEventListener("load", async () => {
+            await UIHelper.activateElementAndWaitForInputSession(focusButton);
+            caretRect = await UIHelper.getUICaretViewRect();
+            shouldBe("caretRect.width", "0");
+            shouldBe("caretRect.height", "0");
+            finishJSTest();
+        });
+    </script>
+</body>
+</html>
\ No newline at end of file

Modified: branches/safari-608-branch/Source/WebCore/ChangeLog (249011 => 249012)


--- branches/safari-608-branch/Source/WebCore/ChangeLog	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebCore/ChangeLog	2019-08-22 16:20:34 UTC (rev 249012)
@@ -1,5 +1,120 @@
 2019-08-22  Kocsen Chung  <[email protected]>
 
+        Cherry-pick r249006. rdar://problem/54600921
+
+    Typing Korean in title field after typing in the body inserts extraneous characters on blog.naver.com
+    https://bugs.webkit.org/show_bug.cgi?id=201023
+    <rdar://problem/54294794>
+    
+    Reviewed by Ryosuke Niwa.
+    
+    Source/WebCore:
+    
+    Ensures that we recognize the blog editor on blog.naver.com to be a hidden editable area. This website places
+    focus inside an editable body element of a subframe that is completely empty (width: 0 and border: 0). See the
+    WebKit ChangeLog for more details.
+    
+    Test: editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html
+    
+    * rendering/RenderLayer.cpp:
+    (WebCore::RenderLayer::calculateClipRects const):
+    
+    Source/WebKit:
+    
+    After r242833, we began to avoid sending redundant ElementDidFocus updates in the case where a focused element
+    was blurred and refocused within the same runloop. This was done to prevent the input view from flickering due
+    to input view reloading, as well as scrolling to reveal the focused element, when tapping to change selection on
+    Microsoft Word online.
+    
+    However, on blog.naver.com, these ElementDidFocus messages were necessary in order to ensure that the platform
+    input context changes when moving between the title and body fields, or when tapping to change selection. This
+    is because blog.naver.com uses a hidden contenteditable area under a subframe (see WebCore ChangeLog for more
+    detail here). While text is never directly inserted into this hidden contenteditable, the events are observed
+    and used to "play back" editing in the main visible content area.
+    
+    Thus, when moving between the title and body fields (or when changing selection within either), the only hint we
+    get is that the hidden editable element is blurred and immediately refocused. Since we no longer send
+    ElementDidFocus updates in this scenario, UIKeyboardImpl and kbd are not aware that the page has effectively
+    changed input contexts.
+    
+    Combined with the fact that Korean IME on iOS may insert additional text given the document context (i.e. text
+    that the input manager, kbd, thinks we've previously inserted), this means that when typing several characters
+    into the body field on naver and then switching to edit the title, initial keystrokes may insert unexpected
+    text in the title field.
+    
+    To fix this, we add some hooks to notify the UI process when an element that was blurred has been immediately
+    refocused. Upon receiving this message, the UI process then tells UIKeyboardImpl to re-retrieve its input
+    context, which calls into -requestAutocorrectionContextWithCompletionHandler: in WKContentView. While notorious
+    for being synchronous IPC, this is mitigated by (1) being limiting to only instances where we have a hidden
+    editable area, and (2) being limited by a batching mechanism in the web process, such that if the focused
+    element is blurred, refocused, re-blurred, and refocused many times in the same runloop, we'll only send a
+    single UpdateInputContextAfterBlurringAndRefocusingElement message (as opposed to the many ElementDidFocus
+    messages we would've sent in previous releases).
+    
+    * Platform/spi/ios/UIKitSPI.h:
+    * UIProcess/PageClient.h:
+    * UIProcess/WebPageProxy.h:
+    * UIProcess/WebPageProxy.messages.in:
+    
+    Add a new mechanism to update the platform input context (on iOS, UIKeyboardImpl's document state) when focus
+    moves away from and immediately returns to a hidden editable element.
+    
+    * UIProcess/ios/PageClientImplIOS.h:
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::updateInputContextAfterBlurringAndRefocusingElement):
+    * UIProcess/ios/WKContentViewInteraction.h:
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView _updateInputContextAfterBlurringAndRefocusingElement]):
+    
+    Tell the active UIKeyboardImpl to refetch document state from the WKContentView. While this does result in a new
+    autocorrection context request (which, unfortunately, triggers synchronous IPC to the web process), this request
+    would've still happened anyways in the case where we would previously have sent an ElementDidFocus message.
+    
+    * UIProcess/ios/WebPageProxyIOS.mm:
+    (WebKit::WebPageProxy::updateInputContextAfterBlurringAndRefocusingElement):
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::elementDidFocus):
+    
+    In the case where we avoid sending a full ElementDidFocus message to the UI process due to refocusing the same
+    element, we should still notify the UI process so that it can synchronize state between the application process
+    and kbd. See above for more details.
+    
+    (WebKit::WebPage::elementDidBlur):
+    (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):
+    
+    LayoutTests:
+    
+    Add a new layout test to verify that we suppress text interactions when focusing an editable element inside an
+    empty, borderless subframe.
+    
+    * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe-expected.txt: Added.
+    * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249006 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-08-22  Wenson Hsieh  <[email protected]>
+
+            Typing Korean in title field after typing in the body inserts extraneous characters on blog.naver.com
+            https://bugs.webkit.org/show_bug.cgi?id=201023
+            <rdar://problem/54294794>
+
+            Reviewed by Ryosuke Niwa.
+
+            Ensures that we recognize the blog editor on blog.naver.com to be a hidden editable area. This website places
+            focus inside an editable body element of a subframe that is completely empty (width: 0 and border: 0). See the
+            WebKit ChangeLog for more details.
+
+            Test: editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html
+
+            * rendering/RenderLayer.cpp:
+            (WebCore::RenderLayer::calculateClipRects const):
+
+2019-08-22  Kocsen Chung  <[email protected]>
+
         Cherry-pick r248977. rdar://problem/54599960
 
     Do not adjust viewport if editing selection is already visible

Modified: branches/safari-608-branch/Source/WebCore/rendering/RenderLayer.cpp (249011 => 249012)


--- branches/safari-608-branch/Source/WebCore/rendering/RenderLayer.cpp	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebCore/rendering/RenderLayer.cpp	2019-08-22 16:20:34 UTC (rev 249012)
@@ -6818,6 +6818,9 @@
         if (!renderViewLayer)
             return false;
 
+        if (is<HTMLFrameOwnerElement>(layer.renderer().element()) && layer.visibleSize().isEmpty())
+            return true;
+
         LayoutRect layerBounds;
         ClipRect backgroundRect;
         ClipRect foregroundRect;

Modified: branches/safari-608-branch/Source/WebKit/ChangeLog (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/ChangeLog	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/ChangeLog	2019-08-22 16:20:34 UTC (rev 249012)
@@ -1,3 +1,173 @@
+2019-08-22  Kocsen Chung  <[email protected]>
+
+        Cherry-pick r249006. rdar://problem/54600921
+
+    Typing Korean in title field after typing in the body inserts extraneous characters on blog.naver.com
+    https://bugs.webkit.org/show_bug.cgi?id=201023
+    <rdar://problem/54294794>
+    
+    Reviewed by Ryosuke Niwa.
+    
+    Source/WebCore:
+    
+    Ensures that we recognize the blog editor on blog.naver.com to be a hidden editable area. This website places
+    focus inside an editable body element of a subframe that is completely empty (width: 0 and border: 0). See the
+    WebKit ChangeLog for more details.
+    
+    Test: editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html
+    
+    * rendering/RenderLayer.cpp:
+    (WebCore::RenderLayer::calculateClipRects const):
+    
+    Source/WebKit:
+    
+    After r242833, we began to avoid sending redundant ElementDidFocus updates in the case where a focused element
+    was blurred and refocused within the same runloop. This was done to prevent the input view from flickering due
+    to input view reloading, as well as scrolling to reveal the focused element, when tapping to change selection on
+    Microsoft Word online.
+    
+    However, on blog.naver.com, these ElementDidFocus messages were necessary in order to ensure that the platform
+    input context changes when moving between the title and body fields, or when tapping to change selection. This
+    is because blog.naver.com uses a hidden contenteditable area under a subframe (see WebCore ChangeLog for more
+    detail here). While text is never directly inserted into this hidden contenteditable, the events are observed
+    and used to "play back" editing in the main visible content area.
+    
+    Thus, when moving between the title and body fields (or when changing selection within either), the only hint we
+    get is that the hidden editable element is blurred and immediately refocused. Since we no longer send
+    ElementDidFocus updates in this scenario, UIKeyboardImpl and kbd are not aware that the page has effectively
+    changed input contexts.
+    
+    Combined with the fact that Korean IME on iOS may insert additional text given the document context (i.e. text
+    that the input manager, kbd, thinks we've previously inserted), this means that when typing several characters
+    into the body field on naver and then switching to edit the title, initial keystrokes may insert unexpected
+    text in the title field.
+    
+    To fix this, we add some hooks to notify the UI process when an element that was blurred has been immediately
+    refocused. Upon receiving this message, the UI process then tells UIKeyboardImpl to re-retrieve its input
+    context, which calls into -requestAutocorrectionContextWithCompletionHandler: in WKContentView. While notorious
+    for being synchronous IPC, this is mitigated by (1) being limiting to only instances where we have a hidden
+    editable area, and (2) being limited by a batching mechanism in the web process, such that if the focused
+    element is blurred, refocused, re-blurred, and refocused many times in the same runloop, we'll only send a
+    single UpdateInputContextAfterBlurringAndRefocusingElement message (as opposed to the many ElementDidFocus
+    messages we would've sent in previous releases).
+    
+    * Platform/spi/ios/UIKitSPI.h:
+    * UIProcess/PageClient.h:
+    * UIProcess/WebPageProxy.h:
+    * UIProcess/WebPageProxy.messages.in:
+    
+    Add a new mechanism to update the platform input context (on iOS, UIKeyboardImpl's document state) when focus
+    moves away from and immediately returns to a hidden editable element.
+    
+    * UIProcess/ios/PageClientImplIOS.h:
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::updateInputContextAfterBlurringAndRefocusingElement):
+    * UIProcess/ios/WKContentViewInteraction.h:
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView _updateInputContextAfterBlurringAndRefocusingElement]):
+    
+    Tell the active UIKeyboardImpl to refetch document state from the WKContentView. While this does result in a new
+    autocorrection context request (which, unfortunately, triggers synchronous IPC to the web process), this request
+    would've still happened anyways in the case where we would previously have sent an ElementDidFocus message.
+    
+    * UIProcess/ios/WebPageProxyIOS.mm:
+    (WebKit::WebPageProxy::updateInputContextAfterBlurringAndRefocusingElement):
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::elementDidFocus):
+    
+    In the case where we avoid sending a full ElementDidFocus message to the UI process due to refocusing the same
+    element, we should still notify the UI process so that it can synchronize state between the application process
+    and kbd. See above for more details.
+    
+    (WebKit::WebPage::elementDidBlur):
+    (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):
+    
+    LayoutTests:
+    
+    Add a new layout test to verify that we suppress text interactions when focusing an editable element inside an
+    empty, borderless subframe.
+    
+    * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe-expected.txt: Added.
+    * editing/selection/ios/do-not-show-selection-in-empty-borderless-subframe.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249006 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-08-22  Wenson Hsieh  <[email protected]>
+
+            Typing Korean in title field after typing in the body inserts extraneous characters on blog.naver.com
+            https://bugs.webkit.org/show_bug.cgi?id=201023
+            <rdar://problem/54294794>
+
+            Reviewed by Ryosuke Niwa.
+
+            After r242833, we began to avoid sending redundant ElementDidFocus updates in the case where a focused element
+            was blurred and refocused within the same runloop. This was done to prevent the input view from flickering due
+            to input view reloading, as well as scrolling to reveal the focused element, when tapping to change selection on
+            Microsoft Word online.
+
+            However, on blog.naver.com, these ElementDidFocus messages were necessary in order to ensure that the platform
+            input context changes when moving between the title and body fields, or when tapping to change selection. This
+            is because blog.naver.com uses a hidden contenteditable area under a subframe (see WebCore ChangeLog for more
+            detail here). While text is never directly inserted into this hidden contenteditable, the events are observed
+            and used to "play back" editing in the main visible content area.
+
+            Thus, when moving between the title and body fields (or when changing selection within either), the only hint we
+            get is that the hidden editable element is blurred and immediately refocused. Since we no longer send
+            ElementDidFocus updates in this scenario, UIKeyboardImpl and kbd are not aware that the page has effectively
+            changed input contexts.
+
+            Combined with the fact that Korean IME on iOS may insert additional text given the document context (i.e. text
+            that the input manager, kbd, thinks we've previously inserted), this means that when typing several characters
+            into the body field on naver and then switching to edit the title, initial keystrokes may insert unexpected
+            text in the title field.
+
+            To fix this, we add some hooks to notify the UI process when an element that was blurred has been immediately
+            refocused. Upon receiving this message, the UI process then tells UIKeyboardImpl to re-retrieve its input
+            context, which calls into -requestAutocorrectionContextWithCompletionHandler: in WKContentView. While notorious
+            for being synchronous IPC, this is mitigated by (1) being limiting to only instances where we have a hidden
+            editable area, and (2) being limited by a batching mechanism in the web process, such that if the focused
+            element is blurred, refocused, re-blurred, and refocused many times in the same runloop, we'll only send a
+            single UpdateInputContextAfterBlurringAndRefocusingElement message (as opposed to the many ElementDidFocus
+            messages we would've sent in previous releases).
+
+            * Platform/spi/ios/UIKitSPI.h:
+            * UIProcess/PageClient.h:
+            * UIProcess/WebPageProxy.h:
+            * UIProcess/WebPageProxy.messages.in:
+
+            Add a new mechanism to update the platform input context (on iOS, UIKeyboardImpl's document state) when focus
+            moves away from and immediately returns to a hidden editable element.
+
+            * UIProcess/ios/PageClientImplIOS.h:
+            * UIProcess/ios/PageClientImplIOS.mm:
+            (WebKit::PageClientImpl::updateInputContextAfterBlurringAndRefocusingElement):
+            * UIProcess/ios/WKContentViewInteraction.h:
+            * UIProcess/ios/WKContentViewInteraction.mm:
+            (-[WKContentView _updateInputContextAfterBlurringAndRefocusingElement]):
+
+            Tell the active UIKeyboardImpl to refetch document state from the WKContentView. While this does result in a new
+            autocorrection context request (which, unfortunately, triggers synchronous IPC to the web process), this request
+            would've still happened anyways in the case where we would previously have sent an ElementDidFocus message.
+
+            * UIProcess/ios/WebPageProxyIOS.mm:
+            (WebKit::WebPageProxy::updateInputContextAfterBlurringAndRefocusingElement):
+            * WebProcess/WebPage/WebPage.cpp:
+            (WebKit::WebPage::elementDidFocus):
+
+            In the case where we avoid sending a full ElementDidFocus message to the UI process due to refocusing the same
+            element, we should still notify the UI process so that it can synchronize state between the application process
+            and kbd. See above for more details.
+
+            (WebKit::WebPage::elementDidBlur):
+            (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):
+            * WebProcess/WebPage/WebPage.h:
+            * WebProcess/WebPage/ios/WebPageIOS.mm:
+            (WebKit::WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded):
+
 2019-08-21  Kocsen Chung  <[email protected]>
 
         Cherry-pick r248974. rdar://problem/54579634

Modified: branches/safari-608-branch/Source/WebKit/Platform/spi/ios/UIKitSPI.h (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2019-08-22 16:20:34 UTC (rev 249012)
@@ -270,6 +270,7 @@
 
 @interface UIKeyboardImpl : UIView <UIKeyboardCandidateListDelegate>
 - (BOOL)smartInsertDeleteIsEnabled;
+- (void)updateForChangedSelection;
 @end
 
 @interface UIKeyboardImpl ()

Modified: branches/safari-608-branch/Source/WebKit/UIProcess/PageClient.h (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/UIProcess/PageClient.h	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/UIProcess/PageClient.h	2019-08-22 16:20:34 UTC (rev 249012)
@@ -385,6 +385,7 @@
     virtual void restorePageCenterAndScale(Optional<WebCore::FloatPoint> center, double scale) = 0;
 
     virtual void elementDidFocus(const FocusedElementInformation&, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, API::Object* userData) = 0;
+    virtual void updateInputContextAfterBlurringAndRefocusingElement() = 0;
     virtual void elementDidBlur() = 0;
     virtual void focusedElementDidChangeInputMode(WebCore::InputMode) = 0;
     virtual void didReceiveEditorStateUpdateAfterFocus() = 0;

Modified: branches/safari-608-branch/Source/WebKit/UIProcess/WebPageProxy.h (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/UIProcess/WebPageProxy.h	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/UIProcess/WebPageProxy.h	2019-08-22 16:20:34 UTC (rev 249012)
@@ -1943,6 +1943,7 @@
 
     void elementDidFocus(const FocusedElementInformation&, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, const UserData&);
     void elementDidBlur();
+    void updateInputContextAfterBlurringAndRefocusingElement();
     void focusedElementDidChangeInputMode(WebCore::InputMode);
     void didReleaseAllTouchPoints();
     void didReceiveEditorStateUpdateAfterFocus();

Modified: branches/safari-608-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in	2019-08-22 16:20:34 UTC (rev 249012)
@@ -408,6 +408,7 @@
 
     ElementDidFocus(struct WebKit::FocusedElementInformation information, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, WebKit::UserData userData)
     ElementDidBlur()
+    UpdateInputContextAfterBlurringAndRefocusingElement()
     FocusedElementDidChangeInputMode(enum:uint8_t WebCore::InputMode mode)
     ScrollingNodeScrollWillStartScroll()
     ScrollingNodeScrollDidEndScroll()

Modified: branches/safari-608-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h	2019-08-22 16:20:34 UTC (rev 249012)
@@ -149,6 +149,7 @@
     void restorePageCenterAndScale(Optional<WebCore::FloatPoint>, double) override;
 
     void elementDidFocus(const FocusedElementInformation&, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, API::Object* userData) override;
+    void updateInputContextAfterBlurringAndRefocusingElement() final;
     void elementDidBlur() override;
     void focusedElementDidChangeInputMode(WebCore::InputMode) override;
     void didReceiveEditorStateUpdateAfterFocus() override;

Modified: branches/safari-608-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm	2019-08-22 16:20:34 UTC (rev 249012)
@@ -560,6 +560,11 @@
     [m_contentView _elementDidFocus:nodeInformation userIsInteracting:userIsInteracting blurPreviousNode:blurPreviousNode activityStateChanges:activityStateChanges userObject:userObject];
 }
 
+void PageClientImpl::updateInputContextAfterBlurringAndRefocusingElement()
+{
+    [m_contentView _updateInputContextAfterBlurringAndRefocusingElement];
+}
+
 bool PageClientImpl::isFocusingElement()
 {
     return [m_contentView isFocusingElement];

Modified: branches/safari-608-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2019-08-22 16:20:34 UTC (rev 249012)
@@ -457,6 +457,7 @@
 - (void)_disableDoubleTapGesturesDuringTapIfNecessary:(uint64_t)requestID;
 - (void)_handleSmartMagnificationInformationForPotentialTap:(uint64_t)requestID renderRect:(const WebCore::FloatRect&)renderRect fitEntireRect:(BOOL)fitEntireRect viewportMinimumScale:(double)viewportMinimumScale viewportMaximumScale:(double)viewportMaximumScale;
 - (void)_elementDidFocus:(const WebKit::FocusedElementInformation&)information userIsInteracting:(BOOL)userIsInteracting blurPreviousNode:(BOOL)blurPreviousNode activityStateChanges:(OptionSet<WebCore::ActivityState::Flag>)activityStateChanges userObject:(NSObject <NSSecureCoding> *)userObject;
+- (void)_updateInputContextAfterBlurringAndRefocusingElement;
 - (void)_elementDidBlur;
 - (void)_hideContextMenuHintContainer;
 - (void)_didUpdateInputMode:(WebCore::InputMode)mode;

Modified: branches/safari-608-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-08-22 16:20:34 UTC (rev 249012)
@@ -5494,6 +5494,14 @@
         _didAccessoryTabInitiateFocus = NO;
 }
 
+- (void)_updateInputContextAfterBlurringAndRefocusingElement
+{
+    if (!hasFocusedElement(_focusedElementInformation) || !_suppressSelectionAssistantReasons)
+        return;
+
+    [UIKeyboardImpl.activeInstance updateForChangedSelection];
+}
+
 - (BOOL)shouldIgnoreKeyboardWillHideNotification
 {
     // Ignore keyboard will hide notifications sent during rotation. They're just there for

Modified: branches/safari-608-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2019-08-22 16:20:34 UTC (rev 249012)
@@ -904,6 +904,11 @@
     process().send(Messages::WebPage::SetIsShowingInputViewForFocusedElement(showingInputView), m_pageID);
 }
 
+void WebPageProxy::updateInputContextAfterBlurringAndRefocusingElement()
+{
+    pageClient().updateInputContextAfterBlurringAndRefocusingElement();
+}
+
 void WebPageProxy::elementDidFocus(const FocusedElementInformation& information, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, const UserData& userData)
 {
     m_pendingInputModeChange = WTF::nullopt;

Modified: branches/safari-608-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2019-08-22 16:20:34 UTC (rev 249012)
@@ -5469,6 +5469,7 @@
 void WebPage::elementDidFocus(WebCore::Element& element)
 {
     if (!shouldDispatchUpdateAfterFocusingElement(element)) {
+        updateInputContextAfterBlurringAndRefocusingElementIfNeeded(element);
         m_focusedElement = &element;
         m_recentlyBlurredElement = nullptr;
         return;
@@ -5476,6 +5477,7 @@
 
     if (is<HTMLSelectElement>(element) || isTextFormControlOrEditableContent(element)) {
         m_focusedElement = &element;
+        m_hasPendingInputContextUpdateAfterBlurringAndRefocusingElement = false;
 
 #if PLATFORM(IOS_FAMILY)
 
@@ -5517,6 +5519,7 @@
             }
             protectedThis->m_recentlyBlurredElement = nullptr;
         });
+        m_hasPendingInputContextUpdateAfterBlurringAndRefocusingElement = false;
     }
 }
 
@@ -6695,6 +6698,10 @@
     return { };
 }
 
+void WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded(Element&)
+{
+}
+
 #endif // !PLATFORM(IOS_FAMILY)
 
 static IntRect elementRectInRootViewCoordinates(const Element& element, const Frame& frame)

Modified: branches/safari-608-branch/Source/WebKit/WebProcess/WebPage/WebPage.h (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/WebProcess/WebPage/WebPage.h	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/WebProcess/WebPage/WebPage.h	2019-08-22 16:20:34 UTC (rev 249012)
@@ -603,6 +603,7 @@
     void elementDidBlur(WebCore::Element&);
     void focusedElementDidChangeInputMode(WebCore::Element&, WebCore::InputMode);
     void resetFocusedElementForFrame(WebFrame*);
+    void updateInputContextAfterBlurringAndRefocusingElementIfNeeded(WebCore::Element&);
 
     void disabledAdaptationsDidChange(const OptionSet<WebCore::DisabledAdaptations>&);
     void viewportPropertiesDidChange(const WebCore::ViewportArguments&);
@@ -1824,6 +1825,7 @@
 
     RefPtr<WebCore::Element> m_focusedElement;
     RefPtr<WebCore::Element> m_recentlyBlurredElement;
+    bool m_hasPendingInputContextUpdateAfterBlurringAndRefocusingElement { false };
     bool m_hasPendingEditorStateUpdate { false };
 
 #if ENABLE(IOS_TOUCH_EVENTS)

Modified: branches/safari-608-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (249011 => 249012)


--- branches/safari-608-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2019-08-22 15:47:23 UTC (rev 249011)
+++ branches/safari-608-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2019-08-22 16:20:34 UTC (rev 249012)
@@ -1170,6 +1170,19 @@
         node->inspect();
 }
 
+void WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded(Element& element)
+{
+    if (m_recentlyBlurredElement != &element || !m_isShowingInputViewForFocusedElement)
+        return;
+
+    m_hasPendingInputContextUpdateAfterBlurringAndRefocusingElement = true;
+    callOnMainThread([this, protectedThis = makeRefPtr(this)] {
+        if (m_hasPendingInputContextUpdateAfterBlurringAndRefocusingElement)
+            send(Messages::WebPageProxy::UpdateInputContextAfterBlurringAndRefocusingElement());
+        m_hasPendingInputContextUpdateAfterBlurringAndRefocusingElement = false;
+    });
+}
+
 void WebPage::blurFocusedElement()
 {
     if (!m_focusedElement)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to