Native caret shows up alongside the page's caret when requesting desktop site on...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 Jan 2019 18:50:39 +0000 (18:50 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 Jan 2019 18:50:39 +0000 (18:50 +0000)
commit64f7f1c78ac64f57cb922fba585e4e1a7b13ee45
treef306139f8433d7776c759efb30f6d0f4a87438b2
parentdaad713a523bff63364109a20b405f417ddbb7ad
Native caret shows up alongside the page's caret when requesting desktop site on jsfiddle.net
https://bugs.webkit.org/show_bug.cgi?id=193180
<rdar://problem/45971041>

Reviewed by Tim Horton.

Source/WebCore:

Adjust a method on RenderObject to additionally detect when the RenderObject is inside of an `overflow: hidden`
container that is also empty. See WebKit ChangeLog for more details.

Test:   editing/selection/ios/hide-selection-in-empty-overflow-hidden-container.html
        editing/selection/ios/show-selection-in-empty-overflow-hidden-document.html

* rendering/RenderObject.cpp:
(WebCore::RenderObject::isTransparentOrFullyClippedRespectingParentFrames const):
(WebCore::RenderObject::isTransparentRespectingParentFrames const): Deleted.
* rendering/RenderObject.h:

Source/WebKit:

JSFiddle uses CodeMirror; CodeMirror's editor works by capturing keystrokes and input in a hidden textarea
element, and then drawing its own selection caret using web content. This textarea is hidden by being placed
underneath an empty div with `overflow: hidden;`.

When requesting desktop site on iOS, both CodeMirror's caret and the native iOS caret are shown because iOS
selection UI consists of native views overlaid on the page, whereas on macOS, the entire textarea (along with
the caret) are occluded by the hidden overflow container. Additionally, various iOS behaviors related to
selection and editing, such as zooming to reveal the focused element and showing the platform callout bar, are
active when focusing this hidden editable area; these don't work as intended, and just interfere with the page's
custom editing UI.

To fix this, we augment the text interaction suppression mechanism added in r238146 to detect when the focused
element is in an empty `overflow: hidden` container, and bail out of native text editing behaviors.

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

Rename elementIsTransparent to elementIsTransparentOrFullyClipped.

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

Rename FocusedElementIsTransparent to FocusedElementIsTransparentOrFullyClipped.

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

Make an additional tweak here to only stop suppressing text interaction assistant in `-_elementDidBlur` if we're
not also in the middle of changing the focused element. Without this, focusing a hidden editable element while
another hidden editable element is currently focused causes us to zoom to reveal the newly focused hidden
editable element, when we should be avoiding this behavior.

(-[WKContentView _updateChangedSelection:]):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::platformEditorState const):
(WebKit::WebPage::getFocusedElementInformation):

LayoutTests:

* editing/selection/ios/hide-selection-in-empty-overflow-hidden-container-expected.txt: Added.
* editing/selection/ios/hide-selection-in-empty-overflow-hidden-container.html: Added.

Add a layout test to verify that focusing a hidden editable element underneath an empty container with
`overflow: hidden` doesn't cause platform selection UI to appear.

* editing/selection/ios/show-selection-in-empty-overflow-hidden-document-expected.txt: Added.
* editing/selection/ios/show-selection-in-empty-overflow-hidden-document.html: Added.

Add a layout test to verify that native selection UI shows up when the document element is made empty with
`overflow: hidden`, but the focused elements are still visible.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239685 268f45cc-cd09-0410-ab3c-d52691b4dbfc
16 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/selection/ios/hide-selection-in-empty-overflow-hidden-container-expected.txt [new file with mode: 0644]
LayoutTests/editing/selection/ios/hide-selection-in-empty-overflow-hidden-container.html [new file with mode: 0644]
LayoutTests/editing/selection/ios/show-selection-in-empty-overflow-hidden-document-expected.txt [new file with mode: 0644]
LayoutTests/editing/selection/ios/show-selection-in-empty-overflow-hidden-document.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
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/WebProcess/WebPage/ios/WebPageIOS.mm