<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[243102] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/243102">243102</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2019-03-18 14:22:53 -0700 (Mon, 18 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS] Native selection views sometimes appear in hidden editable areas after losing focus
https://bugs.webkit.org/show_bug.cgi?id=195894
<rdar://problem/48849989>

Reviewed by Tim Horton.

Source/WebKit:

On certain websites, focus is moved away from an editable element while maintaining a selection inside the
editable element. In the case where the editable element is hidden, this currently breaks our text interaction
suppression heuristics, which suppress text selection gestures and overlays inside focused hidden editable
elements. To fix this, we refactor our text interaction suppression heuristics, such that they are not dependent
on an editable element being focused. See changes below for more details.

Test: editing/selection/ios/hide-selection-in-non-focused-element.html

* Shared/EditorState.cpp:
(WebKit::EditorState::PostLayoutData::encode const):
(WebKit::EditorState::PostLayoutData::decode):
* Shared/EditorState.h:

Rename elementIsTransparentOrFullyClipped to editableRootIsTransparentOrFullyClipped, and additionally compute
this flag by checking whether the root editable element containing the selection is transparent or clipped,
instead of using the currently focused element.

* Shared/FocusedElementInformation.cpp:
(WebKit::FocusedElementInformation::encode const):
(WebKit::FocusedElementInformation::decode):
* Shared/FocusedElementInformation.h:

Remove the elementIsTransparentOrFullyClipped flag from FocusedElementInformation (see below for more detail).

* UIProcess/ios/WKContentViewInteraction.h:

Rename FocusedElementIsTransparentOrFullyClipped to EditableRootIsTransparentOrFullyClipped.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _zoomToRevealFocusedElement]):
(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):

Remove logic that currently uses state on FocusedElementInformation to determine whether to suppress platform
text interactions; instead, only use EditorState to make this determination. This logic was originally added in
the initial implementation of the text interaction suppression heuristic as a way to begin suppressing text
selection state before zooming to reveal the focused element; however, since we now zoom to reveal the text
selection when focusing editable elements, zooming is deferred until the next complete EditorState update
arrives in the UI process so we don't need to worry about beginning to suppress text interactions prior to this
initial editor state update.

(-[WKContentView _elementDidBlur]):
(-[WKContentView _updateSelectionAssistantSuppressionState]):

Add a helper method that updates text selection suppression state using the current EditorState.

(-[WKContentView _selectionChanged]):
(-[WKContentView _updateChangedSelection:]):

Always update text suppression state when receiving an EditorState, instead of only doing so when processing a
text selection gesture.

(-[WKContentView _startSuppressingSelectionAssistantForReason:]):

Renamed from _beginSuppressingSelectionAssistantForReason:, to better match "start/end" terminology of
_endSuppressingSelectionAssistantForReason:.

(-[WKContentView dropInteraction:performDrop:]):
(-[WKContentView _beginSuppressingSelectionAssistantForReason:]): Deleted.
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::editorStateChanged):

Ensure that we run logic to zoom to the focused element *after* updating text selection suppression state, so we
don't erroneously zoom to reveal hidden editable elements.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::platformEditorState const):
(WebKit::WebPage::getFocusedElementInformation):

LayoutTests:

Add a test to verify that moving focus away from a hidden editable element doesn't cause platform selection
views in the element to appear. See WebKit ChangeLog for more details.

* editing/selection/ios/hide-selection-in-non-focused-element-expected.txt: Added.
* editing/selection/ios/hide-selection-in-non-focused-element.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitSharedEditorStatecpp">trunk/Source/WebKit/Shared/EditorState.cpp</a></li>
<li><a href="#trunkSourceWebKitSharedEditorStateh">trunk/Source/WebKit/Shared/EditorState.h</a></li>
<li><a href="#trunkSourceWebKitSharedFocusedElementInformationcpp">trunk/Source/WebKit/Shared/FocusedElementInformation.cpp</a></li>
<li><a href="#trunkSourceWebKitSharedFocusedElementInformationh">trunk/Source/WebKit/Shared/FocusedElementInformation.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosWKContentViewInteractionh">trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosWKContentViewInteractionmm">trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosWebPageProxyIOSmm">trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm</a></li>
<li><a href="#trunkSourceWebKitWebProcessWebPageiosWebPageIOSmm">trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestseditingselectionioshideselectioninnonfocusedelementexpectedtxt">trunk/LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element-expected.txt</a></li>
<li><a href="#trunkLayoutTestseditingselectionioshideselectioninnonfocusedelementhtml">trunk/LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/LayoutTests/ChangeLog 2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2019-03-18  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS] Native selection views sometimes appear in hidden editable areas after losing focus
+        https://bugs.webkit.org/show_bug.cgi?id=195894
+        <rdar://problem/48849989>
+
+        Reviewed by Tim Horton.
+
+        Add a test to verify that moving focus away from a hidden editable element doesn't cause platform selection
+        views in the element to appear. See WebKit ChangeLog for more details.
+
+        * editing/selection/ios/hide-selection-in-non-focused-element-expected.txt: Added.
+        * editing/selection/ios/hide-selection-in-non-focused-element.html: Added.
+
</ins><span class="cx"> 2019-03-18  Antti Koivisto  <antti@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Layer with no backing store should still hit-test over a scroller
</span></span></pre></div>
<a id="trunkLayoutTestseditingselectionioshideselectioninnonfocusedelementexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element-expected.txt (0 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element-expected.txt                               (rev 0)
+++ trunk/LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element-expected.txt  2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+Hello world
+
+Verifies that text selection is suppressed when the selected content is in a hidden editable root, even when focusing a different element. To manually run the test, tap the editable area in the red box, and then tap the button below it. Platform selection views should not become visible.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS selectionRects.length is 0
+PASS getSelection().toString() is "Hello world"
+PASS document.activeElement is focusTarget
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestseditingselectionioshideselectioninnonfocusedelementhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element.html (0 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element.html                               (rev 0)
+++ trunk/LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element.html  2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<style>
+body {
+    width: 100%;
+    height: 100%;
+    margin: 0;
+}
+
+#editor {
+    width: 100%;
+    height: 100%;
+    opacity: 0;
+}
+
+#container {
+    width: 320px;
+    height: 100px;
+    border: 1px solid tomato;
+}
+
+#target {
+    width: 1em;
+    height: 1em;
+}
+
+input {
+    width: 320px;
+    height: 3em;
+}
+</style>
+<script>
+addEventListener("load", runTest);
+jsTestIsAsync = true;
+
+async function runTest() {
+    description("Verifies that text selection is suppressed when the selected content is in a hidden editable root, even when focusing a different element. To manually run the test, tap the editable area in the red box, and then tap the button below it. Platform selection views should not become visible.");
+
+    button = document.querySelector("input");
+    editor = document.getElementById("editor");
+    focusTarget = document.getElementById("focus-target");
+    editor.addEventListener("focus", () => getSelection().selectAllChildren(editor));
+    button.addEventListener("click", () => {
+        event.preventDefault();
+        focusTarget.focus();
+    });
+
+    if (!window.testRunner)
+        return;
+
+    await UIHelper.activateElementAndWaitForInputSession(editor);
+    await UIHelper.activateElement(button);
+    await UIHelper.waitForKeyboardToHide();
+    selectionRects = await UIHelper.getUISelectionViewRects();
+
+    shouldBe("selectionRects.length", "0");
+    shouldBeEqualToString("getSelection().toString()", "Hello world");
+    shouldBe("document.activeElement", "focusTarget");
+
+    finishJSTest();
+}
+</script>
+</head>
+<body>
+<div id="container">
+    <div id="editor" contenteditable>Hello world</div>
+</div>
+<div tabindex="0" id="focus-target"></div>
+<input type="button" value="Press me">
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/Source/WebKit/ChangeLog       2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -1,3 +1,79 @@
</span><ins>+2019-03-18  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS] Native selection views sometimes appear in hidden editable areas after losing focus
+        https://bugs.webkit.org/show_bug.cgi?id=195894
+        <rdar://problem/48849989>
+
+        Reviewed by Tim Horton.
+
+        On certain websites, focus is moved away from an editable element while maintaining a selection inside the
+        editable element. In the case where the editable element is hidden, this currently breaks our text interaction
+        suppression heuristics, which suppress text selection gestures and overlays inside focused hidden editable
+        elements. To fix this, we refactor our text interaction suppression heuristics, such that they are not dependent
+        on an editable element being focused. See changes below for more details.
+
+        Test: editing/selection/ios/hide-selection-in-non-focused-element.html
+
+        * Shared/EditorState.cpp:
+        (WebKit::EditorState::PostLayoutData::encode const):
+        (WebKit::EditorState::PostLayoutData::decode):
+        * Shared/EditorState.h:
+
+        Rename elementIsTransparentOrFullyClipped to editableRootIsTransparentOrFullyClipped, and additionally compute
+        this flag by checking whether the root editable element containing the selection is transparent or clipped,
+        instead of using the currently focused element.
+
+        * Shared/FocusedElementInformation.cpp:
+        (WebKit::FocusedElementInformation::encode const):
+        (WebKit::FocusedElementInformation::decode):
+        * Shared/FocusedElementInformation.h:
+
+        Remove the elementIsTransparentOrFullyClipped flag from FocusedElementInformation (see below for more detail).
+
+        * UIProcess/ios/WKContentViewInteraction.h:
+
+        Rename FocusedElementIsTransparentOrFullyClipped to EditableRootIsTransparentOrFullyClipped.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _zoomToRevealFocusedElement]):
+        (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
+
+        Remove logic that currently uses state on FocusedElementInformation to determine whether to suppress platform
+        text interactions; instead, only use EditorState to make this determination. This logic was originally added in
+        the initial implementation of the text interaction suppression heuristic as a way to begin suppressing text
+        selection state before zooming to reveal the focused element; however, since we now zoom to reveal the text
+        selection when focusing editable elements, zooming is deferred until the next complete EditorState update
+        arrives in the UI process so we don't need to worry about beginning to suppress text interactions prior to this
+        initial editor state update.
+
+        (-[WKContentView _elementDidBlur]):
+        (-[WKContentView _updateSelectionAssistantSuppressionState]):
+
+        Add a helper method that updates text selection suppression state using the current EditorState.
+
+        (-[WKContentView _selectionChanged]):
+        (-[WKContentView _updateChangedSelection:]):
+
+        Always update text suppression state when receiving an EditorState, instead of only doing so when processing a
+        text selection gesture.
+
+        (-[WKContentView _startSuppressingSelectionAssistantForReason:]):
+
+        Renamed from _beginSuppressingSelectionAssistantForReason:, to better match "start/end" terminology of
+        _endSuppressingSelectionAssistantForReason:.
+
+        (-[WKContentView dropInteraction:performDrop:]):
+        (-[WKContentView _beginSuppressingSelectionAssistantForReason:]): Deleted.
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::editorStateChanged):
+
+        Ensure that we run logic to zoom to the focused element *after* updating text selection suppression state, so we
+        don't erroneously zoom to reveal hidden editable elements.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::platformEditorState const):
+        (WebKit::WebPage::getFocusedElementInformation):
+
</ins><span class="cx"> 2019-03-18  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Delay WebProcess launch until a load is triggered in a Web view
</span></span></pre></div>
<a id="trunkSourceWebKitSharedEditorStatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Shared/EditorState.cpp (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Shared/EditorState.cpp       2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/Source/WebKit/Shared/EditorState.cpp  2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx">     encoder << isStableStateUpdate;
</span><span class="cx">     encoder << insideFixedPosition;
</span><span class="cx">     encoder << hasPlainText;
</span><del>-    encoder << elementIsTransparentOrFullyClipped;
</del><ins>+    encoder << editableRootIsTransparentOrFullyClipped;
</ins><span class="cx">     encoder << caretColor;
</span><span class="cx">     encoder << atStartOfSentence;
</span><span class="cx"> #endif
</span><span class="lines">@@ -191,7 +191,7 @@
</span><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(result.hasPlainText))
</span><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.elementIsTransparentOrFullyClipped))
</del><ins>+    if (!decoder.decode(result.editableRootIsTransparentOrFullyClipped))
</ins><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(result.caretColor))
</span><span class="cx">         return false;
</span></span></pre></div>
<a id="trunkSourceWebKitSharedEditorStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Shared/EditorState.h (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Shared/EditorState.h 2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/Source/WebKit/Shared/EditorState.h    2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -109,7 +109,7 @@
</span><span class="cx">         bool isStableStateUpdate { false };
</span><span class="cx">         bool insideFixedPosition { false };
</span><span class="cx">         bool hasPlainText { false };
</span><del>-        bool elementIsTransparentOrFullyClipped { false };
</del><ins>+        bool editableRootIsTransparentOrFullyClipped { false };
</ins><span class="cx">         WebCore::Color caretColor;
</span><span class="cx">         bool atStartOfSentence { false };
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKitSharedFocusedElementInformationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Shared/FocusedElementInformation.cpp (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Shared/FocusedElementInformation.cpp 2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/Source/WebKit/Shared/FocusedElementInformation.cpp    2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -91,7 +91,6 @@
</span><span class="cx">     encoder << title;
</span><span class="cx">     encoder << acceptsAutofilledLoginCredentials;
</span><span class="cx">     encoder << isAutofillableUsernameField;
</span><del>-    encoder << elementIsTransparentOrFullyClipped;
</del><span class="cx">     encoder << representingPageURL;
</span><span class="cx">     encoder.encodeEnum(autofillFieldName);
</span><span class="cx">     encoder << placeholder;
</span><span class="lines">@@ -193,9 +192,6 @@
</span><span class="cx">     if (!decoder.decode(result.isAutofillableUsernameField))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (!decoder.decode(result.elementIsTransparentOrFullyClipped))
-        return false;
-
</del><span class="cx">     if (!decoder.decode(result.representingPageURL))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitSharedFocusedElementInformationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Shared/FocusedElementInformation.h (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Shared/FocusedElementInformation.h   2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/Source/WebKit/Shared/FocusedElementInformation.h      2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -124,7 +124,6 @@
</span><span class="cx">     String title;
</span><span class="cx">     bool acceptsAutofilledLoginCredentials { false };
</span><span class="cx">     bool isAutofillableUsernameField { false };
</span><del>-    bool elementIsTransparentOrFullyClipped { false };
</del><span class="cx">     URL representingPageURL;
</span><span class="cx">     WebCore::AutofillFieldName autofillFieldName { WebCore::AutofillFieldName::None };
</span><span class="cx">     String placeholder;
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosWKContentViewInteractionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h     2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h        2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -156,7 +156,7 @@
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><span class="cx"> enum SuppressSelectionAssistantReason : uint8_t {
</span><del>-    FocusedElementIsTransparentOrFullyClipped = 1 << 0,
</del><ins>+    EditableRootIsTransparentOrFullyClipped = 1 << 0,
</ins><span class="cx">     FocusedElementIsTooSmall = 1 << 1,
</span><span class="cx">     DropAnimationIsRunning = 1 << 2
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm    2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm       2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -1615,7 +1615,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_zoomToRevealFocusedElement
</span><span class="cx"> {
</span><del>-    if (_suppressSelectionAssistantReasons.contains(WebKit::FocusedElementIsTransparentOrFullyClipped) || _suppressSelectionAssistantReasons.contains(WebKit::FocusedElementIsTooSmall))
</del><ins>+    if (_suppressSelectionAssistantReasons.contains(WebKit::EditableRootIsTransparentOrFullyClipped) || _suppressSelectionAssistantReasons.contains(WebKit::FocusedElementIsTooSmall))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     SetForScope<BOOL> isZoomingToRevealFocusedElementForScope { _isZoomingToRevealFocusedElement, YES };
</span><span class="lines">@@ -4843,8 +4843,6 @@
</span><span class="cx">     return selectionBoundingRect;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const double minimumFocusedElementAreaForSuppressingSelectionAssistant = 4;
-
</del><span class="cx"> - (void)_elementDidFocus:(const WebKit::FocusedElementInformation&)information userIsInteracting:(BOOL)userIsInteracting blurPreviousNode:(BOOL)blurPreviousNode changingActivityState:(BOOL)changingActivityState userObject:(NSObject <NSSecureCoding> *)userObject
</span><span class="cx"> {
</span><span class="cx">     SetForScope<BOOL> isChangingFocusForScope { _isChangingFocus, hasFocusedElement(_focusedElementInformation) };
</span><span class="lines">@@ -4867,17 +4865,6 @@
</span><span class="cx">     if ([inputDelegate respondsToSelector:@selector(_webView:decidePolicyForFocusedElement:)])
</span><span class="cx">         startInputSessionPolicy = [inputDelegate _webView:_webView decidePolicyForFocusedElement:focusedElementInfo.get()];
</span><span class="cx"> 
</span><del>-    if (information.elementIsTransparentOrFullyClipped)
-        [self _beginSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTransparentOrFullyClipped];
-    else
-        [self _stopSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTransparentOrFullyClipped];
-
-    auto elementArea = information.elementRect.area<RecordOverflow>();
-    if (!elementArea.hasOverflowed() && elementArea < minimumFocusedElementAreaForSuppressingSelectionAssistant)
-        [self _beginSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTooSmall];
-    else
-        [self _stopSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTooSmall];
-
</del><span class="cx">     BOOL shouldShowInputView = [&] {
</span><span class="cx">         switch (startInputSessionPolicy) {
</span><span class="cx">         case _WKFocusStartsInputSessionPolicyAuto:
</span><span class="lines">@@ -5051,11 +5038,8 @@
</span><span class="cx">     [_webView didEndFormControlInteraction];
</span><span class="cx">     _page->setIsShowingInputViewForFocusedElement(false);
</span><span class="cx"> 
</span><del>-    if (!_isChangingFocus) {
-        [self _stopSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTransparentOrFullyClipped];
-        [self _stopSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTooSmall];
</del><ins>+    if (!_isChangingFocus)
</ins><span class="cx">         _didAccessoryTabInitiateFocus = NO;
</span><del>-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_didUpdateInputMode:(WebCore::InputMode)mode
</span><span class="lines">@@ -5474,8 +5458,43 @@
</span><span class="cx">     [super _wheelChangedWithEvent:event];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_updateSelectionAssistantSuppressionState
+{
+    static const double minimumFocusedElementAreaForSuppressingSelectionAssistant = 4;
+
+    auto& editorState = _page->editorState();
+    if (editorState.isMissingPostLayoutData)
+        return;
+
+    BOOL editableRootIsTransparentOrFullyClipped = NO;
+    BOOL focusedElementIsTooSmall = NO;
+    if (!editorState.selectionIsNone) {
+        auto& postLayoutData = editorState.postLayoutData();
+        if (postLayoutData.editableRootIsTransparentOrFullyClipped)
+            editableRootIsTransparentOrFullyClipped = YES;
+
+        if (hasFocusedElement(_focusedElementInformation)) {
+            auto elementArea = postLayoutData.focusedElementRect.area<RecordOverflow>();
+            if (!elementArea.hasOverflowed() && elementArea < minimumFocusedElementAreaForSuppressingSelectionAssistant)
+                focusedElementIsTooSmall = YES;
+        }
+    }
+
+    if (editableRootIsTransparentOrFullyClipped)
+        [self _startSuppressingSelectionAssistantForReason:WebKit::EditableRootIsTransparentOrFullyClipped];
+    else
+        [self _stopSuppressingSelectionAssistantForReason:WebKit::EditableRootIsTransparentOrFullyClipped];
+
+    if (focusedElementIsTooSmall)
+        [self _startSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTooSmall];
+    else
+        [self _stopSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTooSmall];
+}
+
</ins><span class="cx"> - (void)_selectionChanged
</span><span class="cx"> {
</span><ins>+    [self _updateSelectionAssistantSuppressionState];
+
</ins><span class="cx">     _selectionNeedsUpdate = YES;
</span><span class="cx">     // If we are changing the selection with a gesture there is no need
</span><span class="cx">     // to wait to paint the selection.
</span><span class="lines">@@ -5502,20 +5521,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     auto& postLayoutData = state.postLayoutData();
</span><del>-    if (!state.selectionIsNone && hasFocusedElement(_focusedElementInformation)) {
-        if (postLayoutData.elementIsTransparentOrFullyClipped)
-            [self _beginSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTransparentOrFullyClipped];
-        else
-            [self _stopSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTransparentOrFullyClipped];
-
-        auto elementArea = postLayoutData.focusedElementRect.area<RecordOverflow>();
-        if (!elementArea.hasOverflowed() && elementArea < minimumFocusedElementAreaForSuppressingSelectionAssistant)
-            [self _beginSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTooSmall];
-        else
-            [self _stopSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTooSmall];
-    }
-
-    WebKit::WKSelectionDrawingInfo selectionDrawingInfo(_page->editorState());
</del><ins>+    WebKit::WKSelectionDrawingInfo selectionDrawingInfo(state);
</ins><span class="cx">     if (force || selectionDrawingInfo != _lastSelectionDrawingInfo) {
</span><span class="cx">         LOG_WITH_STREAM(Selection, stream << "_updateChangedSelection " << selectionDrawingInfo);
</span><span class="cx"> 
</span><span class="lines">@@ -5552,7 +5558,7 @@
</span><span class="cx">     return !!_suppressSelectionAssistantReasons;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)_beginSuppressingSelectionAssistantForReason:(WebKit::SuppressSelectionAssistantReason)reason
</del><ins>+- (void)_startSuppressingSelectionAssistantForReason:(WebKit::SuppressSelectionAssistantReason)reason
</ins><span class="cx"> {
</span><span class="cx">     bool wasSuppressingSelectionAssistant = !!_suppressSelectionAssistantReasons;
</span><span class="cx">     _suppressSelectionAssistantReasons.add(reason);
</span><span class="lines">@@ -6551,7 +6557,7 @@
</span><span class="cx">         retainedSelf->_page->performDragOperation(capturedDragData, "data interaction pasteboard", WTFMove(sandboxExtensionHandle), WTFMove(sandboxExtensionForUpload));
</span><span class="cx"> 
</span><span class="cx">         retainedSelf->_visibleContentViewSnapshot = [retainedSelf snapshotViewAfterScreenUpdates:NO];
</span><del>-        [retainedSelf _beginSuppressingSelectionAssistantForReason:WebKit::DropAnimationIsRunning];
</del><ins>+        [retainedSelf _startSuppressingSelectionAssistantForReason:WebKit::DropAnimationIsRunning];
</ins><span class="cx">         [UIView performWithoutAnimation:[retainedSelf] {
</span><span class="cx">             [retainedSelf->_visibleContentViewSnapshot setFrame:[retainedSelf bounds]];
</span><span class="cx">             [retainedSelf addSubview:retainedSelf->_visibleContentViewSnapshot.get()];
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosWebPageProxyIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm     2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm        2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -1079,11 +1079,6 @@
</span><span class="cx">     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
</span><span class="cx">     
</span><span class="cx">     m_editorState = editorState;
</span><del>-
-    if (m_waitingForPostLayoutEditorStateUpdateAfterFocusingElement && !m_editorState.isMissingPostLayoutData) {
-        pageClient().didReceiveEditorStateUpdateAfterFocus();
-        m_waitingForPostLayoutEditorStateUpdateAfterFocusingElement = false;
-    }
</del><span class="cx">     
</span><span class="cx">     // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood).
</span><span class="cx">     if (couldChangeSecureInputState && !editorState.selectionIsNone)
</span><span class="lines">@@ -1096,6 +1091,11 @@
</span><span class="cx">     // even during composition to support phrase boundary gesture.
</span><span class="cx">     pageClient().selectionDidChange();
</span><span class="cx">     updateFontAttributesAfterEditorStateChange();
</span><ins>+
+    if (m_waitingForPostLayoutEditorStateUpdateAfterFocusingElement && !m_editorState.isMissingPostLayoutData) {
+        pageClient().didReceiveEditorStateUpdateAfterFocus();
+        m_waitingForPostLayoutEditorStateUpdateAfterFocusingElement = false;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::showValidationMessage(const IntRect& anchorClientRect, const String& message)
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (243101 => 243102)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2019-03-18 21:18:13 UTC (rev 243101)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm    2019-03-18 21:22:53 UTC (rev 243102)
</span><span class="lines">@@ -256,8 +256,12 @@
</span><span class="cx">             auto& renderer = *m_focusedElement->renderer();
</span><span class="cx">             postLayoutData.focusedElementRect = view->contentsToRootView(renderer.absoluteBoundingBoxRect());
</span><span class="cx">             postLayoutData.caretColor = renderer.style().caretColor();
</span><del>-            postLayoutData.elementIsTransparentOrFullyClipped = enclosingLayerIsTransparentOrFullyClipped(renderer);
</del><span class="cx">         }
</span><ins>+        if (result.isContentEditable) {
+            auto container = makeRefPtr(selection.rootEditableElement());
+            if (container && container->renderer())
+                postLayoutData.editableRootIsTransparentOrFullyClipped = enclosingLayerIsTransparentOrFullyClipped(*container->renderer());
+        }
</ins><span class="cx">         computeEditableRootHasContentAndPlainText(selection, postLayoutData);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -2535,7 +2539,6 @@
</span><span class="cx">         auto& elementFrame = m_page->focusController().focusedOrMainFrame();
</span><span class="cx">         information.elementRect = elementRectInRootViewCoordinates(*m_focusedElement, elementFrame);
</span><span class="cx">         information.nodeFontSize = renderer->style().fontDescription().computedSize();
</span><del>-        information.elementIsTransparentOrFullyClipped = enclosingLayerIsTransparentOrFullyClipped(*renderer);
</del><span class="cx"> 
</span><span class="cx">         bool inFixed = false;
</span><span class="cx">         renderer->localToContainerPoint(FloatPoint(), nullptr, UseTransforms, &inFixed);
</span></span></pre>
</div>
</div>

</body>
</html>