[iOS] Native selection views sometimes appear in hidden editable areas after losing...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Mar 2019 21:22:53 +0000 (21:22 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Mar 2019 21:22:53 +0000 (21:22 +0000)
commit9f18985910880698419c850c92ab15875b4f2016
tree41af4dc33b81cd0a5b618e5080533e2a1914f158
parent267c302948a181950a4e847b07b93e165a039972
[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.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243102 268f45cc-cd09-0410-ab3c-d52691b4dbfc
12 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element-expected.txt [new file with mode: 0644]
LayoutTests/editing/selection/ios/hide-selection-in-non-focused-element.html [new file with mode: 0644]
Source/WebKit/ChangeLog
Source/WebKit/Shared/EditorState.cpp
Source/WebKit/Shared/EditorState.h
Source/WebKit/Shared/FocusedElementInformation.cpp
Source/WebKit/Shared/FocusedElementInformation.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm