Bug 207425 - REGRESSION (r256072): ScrollViewScrollabilityTests.ScrollableWithOverflowHiddenAndInputView fails
Summary: REGRESSION (r256072): ScrollViewScrollabilityTests.ScrollableWithOverflowHidd...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Wenson Hsieh
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-02-07 20:51 PST by Wenson Hsieh
Modified: 2020-02-08 12:36 PST (History)
4 users (show)

See Also:


Attachments
Patch (3.30 KB, patch)
2020-02-07 21:30 PST, Wenson Hsieh
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Wenson Hsieh 2020-02-07 20:51:03 PST
Followup to <rdar://problem/56960774>.
Comment 1 Wenson Hsieh 2020-02-07 20:52:40 PST
TestWebKitAPI.ScrollViewScrollabilityTests.ScrollableWithOverflowHiddenAndInputView Failed
Ran 1 tests of 1 with 0 successful
------------------------------
Test suite failed

Failed

    TestWebKitAPI.ScrollViewScrollabilityTests.ScrollableWithOverflowHiddenAndInputView
        LEAK: 1 WebProcessPool
        LEAK: 1 WebPageProxy

        /Users/whsieh/work/OpenSource/Tools/TestWebKitAPI/Tests/ios/ScrollViewScrollabilityTests.mm:100
        Expected equality of these values:
          [[webView scrollView] isScrollEnabled]
            Which is: false
          __objc_yes
            Which is: true
Comment 2 Wenson Hsieh 2020-02-07 21:05:00 PST
The way this API test currently works is a little unexpected. I think it’s intended to test that after focusing an input field (and bringing up the keyboard), we scroll to reveal the focused element even when the body has `overflow: hidden`. The logic responsible for making this work is in -[WKWebView _updateScrollViewForTransaction:]...

    bool hasDockedInputView = !CGRectIsEmpty(_inputViewBounds);
    bool isZoomed = layerTreeTransaction.pageScaleFactor() > layerTreeTransaction.initialScaleFactor();

    …

    bool scrollingEnabled = _page->scrollingCoordinatorProxy()->hasScrollableMainFrame() || hasDockedInputView || isZoomed || scrollingNeededToRevealUI;
    [_scrollView _setScrollEnabledInternal:scrollingEnabled];

However, since this is an API test on iOS (and therefore does not run in the context of a UIApplication), UIKit never attempts to actually bring up an input view; as a result, _inputViewBounds is always empty, so hasDockedInputView will always be NO. Instead, this test currently passes due to how -[WKWebView _zoomToFocusRect:…:] zooms the input field when running on iPhone; by zooming, the `isZoomed` flag is set, and so we end up setting scrollEnabled to YES anyways.

I manually verified on device (by focusing the bottom half of https://whsieh.github.io/examples/multiple-contenteditable) that we do still scroll to reveal focused elements after my change in r256072, since _inputViewBounds is non-empty.
Comment 3 Wenson Hsieh 2020-02-07 21:08:47 PST
This also explains the need for this snippet in the test:

    BOOL isPhone = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone;
    if (isPhone)
        EXPECT_EQ([[webView scrollView] isScrollEnabled], YES);

Since we don’t zoom on iPad, the `isZoomed` flag is NO and we don’t end up making the scroll view scrollable. This also suggests that if we were to make TestWebKitAPI a proper UI application in the future, this workaround could be removed.
Comment 4 Wenson Hsieh 2020-02-07 21:12:46 PST
(In reply to Wenson Hsieh from comment #3)
> This also explains the need for this snippet in the test:
> 
>     BOOL isPhone = [[UIDevice currentDevice] userInterfaceIdiom] ==
> UIUserInterfaceIdiomPhone;
>     if (isPhone)
>         EXPECT_EQ([[webView scrollView] isScrollEnabled], YES);
> 
> Since we don’t zoom on iPad, the `isZoomed` flag is NO and we don’t end up
> making the scroll view scrollable. This also suggests that if we were to
> make TestWebKitAPI a proper UI application in the future, this workaround
> could be removed.

On closer inspection, maybe not, because the test also explicitly overrides the input view and input accessory views to be empty UIViews, which means that the _inputViewBounds would be empty anyways :/

    auto inputView = adoptNS([[UIView alloc] init]);
    auto inputAccessoryView = adoptNS([[UIView alloc] init]);
    auto inputDelegate = adoptNS([TestInputDelegate new]);
    [inputDelegate setWillStartInputSessionHandler:[inputView, inputAccessoryView] (WKWebView *, id<_WKFormInputSession> session) {
        session.customInputView = inputView.get();
        session.customInputAccessoryView = inputAccessoryView.get();
    }];
Comment 5 Wenson Hsieh 2020-02-07 21:30:36 PST
Created attachment 390167 [details]
Patch
Comment 6 Wenson Hsieh 2020-02-08 11:52:28 PST
Comment on attachment 390167 [details]
Patch

Thanks for the review!
Comment 7 WebKit Commit Bot 2020-02-08 12:36:33 PST
Comment on attachment 390167 [details]
Patch

Clearing flags on attachment: 390167

Committed r256092: <https://trac.webkit.org/changeset/256092>
Comment 8 WebKit Commit Bot 2020-02-08 12:36:34 PST
All reviewed patches have been landed.  Closing bug.