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

Changeset 265117 in webkit


Ignore:
Timestamp:
Jul 30, 2020, 4:31:59 PM (6 years ago)
Author:
Wenson Hsieh
Message:

[iPadOS] Two taps are required to choose a country/region when creating an account on ea.com
https://bugs.webkit.org/show_bug.cgi?id=214984
<rdar://problem/66261490>

Reviewed by Devin Rousso.

Source/WebKit:

On the desktop version of the account creation page on ea.com, tapping a custom selection menu element
programmatically focuses a real select element that is positioned far outside the viewport. As a result, on
iPad, we still attempt to show a popover for this focused select at the element location. This popover is not
visible to the user, but on iOS 13, it still steals modal focus from the web view, which means that an
additional tap anywhere in the window is required to dismiss the (invisible) popover before the user can choose
one of the options in the custom in-page menu that is shown.

Furthermore, upon choosing one of these options, the page programmatically focuses the offscreen select again.
This causes us to re-present the offscreen popover, which requires yet another tap to dismiss on iOS 13.
However, on iOS 14, this actually results in a crash when attempting to scroll the popover's inner UITableView
to the selected row.

To fix both the crash on iOS 14 and the multiple redundant taps required to dismiss the popover on iOS 13, avoid
showing popovers altogether if the popover's presentation rect is outside the bounds of the content view, since
we cannot reasonably expect a user to interact with such a popover anyways.

Test: fast/forms/ios/repeatedly-focus-offscreen-select.html

  • UIProcess/ios/forms/WKFormPopover.mm:

(-[WKRotatingPopover presentPopoverAnimated:]):

LayoutTests:

Add a test that exercises both the crash and the UI bug on iPadOS. Note that this test already passes on iOS,
where we don't use popovers for focused selects.

  • fast/forms/ios/repeatedly-focus-offscreen-select-expected.txt: Added.
  • fast/forms/ios/repeatedly-focus-offscreen-select.html: Added.
Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r265098 r265117  
     12020-07-30  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iPadOS] Two taps are required to choose a country/region when creating an account on ea.com
     4        https://bugs.webkit.org/show_bug.cgi?id=214984
     5        <rdar://problem/66261490>
     6
     7        Reviewed by Devin Rousso.
     8
     9        Add a test that exercises both the crash and the UI bug on iPadOS. Note that this test already passes on iOS,
     10        where we don't use popovers for focused selects.
     11
     12        * fast/forms/ios/repeatedly-focus-offscreen-select-expected.txt: Added.
     13        * fast/forms/ios/repeatedly-focus-offscreen-select.html: Added.
     14
    1152020-07-30  Antoine Quint  <graouts@webkit.org>
    216
  • trunk/Source/WebKit/ChangeLog

    r265115 r265117  
     12020-07-30  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iPadOS] Two taps are required to choose a country/region when creating an account on ea.com
     4        https://bugs.webkit.org/show_bug.cgi?id=214984
     5        <rdar://problem/66261490>
     6
     7        Reviewed by Devin Rousso.
     8
     9        On the desktop version of the account creation page on ea.com, tapping a custom selection menu element
     10        programmatically focuses a real `select` element that is positioned far outside the viewport. As a result, on
     11        iPad, we still attempt to show a popover for this focused select at the element location. This popover is not
     12        visible to the user, but on iOS 13, it still steals modal focus from the web view, which means that an
     13        additional tap anywhere in the window is required to dismiss the (invisible) popover before the user can choose
     14        one of the options in the custom in-page menu that is shown.
     15
     16        Furthermore, upon choosing one of these options, the page programmatically focuses the offscreen select again.
     17        This causes us to re-present the offscreen popover, which requires yet another tap to dismiss on iOS 13.
     18        However, on iOS 14, this actually results in a crash when attempting to scroll the popover's inner UITableView
     19        to the selected row.
     20
     21        To fix both the crash on iOS 14 and the multiple redundant taps required to dismiss the popover on iOS 13, avoid
     22        showing popovers altogether if the popover's presentation rect is outside the bounds of the content view, since
     23        we cannot reasonably expect a user to interact with such a popover anyways.
     24
     25        Test: fast/forms/ios/repeatedly-focus-offscreen-select.html
     26
     27        * UIProcess/ios/forms/WKFormPopover.mm:
     28        (-[WKRotatingPopover presentPopoverAnimated:]):
     29
    1302020-07-30  Jer Noble  <jer.noble@apple.com>
    231
  • trunk/Source/WebKit/UIProcess/ios/forms/WKFormPopover.mm

    r264187 r265117  
    134134- (void)presentPopoverAnimated:(BOOL)animated
    135135{
     136    auto directions = [self popoverArrowDirections];
     137    CGRect presentationRect;
     138    if (CGPointEqualToPoint(self.presentationPoint, CGPointZero))
     139        presentationRect = _view.focusedElementInformation.interactionRect;
     140    else {
     141        auto scale = _view.page->pageScaleFactor();
     142        presentationRect = CGRectMake(self.presentationPoint.x * scale, self.presentationPoint.y * scale, 1, 1);
     143    }
     144
     145    if (!CGRectIntersectsRect(presentationRect, _view.bounds))
     146        return;
     147
    136148#if PLATFORM(MACCATALYST)
    137149    [_view startRelinquishingFirstResponderToFocusedElement];
    138150#endif
    139 
    140     UIPopoverArrowDirection directions = [self popoverArrowDirections];
    141 
    142     BOOL presentWithPoint = !CGPointEqualToPoint(self.presentationPoint, CGPointZero);
    143     if (presentWithPoint) {
    144         CGFloat scale = [_view page]->pageScaleFactor();
    145         [_popoverController presentPopoverFromRect:CGRectIntegral(CGRectMake(self.presentationPoint.x * scale, self.presentationPoint.y * scale, 1, 1))
    146                                             inView:_view
    147                           permittedArrowDirections:directions
    148                                           animated:animated];
    149     } else {
    150         CGRect boundingBoxOfDOMNode = _view.focusedElementInformation.interactionRect;
    151         [_popoverController presentPopoverFromRect:CGRectIntegral(boundingBoxOfDOMNode)
    152                                             inView:_view
    153                           permittedArrowDirections:directions
    154                                           animated:animated];
    155     }
     151    [_popoverController presentPopoverFromRect:CGRectIntegral(presentationRect) inView:_view permittedArrowDirections:directions animated:animated];
    156152}
    157153
Note: See TracChangeset for help on using the changeset viewer.