Changeset 247158 in webkit


Ignore:
Timestamp:
Jul 5, 2019 9:22:42 AM (5 years ago)
Author:
Wenson Hsieh
Message:

Touching media controls sometimes shows software keyboard
https://bugs.webkit.org/show_bug.cgi?id=199490
<rdar://problem/52076270>

Reviewed by Eric Carlson.

Source/WebKit:

In r243044, we added a compatibility hack for Google Slides (and other G-suite properties) to allow the on-
screen keyboard to show up after a prevented touch event in the case where an element was already focused, even
if the touch event handler doesn't explicitly refocus the element. However, this means that if a regular text
field (or other form control) has been programmatically focused, then interacting with any other element that
prevents default on touchstart will cause us to show the keyboard for that focused element.

To mitigate this, only fall down this refocusing codepath in the case where the focused element is a hidden
editable element (in the style of many Google productivity web apps). For non-hidden editable elements that are
already focused, this refocusing logic is not necessary, since the user should be able to interact with the
control to show the keyboard anyways; for hidden editable areas, this compatibility hack is actually needed,
since there is typically no other way for a user to focus these elements and show an on-screen keyboard.

Tests: fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html

fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::dispatchTouchEvent):

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::isTransparentOrFullyClipped const):

Renamed from enclosingLayerIsTransparentOrFullyClipped, and pulled out into a private helper method.

(WebKit::WebPage::platformEditorState const):
(WebKit::WebPage::requestEvasionRectsAboveSelection):
(WebKit::WebPage::getFocusedElementInformation):
(WebKit::enclosingLayerIsTransparentOrFullyClipped): Deleted.

Tools:

Adds plumbing for a new testing hook to check whether or not there is an active input session. See other
ChangeLog entries for more detail.

  • DumpRenderTree/ios/UIScriptControllerIOS.mm:

(WTR::UIScriptController::hasInputSession const):

  • TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
  • TestRunnerShared/UIScriptContext/UIScriptController.cpp:

(WTR::UIScriptController::hasInputSession const):

  • TestRunnerShared/UIScriptContext/UIScriptController.h:
  • WebKitTestRunner/ios/UIScriptControllerIOS.mm:

(WTR::UIScriptController::hasInputSession const):

LayoutTests:

Adds a new layout test to verify that the keyboard only appears after a handled touch event if the focused
element is inside a hidden editable area; otherwise, the keyboard should not be present.

  • fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart-expected.txt: Added.
  • fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html: Added.

This test passes as long as we didn't begin showing the keyboard after tapping.

  • fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt:
  • fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html:

Adjust this existing test to make the focused textarea hidden.

  • resources/ui-helper.js:

(window.UIHelper.hasInputSession):

Add a new testing hook to check whether there is an active input session.

Location:
trunk
Files:
2 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r247148 r247158  
     12019-07-05  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Touching media controls sometimes shows software keyboard
     4        https://bugs.webkit.org/show_bug.cgi?id=199490
     5        <rdar://problem/52076270>
     6
     7        Reviewed by Eric Carlson.
     8
     9        Adds a new layout test to verify that the keyboard only appears after a handled touch event if the focused
     10        element is inside a hidden editable area; otherwise, the keyboard should not be present.
     11
     12        * fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart-expected.txt: Added.
     13        * fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html: Added.
     14
     15        This test passes as long as we didn't begin showing the keyboard after tapping.
     16
     17        * fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt:
     18        * fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html:
     19
     20        Adjust this existing test to make the focused textarea hidden.
     21
     22        * resources/ui-helper.js:
     23        (window.UIHelper.hasInputSession):
     24
     25        Add a new testing hook to check whether there is an active input session.
     26
    1272019-07-05  Antoine Quint  <graouts@apple.com>
    228
  • trunk/LayoutTests/fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt

    r243044 r247158  
    11
    2 Verifies that the keyboard shows up even after preventing default on touchstart. To manually test, tap the textarea; the textarea should remain focused, and the keyboard should appear.
     2Verifies that the keyboard shows up even after preventing default on touchstart when focusing a hidden editable area. To manually test, tap the red box; the textarea should remain focused, and the keyboard should appear.
    33
    44On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
  • trunk/LayoutTests/fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html

    r243044 r247158  
    1111}
    1212
    13 textarea {
     13textarea, #target {
    1414    width: 100%;
    1515    height: 100px;
    16     font-size: 50px;
    17     text-align: center;
     16    position: absolute;
     17    top: 0;
     18}
     19
     20#target {
     21    background-color: tomato;
     22    z-index: 1;
     23    opacity: 0.25;
     24}
     25
     26textarea {
     27    opacity: 0;
     28}
     29
     30#description {
     31    margin-top: 100px;
    1832}
    1933</style>
     
    2135<body>
    2236    <textarea></textarea>
     37    <div id="target"></div>
    2338    <pre id="description"></pre>
    2439    <pre id="console"></pre>
     
    2742    jsTestIsAsync = true;
    2843    textarea = document.querySelector("textarea");
     44    target = document.getElementById("target");
     45    target.addEventListener("touchstart", event => event.preventDefault());
    2946
    30     description("Verifies that the keyboard shows up even after preventing default on touchstart. To manually test, tap the textarea; the textarea should remain focused, and the keyboard should appear.");
     47    description("Verifies that the keyboard shows up even after preventing default on touchstart when focusing a hidden editable area. To manually test, tap the red box; the textarea should remain focused, and the keyboard should appear.");
    3148
    32     textarea.addEventListener("touchstart", event => event.preventDefault());
    3349    addEventListener("load", async () => {
    3450        textarea.focus();
    35         await UIHelper.activateElementAndWaitForInputSession(textarea);
     51        await UIHelper.activateElementAndWaitForInputSession(target);
    3652        testPassed("keyboard was shown.");
    3753        shouldBe("document.activeElement", "textarea");
  • trunk/LayoutTests/resources/ui-helper.js

    r246817 r247158  
    373373    }
    374374
     375    static hasInputSession()
     376    {
     377        return new Promise(resolve => {
     378            testRunner.runUIScript("uiController.hasInputSession", result => resolve(result === "true"));
     379        });
     380    }
     381
    375382    static isPresentingModally()
    376383    {
  • trunk/Source/WebKit/ChangeLog

    r247146 r247158  
     12019-07-05  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Touching media controls sometimes shows software keyboard
     4        https://bugs.webkit.org/show_bug.cgi?id=199490
     5        <rdar://problem/52076270>
     6
     7        Reviewed by Eric Carlson.
     8
     9        In r243044, we added a compatibility hack for Google Slides (and other G-suite properties) to allow the on-
     10        screen keyboard to show up after a prevented touch event in the case where an element was already focused, even
     11        if the touch event handler doesn't explicitly refocus the element. However, this means that if a regular text
     12        field (or other form control) has been programmatically focused, then interacting with any other element that
     13        prevents default on touchstart will cause us to show the keyboard for that focused element.
     14
     15        To mitigate this, only fall down this refocusing codepath in the case where the focused element is a hidden
     16        editable element (in the style of many Google productivity web apps). For non-hidden editable elements that are
     17        already focused, this refocusing logic is not necessary, since the user should be able to interact with the
     18        control to show the keyboard anyways; for hidden editable areas, this compatibility hack is actually needed,
     19        since there is typically no other way for a user to focus these elements and show an on-screen keyboard.
     20
     21        Tests:  fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html
     22                fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html
     23
     24        * WebProcess/WebPage/WebPage.cpp:
     25        (WebKit::WebPage::dispatchTouchEvent):
     26        * WebProcess/WebPage/WebPage.h:
     27        * WebProcess/WebPage/ios/WebPageIOS.mm:
     28        (WebKit::WebPage::isTransparentOrFullyClipped const):
     29
     30        Renamed from enclosingLayerIsTransparentOrFullyClipped, and pulled out into a private helper method.
     31
     32        (WebKit::WebPage::platformEditorState const):
     33        (WebKit::WebPage::requestEvasionRectsAboveSelection):
     34        (WebKit::WebPage::getFocusedElementInformation):
     35        (WebKit::enclosingLayerIsTransparentOrFullyClipped): Deleted.
     36
    1372019-07-04  Chris Dumez  <cdumez@apple.com>
    238
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r246938 r247158  
    28972897        auto newFocusedFrame = makeRefPtr(m_page->focusController().focusedFrame());
    28982898        auto newFocusedElement = makeRefPtr(newFocusedFrame ? newFocusedFrame->document()->focusedElement() : nullptr);
    2899         if (oldFocusedElement == newFocusedElement)
     2899        if (oldFocusedElement == newFocusedElement && isTransparentOrFullyClipped(*newFocusedElement))
    29002900            elementDidRefocus(*newFocusedElement);
    29012901    }
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r247027 r247158  
    14491449#if PLATFORM(IOS_FAMILY)
    14501450    void didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>&, const String& displayString, const IPC::DataReference& iconData);
     1451    bool isTransparentOrFullyClipped(const WebCore::Element&) const;
    14511452#endif
    14521453
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r247145 r247158  
    186186}
    187187
    188 static bool enclosingLayerIsTransparentOrFullyClipped(const RenderObject& renderer)
    189 {
    190     auto* enclosingLayer = renderer.enclosingLayer();
     188bool WebPage::isTransparentOrFullyClipped(const Element& element) const
     189{
     190    auto* renderer = element.renderer();
     191    if (!renderer)
     192        return false;
     193
     194    auto* enclosingLayer = renderer->enclosingLayer();
    191195    return enclosingLayer && enclosingLayer->isTransparentOrFullyClippedRespectingParentFrames();
    192196}
     
    265269        }
    266270        if (result.isContentEditable) {
    267             auto container = makeRefPtr(selection.rootEditableElement());
    268             if (container && container->renderer())
    269                 postLayoutData.editableRootIsTransparentOrFullyClipped = enclosingLayerIsTransparentOrFullyClipped(*container->renderer());
     271            if (auto container = makeRefPtr(selection.rootEditableElement()))
     272                postLayoutData.editableRootIsTransparentOrFullyClipped = isTransparentOrFullyClipped(*container);
    270273        }
    271274        computeEditableRootHasContentAndPlainText(selection, postLayoutData);
     
    18021805    }
    18031806
    1804     if (!m_focusedElement || !m_focusedElement->renderer() || enclosingLayerIsTransparentOrFullyClipped(*m_focusedElement->renderer())) {
     1807    if (!m_focusedElement || !m_focusedElement->renderer() || isTransparentOrFullyClipped(*m_focusedElement)) {
    18051808        reply({ });
    18061809        return;
     
    29922995    }
    29932996
    2994     if (m_focusedElement->document().quirks().shouldSuppressAutocorrectionAndAutocaptializationInHiddenEditableAreas() && m_focusedElement->renderer() && enclosingLayerIsTransparentOrFullyClipped(*m_focusedElement->renderer())) {
     2997    if (m_focusedElement->document().quirks().shouldSuppressAutocorrectionAndAutocaptializationInHiddenEditableAreas() && isTransparentOrFullyClipped(*m_focusedElement)) {
    29952998        information.autocapitalizeType = AutocapitalizeTypeNone;
    29962999        information.isAutocorrect = false;
  • trunk/Tools/ChangeLog

    r247143 r247158  
     12019-07-05  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Touching media controls sometimes shows software keyboard
     4        https://bugs.webkit.org/show_bug.cgi?id=199490
     5        <rdar://problem/52076270>
     6
     7        Reviewed by Eric Carlson.
     8
     9        Adds plumbing for a new testing hook to check whether or not there is an active input session. See other
     10        ChangeLog entries for more detail.
     11
     12        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
     13        (WTR::UIScriptController::hasInputSession const):
     14        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
     15        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
     16        (WTR::UIScriptController::hasInputSession const):
     17        * TestRunnerShared/UIScriptContext/UIScriptController.h:
     18        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
     19        (WTR::UIScriptController::hasInputSession const):
     20
    1212019-07-04  Aakash Jain  <aakash_jain@apple.com>
    222
  • trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm

    r244370 r247158  
    288288}
    289289
     290bool UIScriptController::hasInputSession() const
     291{
     292    return false;
     293}
     294
    290295double UIScriptController::minimumZoomScale() const
    291296{
  • trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl

    r244370 r247158  
    225225    attribute object didHideKeyboardCallback;
    226226    readonly attribute boolean isShowingKeyboard;
     227    readonly attribute boolean hasInputSession;
    227228
    228229    attribute object didShowMenuCallback;
  • trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp

    r246639 r247158  
    454454}
    455455
     456bool UIScriptController::hasInputSession() const
     457{
     458    return false;
     459}
     460
    456461double UIScriptController::zoomScale() const
    457462{
  • trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h

    r244370 r247158  
    164164
    165165    bool isShowingKeyboard() const;
     166    bool hasInputSession() const;
    166167
    167168    void setDidHideMenuCallback(JSValueRef);
  • trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

    r245057 r247158  
    626626}
    627627
     628bool UIScriptController::hasInputSession() const
     629{
     630    return TestController::singleton().mainWebView()->platformView().isInteractingWithFormControl;
     631}
     632
    628633void UIScriptController::applyAutocorrection(JSStringRef newString, JSStringRef oldString, JSValueRef callback)
    629634{
Note: See TracChangeset for help on using the changeset viewer.