Changeset 244096 in webkit


Ignore:
Timestamp:
Apr 9, 2019 2:45:03 PM (5 years ago)
Author:
commit-queue@webkit.org
Message:

[iPad] Should open popover when the spacebar is pressed
https://bugs.webkit.org/show_bug.cgi?id=196360
<rdar://problem/49389129>

Patch by Daniel Bates <dabates@apple.com> on 2019-04-09
Reviewed by Brent Fulgham.

Source/WebKit:

Pressing the spacebar should open the popover for a focused popup button (e.g. <select>) on iOS
just like it does on the Mac.

For now, we keep the iPhone behavior of blurring the element when the Done button is pressed and
hence pressing spacebar does nothing (because there is no focused element).

  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView accessoryOpen]): Added. Extracted the logic from -_elementDidFocus to scroll to
the focused element, update the accessory and then tell the accessory to begin editing.
(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
Write in terms of -accessoryOpen.

  • UIProcess/ios/forms/WKFormPeripheralBase.mm:

(-[WKFormPeripheralBase handleKeyEvent:]): Interpret the spacebar when the peripheral is closed (!_editing)
and call -accessoryOpen to ultimately call back to this peripheral to tell it to begin editing,
which will cause the popover to appear again.

Tools:

Add testing infrastructure to support waiting for a popover to be presented or dismissed.

  • DumpRenderTree/ios/UIScriptControllerIOS.mm:

(WTR::UIScriptController::isShowingPopover const): Added.
(WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added.
(WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added.

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

(WTR::UIScriptController::setWillPresentPopoverCallback): Added.
(WTR::UIScriptController::willPresentPopoverCallback const): Added.
(WTR::UIScriptController::setDidDismissPopoverCallback): Added.
(WTR::UIScriptController::didDismissPopoverCallback const): Added.
(WTR::UIScriptController::isShowingPopover const): Added.
(WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added.
(WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added.

  • TestRunnerShared/UIScriptContext/UIScriptController.h:
  • WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
  • WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:

(-[TestRunnerWKWebView initWithFrame:configuration:]): Update some state.
(-[TestRunnerWKWebView resetInteractionCallbacks]): Ditto.
(-[TestRunnerWKWebView _willPresentPopover]): Added.
(-[TestRunnerWKWebView _didDismissPopover]): Added.

  • WebKitTestRunner/ios/UIScriptControllerIOS.mm:

(WTR::UIScriptController::isShowingPopover const): Added.
(WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added.
(WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added.

LayoutTests:

Add an iPad-specific test to ensure that pressing the spacebar opens the popover and scrolls
the form control into view.

  • fast/forms/ios/ipad/open-picker-using-keyboard-expected.txt: Added.
  • fast/forms/ios/ipad/open-picker-using-keyboard.html: Added.
  • platform/ios/TestExpectations: Skip tests in fast/forms/ios/ipad. We will unskip for iPad below.
  • platform/ipad/TestExpectations: Mark tests in fast/forms/ios/ipad as PASS so we run them.
  • resources/ui-helper.js:

(window.UIHelper.waitForPopoverToPresent):
(window.UIHelper.waitForPopoverToDismiss):

Location:
trunk
Files:
2 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r244094 r244096  
     12019-04-09  Daniel Bates  <dabates@apple.com>
     2
     3        [iPad] Should open popover when the spacebar is pressed
     4        https://bugs.webkit.org/show_bug.cgi?id=196360
     5        <rdar://problem/49389129>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Add an iPad-specific test to ensure that pressing the spacebar opens the popover and scrolls
     10        the form control into view.
     11
     12        * fast/forms/ios/ipad/open-picker-using-keyboard-expected.txt: Added.
     13        * fast/forms/ios/ipad/open-picker-using-keyboard.html: Added.
     14        * platform/ios/TestExpectations: Skip tests in fast/forms/ios/ipad. We will unskip for iPad below.
     15        * platform/ipad/TestExpectations: Mark tests in fast/forms/ios/ipad as PASS so we run them.
     16        * resources/ui-helper.js:
     17        (window.UIHelper.waitForPopoverToPresent):
     18        (window.UIHelper.waitForPopoverToDismiss):
     19
    1202019-04-09  Youenn Fablet  <youenn@apple.com>
    221
  • trunk/LayoutTests/platform/ios/TestExpectations

    r244036 r244096  
    2626# iPad-specific tests skipped here and re-enabled in platform/ipad
    2727fast/events/ios/ipad [ Skip ]
     28fast/forms/ios/ipad [ Skip ]
    2829
    2930###
  • trunk/LayoutTests/platform/ipad/TestExpectations

    r241275 r244096  
     1fast/forms/ios/ipad [ Pass ]
     2
    13# iPads don't zoom when form elements are focused
    24fast/forms/ios/accessory-bar-navigation.html [ Skip ]
  • trunk/LayoutTests/resources/ui-helper.js

    r243513 r244096  
    383383    }
    384384
     385    static waitForPopoverToPresent()
     386    {
     387        if (!this.isWebKit2() || !this.isIOS())
     388            return Promise.resolve();
     389
     390        return new Promise(resolve => {
     391            testRunner.runUIScript(`
     392                (function() {
     393                    if (uiController.isShowingPopover)
     394                        uiController.uiScriptComplete();
     395                    else
     396                        uiController.willPresentPopoverCallback = () => uiController.uiScriptComplete();
     397                })()`, resolve);
     398        });
     399    }
     400
     401    static waitForPopoverToDismiss()
     402    {
     403        if (!this.isWebKit2() || !this.isIOS())
     404            return Promise.resolve();
     405
     406        return new Promise(resolve => {
     407            testRunner.runUIScript(`
     408                (function() {
     409                    if (uiController.isShowingPopover)
     410                        uiController.didDismissPopoverCallback = () => uiController.uiScriptComplete();
     411                    else
     412                        uiController.uiScriptComplete();
     413                })()`, resolve);
     414        });
     415    }
     416
    385417    static waitForKeyboardToHide()
    386418    {
  • trunk/Source/WebKit/ChangeLog

    r244095 r244096  
     12019-04-09  Daniel Bates  <dabates@apple.com>
     2
     3        [iPad] Should open popover when the spacebar is pressed
     4        https://bugs.webkit.org/show_bug.cgi?id=196360
     5        <rdar://problem/49389129>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Pressing the spacebar should open the popover for a focused popup button (e.g. <select>) on iOS
     10        just like it does on the Mac.
     11
     12        For now, we keep the iPhone behavior of blurring the element when the Done button is pressed and
     13        hence pressing spacebar does nothing (because there is no focused element).
     14
     15        * UIProcess/ios/WKContentViewInteraction.h:
     16        * UIProcess/ios/WKContentViewInteraction.mm:
     17        (-[WKContentView accessoryOpen]): Added. Extracted the logic from -_elementDidFocus to scroll to
     18        the focused element, update the accessory and then tell the accessory to begin editing.
     19        (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
     20        Write in terms of -accessoryOpen.
     21        * UIProcess/ios/forms/WKFormPeripheralBase.mm:
     22        (-[WKFormPeripheralBase handleKeyEvent:]): Interpret the spacebar when the peripheral is closed (!_editing)
     23        and call -accessoryOpen to ultimately call back to this peripheral to tell it to begin editing,
     24        which will cause the popover to appear again.
     25
    1262019-04-09  Chris Dumez  <cdumez@apple.com>
    227
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r243963 r244096  
    429429- (void)_showRunOpenPanel:(API::OpenPanelParameters*)parameters resultListener:(WebKit::WebOpenPanelResultListenerProxy*)listener;
    430430- (void)_showShareSheet:(const WebCore::ShareDataWithParsedURL&)shareData completionHandler:(WTF::CompletionHandler<void(bool)>&&)completionHandler;
    431 - (void)accessoryDone;
    432431- (void)dismissFilePicker;
    433432- (void)_didHandleKeyEvent:(::WebEvent *)event eventWasHandled:(BOOL)eventWasHandled;
     
    450449- (void)_didChangeWebViewEditability;
    451450
     451// UIWebFormAccessoryDelegate protocol
     452- (void)accessoryDone;
     453
     454- (void)accessoryOpen;
     455
    452456- (void)_requestDOMPasteAccessWithElementRect:(const WebCore::IntRect&)elementRect originIdentifier:(const String&)originIdentifier completionHandler:(CompletionHandler<void(WebCore::DOMPasteAccessResponse)>&&)completionHandler;
    453457
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r244056 r244096  
    38083808}
    38093809
     3810- (void)accessoryOpen
     3811{
     3812    if (!_inputPeripheral)
     3813        return;
     3814    [self _zoomToRevealFocusedElement];
     3815    [self _updateAccessory];
     3816    [_inputPeripheral beginEditing];
     3817}
     3818
    38103819- (void)_updateAccessory
    38113820{
     
    50005009            if (!self.isFirstResponder)
    50015010                [self becomeFirstResponder];
    5002             [self _zoomToRevealFocusedElement];
    5003             [self _updateAccessory];
    5004             [_inputPeripheral beginEditing];
     5011            [self accessoryOpen];
    50055012        }
    50065013        return;
  • trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheralBase.mm

    r243808 r244096  
    8585        return YES;
    8686    }
     87    if (!_editing && keyEvent._keyCode == kHIDUsage_KeyboardSpacebar) {
     88        [_view accessoryOpen];
     89        return YES;
     90    }
    8791    return NO;
    8892}
  • trunk/Tools/ChangeLog

    r244089 r244096  
     12019-04-09  Daniel Bates  <dabates@apple.com>
     2
     3        [iPad] Should open popover when the spacebar is pressed
     4        https://bugs.webkit.org/show_bug.cgi?id=196360
     5        <rdar://problem/49389129>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Add testing infrastructure to support waiting for a popover to be presented or dismissed.
     10
     11        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
     12        (WTR::UIScriptController::isShowingPopover const): Added.
     13        (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added.
     14        (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added.
     15        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
     16        * TestRunnerShared/UIScriptContext/UIScriptContext.h:
     17        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
     18        (WTR::UIScriptController::setWillPresentPopoverCallback): Added.
     19        (WTR::UIScriptController::willPresentPopoverCallback const): Added.
     20        (WTR::UIScriptController::setDidDismissPopoverCallback): Added.
     21        (WTR::UIScriptController::didDismissPopoverCallback const): Added.
     22        (WTR::UIScriptController::isShowingPopover const): Added.
     23        (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added.
     24        (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added.
     25        * TestRunnerShared/UIScriptContext/UIScriptController.h:
     26        * WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
     27        * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
     28        (-[TestRunnerWKWebView initWithFrame:configuration:]): Update some state.
     29        (-[TestRunnerWKWebView resetInteractionCallbacks]): Ditto.
     30        (-[TestRunnerWKWebView _willPresentPopover]): Added.
     31        (-[TestRunnerWKWebView _didDismissPopover]): Added.
     32        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
     33        (WTR::UIScriptController::isShowingPopover const): Added.
     34        (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added.
     35        (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added.
     36
    1372019-04-09  Alex Christensen  <achristensen@webkit.org>
    238
  • trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm

    r243523 r244096  
    354354}
    355355
     356bool UIScriptController::isShowingPopover() const
     357{
     358    return false;
     359}
     360
     361void UIScriptController::platformSetWillPresentPopoverCallback()
     362{
     363}
     364
     365void UIScriptController::platformSetDidDismissPopoverCallback()
     366{
     367}
     368
    356369JSObjectRef UIScriptController::rectForMenuAction(JSStringRef) const
    357370{
  • trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl

    r243523 r244096  
    232232    object rectForMenuAction(DOMString action);
    233233
     234    readonly attribute boolean isShowingPopover;
     235    attribute object willPresentPopoverCallback;
     236    attribute object didDismissPopoverCallback;
     237
    234238    attribute object willBeginZoomingCallback;
    235239    attribute object didEndZoomingCallback;
  • trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptContext.h

    r241322 r244096  
    5757    CallbackTypeDidShowMenu,
    5858    CallbackTypeDidHideMenu,
     59    CallbackTypeWillPresentPopover,
     60    CallbackTypeDidDismissPopover,
    5961    CallbackTypeDidEndScrolling,
    6062    CallbackTypeDidStartFormControlInteraction,
  • trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp

    r243523 r244096  
    228228}
    229229
     230void UIScriptController::setWillPresentPopoverCallback(JSValueRef callback)
     231{
     232    m_context->registerCallback(callback, CallbackTypeWillPresentPopover);
     233    platformSetWillPresentPopoverCallback();
     234}
     235
     236JSValueRef UIScriptController::willPresentPopoverCallback() const
     237{
     238    return m_context->callbackWithID(CallbackTypeWillPresentPopover);
     239}
     240
     241void UIScriptController::setDidDismissPopoverCallback(JSValueRef callback)
     242{
     243    m_context->registerCallback(callback, CallbackTypeDidDismissPopover);
     244    platformSetDidDismissPopoverCallback();
     245}
     246
     247JSValueRef UIScriptController::didDismissPopoverCallback() const
     248{
     249    return m_context->callbackWithID(CallbackTypeDidDismissPopover);
     250}
     251
    230252#if !PLATFORM(COCOA)
    231253
     
    554576}
    555577
     578bool UIScriptController::isShowingPopover() const
     579{
     580    return false;
     581}
     582
     583void UIScriptController::platformSetWillPresentPopoverCallback()
     584{
     585}
     586
     587void UIScriptController::platformSetDidDismissPopoverCallback()
     588{
     589}
     590
    556591JSObjectRef UIScriptController::menuRect() const
    557592{
  • trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h

    r243523 r244096  
    167167    void setDidHideMenuCallback(JSValueRef);
    168168    JSValueRef didHideMenuCallback() const;
    169 
    170169    void setDidShowMenuCallback(JSValueRef);
    171170    JSValueRef didShowMenuCallback() const;
     171
     172    bool isShowingPopover() const;
     173    void setDidDismissPopoverCallback(JSValueRef);
     174    JSValueRef didDismissPopoverCallback() const;
     175    void setWillPresentPopoverCallback(JSValueRef);
     176    JSValueRef willPresentPopoverCallback() const;
    172177
    173178    bool isShowingMenu() const;
     
    251256    void platformSetDidShowMenuCallback();
    252257    void platformSetDidHideMenuCallback();
     258    void platformSetWillPresentPopoverCallback();
     259    void platformSetDidDismissPopoverCallback();
    253260    void platformSetDidEndScrollingCallback();
    254261    void platformClearAllCallbacks();
  • trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h

    r243021 r244096  
    4444@property (nonatomic, copy) void (^didShowMenuCallback)(void);
    4545@property (nonatomic, copy) void (^didHideMenuCallback)(void);
     46@property (nonatomic, copy) void (^willPresentPopoverCallback)(void);
     47@property (nonatomic, copy) void (^didDismissPopoverCallback)(void);
    4648@property (nonatomic, copy) void (^didEndScrollingCallback)(void);
    4749@property (nonatomic, copy) void (^rotationDidEndCallback)(void);
     
    5759@property (nonatomic, readonly, getter=isShowingKeyboard) BOOL showingKeyboard;
    5860@property (nonatomic, readonly, getter=isShowingMenu) BOOL showingMenu;
     61@property (nonatomic, readonly, getter=isShowingPopover) BOOL showingPopover;
    5962@property (nonatomic, assign) BOOL usesSafariLikeRotation;
    6063@property (nonatomic, readonly, getter=isInteractingWithFormControl) BOOL interactingWithFormControl;
  • trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm

    r243021 r244096  
    5656@property (nonatomic, getter=isShowingKeyboard, setter=setIsShowingKeyboard:) BOOL showingKeyboard;
    5757@property (nonatomic, getter=isShowingMenu, setter=setIsShowingMenu:) BOOL showingMenu;
     58@property (nonatomic, getter=isShowingPopover, setter=setIsShowingPopover:) BOOL showingPopover;
    5859
    5960@end
     
    8081        [center addObserver:self selector:@selector(_didShowMenu) name:UIMenuControllerDidShowMenuNotification object:nil];
    8182        [center addObserver:self selector:@selector(_didHideMenu) name:UIMenuControllerDidHideMenuNotification object:nil];
     83        [center addObserver:self selector:@selector(_willPresentPopover) name:@"UIPopoverControllerWillPresentPopoverNotification" object:nil];
     84        [center addObserver:self selector:@selector(_didDismissPopover) name:@"UIPopoverControllerDidDismissPopoverNotification" object:nil];
    8285        self.UIDelegate = self;
    8386    }
     
    142145    self.didShowMenuCallback = nil;
    143146    self.didHideMenuCallback = nil;
     147    self.willPresentPopoverCallback = nil;
     148    self.didDismissPopoverCallback = nil;
    144149    self.didEndScrollingCallback = nil;
    145150    self.rotationDidEndCallback = nil;
     
    201206}
    202207
     208- (void)_willPresentPopover
     209{
     210    if (self.showingPopover)
     211        return;
     212
     213    self.showingPopover = YES;
     214    if (self.willPresentPopoverCallback)
     215        self.willPresentPopoverCallback();
     216}
     217
     218- (void)_didDismissPopover
     219{
     220    if (!self.showingPopover)
     221        return;
     222
     223    self.showingPopover = NO;
     224    if (self.didDismissPopoverCallback)
     225        self.didDismissPopoverCallback();
     226}
     227
    203228- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
    204229{
  • trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

    r243523 r244096  
    908908}
    909909
     910bool UIScriptController::isShowingPopover() const
     911{
     912    return TestController::singleton().mainWebView()->platformView().showingPopover;
     913}
     914
     915void UIScriptController::platformSetWillPresentPopoverCallback()
     916{
     917    TestController::singleton().mainWebView()->platformView().willPresentPopoverCallback = ^{
     918        if (!m_context)
     919            return;
     920        m_context->fireCallback(CallbackTypeWillPresentPopover);
     921    };
     922}
     923
     924void UIScriptController::platformSetDidDismissPopoverCallback()
     925{
     926    TestController::singleton().mainWebView()->platformView().didDismissPopoverCallback = ^{
     927        if (!m_context)
     928            return;
     929        m_context->fireCallback(CallbackTypeDidDismissPopover);
     930    };
     931}
     932
    910933JSObjectRef UIScriptController::rectForMenuAction(JSStringRef jsAction) const
    911934{
     
    975998    webView.didHideKeyboardCallback = nil;
    976999    webView.didShowKeyboardCallback = nil;
     1000    webView.willPresentPopoverCallback = nil;
     1001    webView.didDismissPopoverCallback = nil;
    9771002    webView.didEndScrollingCallback = nil;
    9781003    webView.rotationDidEndCallback = nil;
Note: See TracChangeset for help on using the changeset viewer.