⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 243044 in webkit


Ignore:
Timestamp:
Mar 16, 2019, 2:17:40 PM (7 years ago)
Author:
Wenson Hsieh
Message:

[iOS] Software keyboard never appears when editing on some websites
https://bugs.webkit.org/show_bug.cgi?id=195824
<rdar://problem/48020610>

Reviewed by Ryosuke Niwa.

Source/WebKit:

In the scenario where an element has already been programmatically focused but the UI process isn't showing an
input view for it, there are a couple of different ways in which an input view may still be shown for that
element:

  1. If the page attempts to programmatically focus the element, we'll invoke elementDidRefocus to recompute

information about the focused element and propagate it to the UI process. By default, if programmatic focus was
triggered under the scope of user interaction, we'll allow the input view to appear.

  1. In the case where page does not attempt to programmatically focus the element but a click is dispatched,

there is logic in WebPage::completeSyntheticClick to send information about the already-focused element.

On the web page relevant to this bug, focus is programmatically moved to hidden contenteditable areas upon page
load, and touchstart is also prevented; furthermore, the page does not attempt to programmatically refocus the
hidden editable area upon receiving touchstart. This means that the user will never be able to bring up the
keyboard, since the editable area is already programmatically focused and subsequent attempts to tap in the
page do nothing, because the page has already focused the hidden editable area (with the expectation that the
software keyboard should already be present).

To fix this, we bring some of the same logic in completeSyntheticClick over to dispatchTouchEvent, by sending
focused element information to the UI process if the focused element did not change over the course of
dispatching the touch event. Similar code was introduced in r167774 to fix the same type of issue (i.e.
inability to bring up the software keyboard), but this was later reverted in r188405 due to causing bugs such as
<rdar://problem/22204108>, wherein this logic to bring up the keyboard in dispatchTouchEvent would scroll and
zoom the page, such that the click event fired after touchend would be dispatched in the wrong location and (in
the case of <rdar://problem/22204108>) caused the focused element to immediately blur again.

To mitigate this issue, we add the additional constraint that we only send focused element info in the case
where the touch won't also generate a click later down the road, by requiring that the dispatched event was
handled by the page (i.e. prevented).

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

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::dispatchTouchEvent):

LayoutTests:

Add a layout test to verify that tapping a programmatically focused textarea that prevents touchstart still
causes the keyboard to appear.

  • fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt: Added.
  • fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html: Added.
Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r243043 r243044  
     12019-03-16  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Software keyboard never appears when editing on some websites
     4        https://bugs.webkit.org/show_bug.cgi?id=195824
     5        <rdar://problem/48020610>
     6
     7        Reviewed by Ryosuke Niwa.
     8
     9        Add a layout test to verify that tapping a programmatically focused textarea that prevents touchstart still
     10        causes the keyboard to appear.
     11
     12        * fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt: Added.
     13        * fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html: Added.
     14
    1152019-03-16  Zalan Bujtas  <zalan@apple.com>
    216
  • trunk/Source/WebKit/ChangeLog

    r243043 r243044  
     12019-03-16  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Software keyboard never appears when editing on some websites
     4        https://bugs.webkit.org/show_bug.cgi?id=195824
     5        <rdar://problem/48020610>
     6
     7        Reviewed by Ryosuke Niwa.
     8
     9        In the scenario where an element has already been programmatically focused but the UI process isn't showing an
     10        input view for it, there are a couple of different ways in which an input view may still be shown for that
     11        element:
     12
     13        1. If the page attempts to programmatically focus the element, we'll invoke elementDidRefocus to recompute
     14        information about the focused element and propagate it to the UI process. By default, if programmatic focus was
     15        triggered under the scope of user interaction, we'll allow the input view to appear.
     16
     17        2. In the case where page does not attempt to programmatically focus the element but a click is dispatched,
     18        there is logic in WebPage::completeSyntheticClick to send information about the already-focused element.
     19
     20        On the web page relevant to this bug, focus is programmatically moved to hidden contenteditable areas upon page
     21        load, and touchstart is also prevented; furthermore, the page does not attempt to programmatically refocus the
     22        hidden editable area upon receiving touchstart. This means that the user will never be able to bring up the
     23        keyboard, since the editable area is already programmatically focused and subsequent attempts to tap in the
     24        page do nothing, because the page has already focused the hidden editable area (with the expectation that the
     25        software keyboard should already be present).
     26
     27        To fix this, we bring some of the same logic in completeSyntheticClick over to dispatchTouchEvent, by sending
     28        focused element information to the UI process if the focused element did not change over the course of
     29        dispatching the touch event. Similar code was introduced in r167774 to fix the same type of issue (i.e.
     30        inability to bring up the software keyboard), but this was later reverted in r188405 due to causing bugs such as
     31        <rdar://problem/22204108>, wherein this logic to bring up the keyboard in dispatchTouchEvent would scroll and
     32        zoom the page, such that the click event fired after touchend would be dispatched in the wrong location and (in
     33        the case of <rdar://problem/22204108>) caused the focused element to immediately blur again.
     34
     35        To mitigate this issue, we add the additional constraint that we only send focused element info in the case
     36        where the touch won't also generate a click later down the road, by requiring that the dispatched event was
     37        handled by the page (i.e. prevented).
     38
     39        Test: fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html
     40
     41        * WebProcess/WebPage/WebPage.cpp:
     42        (WebKit::WebPage::dispatchTouchEvent):
     43
    1442019-03-16  Zalan Bujtas  <zalan@apple.com>
    245
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r243002 r243044  
    28182818    SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
    28192819
     2820    auto oldFocusedFrame = makeRefPtr(m_page->focusController().focusedFrame());
     2821    auto oldFocusedElement = makeRefPtr(oldFocusedFrame ? oldFocusedFrame->document()->focusedElement() : nullptr);
     2822
    28202823    m_lastInteractionLocation = touchEvent.position();
    28212824    CurrentEvent currentEvent(touchEvent);
    28222825    handled = handleTouchEvent(touchEvent, m_page.get());
    28232826    updatePotentialTapSecurityOrigin(touchEvent, handled);
     2827
     2828    if (handled && oldFocusedElement) {
     2829        auto newFocusedFrame = makeRefPtr(m_page->focusController().focusedFrame());
     2830        auto newFocusedElement = makeRefPtr(newFocusedFrame ? newFocusedFrame->document()->focusedElement() : nullptr);
     2831        if (oldFocusedElement == newFocusedElement)
     2832            elementDidRefocus(*newFocusedElement);
     2833    }
    28242834}
    28252835
Note: See TracChangeset for help on using the changeset viewer.