Changeset 229998 in webkit


Ignore:
Timestamp:
Mar 27, 2018 9:37:43 AM (6 years ago)
Author:
BJ Burg
Message:

Web Automation: support enter/exit fullscreen and hide/restore window operations
https://bugs.webkit.org/show_bug.cgi?id=182837
<rdar://problem/37580732>

Reviewed by Tim Horton.

The W3C specification is more explicit about when to exit fullscreen and
restore the window for a browsing context. So, WebKit needs to have support
for performing these operations on behalf of a driver.

Based on prototyping, it is sufficient to use a JavaScript atom to enter
fullscreen mode. This is included in the patch as EnterFullscreen.js and
can be used to implement the §10.7.5 Fullscreen Window command.

Other window operations cannot be peformed from JavaScript, so we need to
delegate these operations to the session client (i.e., Safari).
This patch adds session client callouts for restoring, minimizing, and
switching to a browsing context.

Exiting fullscreen happens implicitly (per specification) when setting a
window frame without an actual frame, or when switching/restoring/minimizing a window.
If needed, a driver can call Set Window Rect in this way to unfullscreen a context.
Similarly, a driver can restore a minimized window using Set Window Rect.

  • UIProcess/API/APIAutomationSessionClient.h:

(API::AutomationSessionClient::requestHideWindowOfPage):
(API::AutomationSessionClient::requestRestoreWindowOfPage):
(API::AutomationSessionClient::requestSwitchToPage):
Add new API client methods.

  • UIProcess/API/Cocoa/_WKAutomationSessionDelegate.h:

Add new Cocoa API delegate methods.

  • UIProcess/Automation/Automation.json:

Make the switch to browsing context command asynchronous, since this functionality
is not always synchronous, and we prefer to use completion handlers in the delegates.

Add new protocol method for hiding the window of a browsing context.
This is expected to minimize/miniaturize a window for desktop window managers.

  • UIProcess/Automation/WebAutomationSession.h:
  • UIProcess/Automation/WebAutomationSession.cpp:

(WebKit::WebAutomationSession::switchToBrowsingContext):
Make this function asynchronous. Call out to the session client.

(WebKit::WebAutomationSession::setWindowFrameOfBrowsingContext):
Follow the steps in the specification to restore window and exit fullscreen.

(WebKit::WebAutomationSession::hideWindowOfBrowsingContext):
Exit fullscreen and call out to the session client.

(WebKit::WebAutomationSession::exitFullscreenWindowForPage):
This is a little strange. Because there is no async API for exiting fullscreen
from C++ code, we hook into willEnterFullScreen and didExitFullScreen and send
out the response if the page exited fullscreen after we requested it to do so.
Because the W3C specification mandates that drivers only process one command at
a time, there will only ever be one callback installed by this method at a time.

(WebKit::WebAutomationSession::restoreWindowForPage):
(WebKit::WebAutomationSession::hideWindowForPage):
Call out to the session client.

(WebKit::WebAutomationSession::didEnterFullScreenForPage):
(WebKit::WebAutomationSession::didExitFullScreenForPage):
Add methods to be called by instrumentation hooks in WebFullScreenManagerProxy.

  • UIProcess/Automation/atoms/EnterFullscreen.js: Added.

(enterFullscreen):

  • UIProcess/Cocoa/AutomationSessionClient.h:
  • UIProcess/Cocoa/AutomationSessionClient.mm:

(WebKit::AutomationSessionClient::AutomationSessionClient):
(WebKit::AutomationSessionClient::requestSwitchToPage):
(WebKit::AutomationSessionClient::requestHideWindowOfPage):
(WebKit::AutomationSessionClient::requestRestoreWindowOfPage):
(WebKit::AutomationSessionClient::isShowingJavaScriptDialogOnPage):
Add boilerplate to convert C++ API client to Objective-C delegate methods.

  • UIProcess/WebFullScreenManagerProxy.cpp:

(WebKit::WebFullScreenManagerProxy::didEnterFullScreen):
(WebKit::WebFullScreenManagerProxy::didExitFullScreen):
Notify the automation session if the page is under automation and
enters or exits fullscreen.

  • WebKit.xcodeproj/project.pbxproj:

Add EnterFullscreen.js to the list of WebDriver atoms. These are copied
as WebKit2 private headers and used by driver implementations.

Location:
trunk/Source/WebKit
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r229995 r229998  
     12018-03-27  Brian Burg  <bburg@apple.com>
     2
     3        Web Automation: support enter/exit fullscreen and hide/restore window operations
     4        https://bugs.webkit.org/show_bug.cgi?id=182837
     5        <rdar://problem/37580732>
     6
     7        Reviewed by Tim Horton.
     8
     9        The W3C specification is more explicit about when to exit fullscreen and
     10        restore the window for a browsing context. So, WebKit needs to have support
     11        for performing these operations on behalf of a driver.
     12
     13        Based on prototyping, it is sufficient to use a JavaScript atom to enter
     14        fullscreen mode. This is included in the patch as EnterFullscreen.js and
     15        can be used to implement the §10.7.5 Fullscreen Window command.
     16
     17        Other window operations cannot be peformed from JavaScript, so we need to
     18        delegate these operations to the session client (i.e., Safari).
     19        This patch adds session client callouts for restoring, minimizing, and
     20        switching to a browsing context.
     21
     22        Exiting fullscreen happens implicitly (per specification) when setting a
     23        window frame without an actual frame, or when switching/restoring/minimizing a window.
     24        If needed, a driver can call Set Window Rect in this way to unfullscreen a context.
     25        Similarly, a driver can restore a minimized window using Set Window Rect.
     26
     27        * UIProcess/API/APIAutomationSessionClient.h:
     28        (API::AutomationSessionClient::requestHideWindowOfPage):
     29        (API::AutomationSessionClient::requestRestoreWindowOfPage):
     30        (API::AutomationSessionClient::requestSwitchToPage):
     31        Add new API client methods.
     32
     33        * UIProcess/API/Cocoa/_WKAutomationSessionDelegate.h:
     34        Add new Cocoa API delegate methods.
     35
     36        * UIProcess/Automation/Automation.json:
     37        Make the switch to browsing context command asynchronous, since this functionality
     38        is not always synchronous, and we prefer to use completion handlers in the delegates.
     39
     40        Add new protocol method for hiding the window of a browsing context.
     41        This is expected to minimize/miniaturize a window for desktop window managers.
     42
     43        * UIProcess/Automation/WebAutomationSession.h:
     44        * UIProcess/Automation/WebAutomationSession.cpp:
     45        (WebKit::WebAutomationSession::switchToBrowsingContext):
     46        Make this function asynchronous. Call out to the session client.
     47
     48        (WebKit::WebAutomationSession::setWindowFrameOfBrowsingContext):
     49        Follow the steps in the specification to restore window and exit fullscreen.
     50
     51        (WebKit::WebAutomationSession::hideWindowOfBrowsingContext):
     52        Exit fullscreen and call out to the session client.
     53
     54        (WebKit::WebAutomationSession::exitFullscreenWindowForPage):
     55        This is a little strange. Because there is no async API for exiting fullscreen
     56        from C++ code, we hook into willEnterFullScreen and didExitFullScreen and send
     57        out the response if the page exited fullscreen after we requested it to do so.
     58        Because the W3C specification mandates that drivers only process one command at
     59        a time, there will only ever be one callback installed by this method at a time.
     60
     61        (WebKit::WebAutomationSession::restoreWindowForPage):
     62        (WebKit::WebAutomationSession::hideWindowForPage):
     63        Call out to the session client.
     64
     65        (WebKit::WebAutomationSession::didEnterFullScreenForPage):
     66        (WebKit::WebAutomationSession::didExitFullScreenForPage):
     67        Add methods to be called by instrumentation hooks in WebFullScreenManagerProxy.
     68
     69        * UIProcess/Automation/atoms/EnterFullscreen.js: Added.
     70        (enterFullscreen):
     71
     72        * UIProcess/Cocoa/AutomationSessionClient.h:
     73        * UIProcess/Cocoa/AutomationSessionClient.mm:
     74        (WebKit::AutomationSessionClient::AutomationSessionClient):
     75        (WebKit::AutomationSessionClient::requestSwitchToPage):
     76        (WebKit::AutomationSessionClient::requestHideWindowOfPage):
     77        (WebKit::AutomationSessionClient::requestRestoreWindowOfPage):
     78        (WebKit::AutomationSessionClient::isShowingJavaScriptDialogOnPage):
     79        Add boilerplate to convert C++ API client to Objective-C delegate methods.
     80
     81        * UIProcess/WebFullScreenManagerProxy.cpp:
     82        (WebKit::WebFullScreenManagerProxy::didEnterFullScreen):
     83        (WebKit::WebFullScreenManagerProxy::didExitFullScreen):
     84        Notify the automation session if the page is under automation and
     85        enters or exits fullscreen.
     86
     87        * WebKit.xcodeproj/project.pbxproj:
     88        Add EnterFullscreen.js to the list of WebDriver atoms. These are copied
     89        as WebKit2 private headers and used by driver implementations.
     90
    1912018-03-27  Eric Carlson  <eric.carlson@apple.com>
    292
  • trunk/Source/WebKit/UIProcess/API/APIAutomationSessionClient.h

    r229984 r229998  
    5555    virtual void didDisconnectFromRemote(WebKit::WebAutomationSession&) { }
    5656    virtual void requestNewPageWithOptions(WebKit::WebAutomationSession&, AutomationSessionBrowsingContextOptions, CompletionHandler<void(WebKit::WebPageProxy*)>&& completionHandler) { completionHandler(nullptr); }
     57    virtual void requestHideWindowOfPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&, CompletionHandler<void()>&& completionHandler) { completionHandler(); }
     58    virtual void requestRestoreWindowOfPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&, CompletionHandler<void()>&& completionHandler) { completionHandler(); }
     59    virtual void requestSwitchToPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&, CompletionHandler<void()>&& completionHandler) { completionHandler(); }
    5760    virtual bool isShowingJavaScriptDialogOnPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&) { return false; }
    5861    virtual void dismissCurrentJavaScriptDialogOnPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&) { }
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAutomationSessionDelegate.h

    r229984 r229998  
    5353
    5454- (void)_automationSession:(_WKAutomationSession *)automationSession requestNewWebViewWithOptions:(_WKAutomationSessionBrowsingContextOptions)options completionHandler:(void(^)(WKWebView * _Nullable))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     55- (void)_automationSession:(_WKAutomationSession *)automationSession requestHideWindowOfWebView:(WKWebView *)webView completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     56- (void)_automationSession:(_WKAutomationSession *)automationSession requestRestoreWindowOfWebView:(WKWebView *)webView completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     57- (void)_automationSession:(_WKAutomationSession *)automationSession requestSwitchToWebView:(WKWebView *)webView completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
    5558- (BOOL)_automationSession:(_WKAutomationSession *)automationSession isShowingJavaScriptDialogForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(10.13), ios(11.0));
    5659- (void)_automationSession:(_WKAutomationSession *)automationSession dismissCurrentJavaScriptDialogForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(10.13), ios(11.0));
     
    6366// migrate clients to use WKWebView, or expose the same behavior via a C SPI for those clients.
    6467- (void)_automationSession:(_WKAutomationSession *)automationSession requestNewPageWithOptions:(_WKAutomationSessionBrowsingContextOptions)options completionHandler:(void(^)(WKPageRef))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     68- (void)_automationSession:(_WKAutomationSession *)automationSession requestHideWindowOfPage:(WKPageRef)page completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     69- (void)_automationSession:(_WKAutomationSession *)automationSession requestRestoreWindowOfPage:(WKPageRef)page completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     70- (void)_automationSession:(_WKAutomationSession *)automationSession requestSwitchToPage:(WKPageRef)page completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
    6571- (BOOL)_automationSession:(_WKAutomationSession *)automationSession isShowingJavaScriptDialogOnPage:(WKPageRef)page WK_API_AVAILABLE(macosx(10.13), ios(11.0));
    6672- (void)_automationSession:(_WKAutomationSession *)automationSession dismissCurrentJavaScriptDialogOnPage:(WKPageRef)page WK_API_AVAILABLE(macosx(10.13), ios(11.0));
  • trunk/Source/WebKit/UIProcess/Automation/Automation.json

    r229984 r229998  
    291291                { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be made focused." },
    292292                { "name": "frameHandle", "$ref": "FrameHandle", "optional": true, "description": "The handle for the frame that should be focused. Defaults to the main frame if omitted." }
    293             ]
     293            ],
     294            "async": true
    294295        },
    295296        {
    296297            "name": "setWindowFrameOfBrowsingContext",
    297             "description": "Moves and/or resizes the window of the specified top-level browsing context to the specified size and origin. Both the size and origin may be omitted. Regardless of the arguments, this command will exit fullscreen and deminiaturize the window if applicable.",
     298            "description": "Moves and/or resizes the window of the specified top-level browsing context to the specified position and size. Both position and size may be omitted. This command implicitly exits fullscreen and restores the window (if previously hidden), then optionally sets the window frame.",
    298299            "parameters": [
    299300                { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context to be resized." },
    300301                { "name": "origin", "$ref": "Point", "optional": true, "description": "The new origin for the browsing context's window. The position is interpreted in screen coordinate space, relative to the upper left corner of the screen." },
    301302                { "name": "size", "$ref": "Size", "optional": true, "description": "The new size for the browsing context's window. The size is interpreted in screen pixels." }
     303            ],
     304            "async": true
     305        },
     306        {
     307            "name": "hideWindowOfBrowsingContext",
     308            "description": "Causes the window of the specified browsing context to be hidden/minimized/iconified. This command implicitly exits fullscreen mode.",
     309            "parameters": [
     310                { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context whose window should be hidden." }
    302311            ],
    303312            "async": true
  • trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp

    r229984 r229998  
    3636#include "WebAutomationSessionProxyMessages.h"
    3737#include "WebCookieManagerProxy.h"
     38#include "WebFullScreenManagerProxy.h"
    3839#include "WebInspectorProxy.h"
    3940#include "WebOpenPanelResultListenerProxy.h"
     
    300301}
    301302
    302 void WebAutomationSession::switchToBrowsingContext(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle)
    303 {
    304     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
    305     if (!page)
    306         SYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
     303void WebAutomationSession::switchToBrowsingContext(const String& browsingContextHandle, const String* optionalFrameHandle, Ref<SwitchToBrowsingContextCallback>&& callback)
     304{
     305    WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     306    if (!page)
     307        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
    307308
    308309    std::optional<uint64_t> frameID = webFrameIDForHandle(optionalFrameHandle ? *optionalFrameHandle : emptyString());
    309310    if (!frameID)
    310         SYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
    311 
    312     page->setFocus(true);
    313     page->process().send(Messages::WebAutomationSessionProxy::FocusFrame(page->pageID(), frameID.value()), 0);
     311        ASYNC_FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
     312
     313
     314    m_client->requestSwitchToPage(*this, *page, [frameID, page = makeRef(*page), callback = WTFMove(callback)]() {
     315        page->setFocus(true);
     316        page->process().send(Messages::WebAutomationSessionProxy::FocusFrame(page->pageID(), frameID.value()), 0);
     317
     318        callback->sendSuccess();
     319    });
    314320}
    315321
    316322void WebAutomationSession::setWindowFrameOfBrowsingContext(const String& handle, const JSON::Object* optionalOriginObject, const JSON::Object* optionalSizeObject, Ref<SetWindowFrameOfBrowsingContextCallback>&& callback)
    317323{
    318 #if PLATFORM(IOS)
    319     ASYNC_FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
    320 #else
    321324    std::optional<float> x;
    322325    std::optional<float> y;
     
    355358        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
    356359
    357     // FIXME (§10.7.2 Step 10): We need to exit fullscreen before setting the frame.
    358     // FIXME (§10.7.2 Step 11): We need to de-miniaturize the window before setting the frame.
    359 
    360     page->getWindowFrameWithCallback([callback = WTFMove(callback), page = makeRef(*page), width, height, x, y](WebCore::FloatRect originalFrame) mutable {
    361         WebCore::FloatRect newFrame = WebCore::FloatRect(WebCore::FloatPoint(x.value_or(originalFrame.location().x()), y.value_or(originalFrame.location().y())), WebCore::FloatSize(width.value_or(originalFrame.size().width()), height.value_or(originalFrame.size().height())));
    362         if (newFrame == originalFrame)
    363             return callback->sendSuccess();
    364 
    365         page->setWindowFrame(newFrame);
    366         callback->sendSuccess();
     360    exitFullscreenWindowForPage(*page, [this, protectedThis = makeRef(*this), callback = WTFMove(callback), page = makeRefPtr(page), width, height, x, y]() mutable {
     361        this->restoreWindowForPage(*page, [callback = WTFMove(callback), page = WTFMove(page), width, height, x, y]() mutable {
     362            page->getWindowFrameWithCallback([callback = WTFMove(callback), page = WTFMove(page), width, height, x, y](WebCore::FloatRect originalFrame) mutable {
     363                WebCore::FloatRect newFrame = WebCore::FloatRect(WebCore::FloatPoint(x.value_or(originalFrame.location().x()), y.value_or(originalFrame.location().y())), WebCore::FloatSize(width.value_or(originalFrame.size().width()), height.value_or(originalFrame.size().height())));
     364                if (newFrame != originalFrame)
     365                    page->setWindowFrame(newFrame);
     366               
     367                callback->sendSuccess();
     368            });
     369        });
    367370    });
    368 #endif
    369371}
    370372
     
    508510}
    509511
     512void WebAutomationSession::hideWindowOfBrowsingContext(const String& browsingContextHandle, Ref<HideWindowOfBrowsingContextCallback>&& callback)
     513{
     514    WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     515    if (!page)
     516        ASYNC_FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
     517   
     518    exitFullscreenWindowForPage(*page, [protectedThis = makeRef(*this), callback = WTFMove(callback), page = makeRefPtr(page)]() mutable {
     519        protectedThis->hideWindowForPage(*page, [callback = WTFMove(callback)]() mutable {
     520            callback->sendSuccess();
     521        });
     522    });
     523}
     524
     525void WebAutomationSession::exitFullscreenWindowForPage(WebPageProxy& page, WTF::CompletionHandler<void()>&& completionHandler)
     526{
     527#if ENABLE(FULLSCREEN_API)
     528    ASSERT(!m_windowStateTransitionCallback);
     529    if (!page.fullScreenManager()->isFullScreen()) {
     530        completionHandler();
     531        return;
     532    }
     533   
     534    m_windowStateTransitionCallback = WTF::Function<void(WindowTransitionedToState)> { [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](WindowTransitionedToState state) mutable {
     535        // If fullscreen exited and we didn't request that, just ignore it.
     536        if (state != WindowTransitionedToState::Unfullscreen)
     537            return;
     538
     539        // Keep this callback in scope so completionHandler does not get destroyed before we call it.
     540        auto protectedCallback = WTFMove(m_windowStateTransitionCallback);
     541        completionHandler();
     542    } };
     543   
     544    page.fullScreenManager()->requestExitFullScreen();
     545#else
     546    completionHandler();
     547#endif
     548}
     549
     550void WebAutomationSession::restoreWindowForPage(WebPageProxy& page, WTF::CompletionHandler<void()>&& completionHandler)
     551{
     552    m_client->requestRestoreWindowOfPage(*this, page, WTFMove(completionHandler));
     553}
     554
     555void WebAutomationSession::hideWindowForPage(WebPageProxy& page, WTF::CompletionHandler<void()>&& completionHandler)
     556{
     557    m_client->requestHideWindowOfPage(*this, page, WTFMove(completionHandler));
     558}
     559
    510560void WebAutomationSession::willShowJavaScriptDialog(WebPageProxy& page)
    511561{
     
    533583        }
    534584    });
     585}
     586   
     587void WebAutomationSession::didEnterFullScreenForPage(const WebPageProxy&)
     588{
     589    if (m_windowStateTransitionCallback)
     590        m_windowStateTransitionCallback(WindowTransitionedToState::Fullscreen);
     591}
     592
     593void WebAutomationSession::didExitFullScreenForPage(const WebPageProxy&)
     594{
     595    if (m_windowStateTransitionCallback)
     596        m_windowStateTransitionCallback(WindowTransitionedToState::Unfullscreen);
    535597}
    536598
  • trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h

    r229984 r229998  
    3232#include "ShareableBitmap.h"
    3333#include "WebEvent.h"
     34#include <wtf/CompletionHandler.h>
    3435#include <wtf/Forward.h>
    3536#include <wtf/RunLoop.h>
     
    101102    void handleRunOpenPanel(const WebPageProxy&, const WebFrameProxy&, const API::OpenPanelParameters&, WebOpenPanelResultListenerProxy&);
    102103    void willShowJavaScriptDialog(WebPageProxy&);
     104    void didEnterFullScreenForPage(const WebPageProxy&);
     105    void didExitFullScreenForPage(const WebPageProxy&);
    103106
    104107    bool shouldAllowGetUserMediaForPage(const WebPageProxy&) const;
     
    120123    void getBrowsingContexts(Ref<GetBrowsingContextsCallback>&&) final;
    121124    void getBrowsingContext(const String&, Ref<GetBrowsingContextCallback>&&) final;
    122     void closeBrowsingContext(Inspector::ErrorString&, const String&) override;
    123     void switchToBrowsingContext(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle) override;
    124125    void createBrowsingContext(const bool* preferNewTab, Ref<CreateBrowsingContextCallback>&&) final;
     126    void closeBrowsingContext(Inspector::ErrorString&, const String&) final;
     127    void switchToBrowsingContext(const String& browsingContextHandle, const String* optionalFrameHandle, Ref<SwitchToBrowsingContextCallback>&&) final;
    125128    void setWindowFrameOfBrowsingContext(const String& handle, const JSON::Object* origin, const JSON::Object* size, Ref<SetWindowFrameOfBrowsingContextCallback>&&) final;
     129    void hideWindowOfBrowsingContext(const String& handle, Ref<HideWindowOfBrowsingContextCallback>&&) final;
    126130    void navigateBrowsingContext(const String& handle, const String& url, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<NavigateBrowsingContextCallback>&&) override;
    127131    void goBackInBrowsingContext(const String&, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoBackInBrowsingContextCallback>&&) override;
     
    178182    void loadTimerFired();
    179183
     184    void exitFullscreenWindowForPage(WebPageProxy&, WTF::CompletionHandler<void()>&&);
     185    void restoreWindowForPage(WebPageProxy&, WTF::CompletionHandler<void()>&&);
     186    void hideWindowForPage(WebPageProxy&, WTF::CompletionHandler<void()>&&);
     187
    180188    // Implemented in generated WebAutomationSessionMessageReceiver.cpp.
    181189    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
     
    254262    HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::SelectOptionElementCallback>> m_selectOptionElementCallbacks;
    255263
     264    enum class WindowTransitionedToState {
     265        Fullscreen,
     266        Unfullscreen,
     267    };
     268    Function<void(WindowTransitionedToState)> m_windowStateTransitionCallback { };
     269
    256270    RunLoop::Timer<WebAutomationSession> m_loadTimer;
    257271    Vector<String> m_filesToSelectForFileUpload;
  • trunk/Source/WebKit/UIProcess/Cocoa/AutomationSessionClient.h

    r229984 r229998  
    4747
    4848    void requestNewPageWithOptions(WebAutomationSession&, API::AutomationSessionBrowsingContextOptions, CompletionHandler<void(WebPageProxy*)>&&) override;
     49    void requestSwitchToPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&, CompletionHandler<void()>&&) override;
     50    void requestHideWindowOfPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&, CompletionHandler<void()>&&) override;
     51    void requestRestoreWindowOfPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&, CompletionHandler<void()>&&) override;
     52
    4953    bool isShowingJavaScriptDialogOnPage(WebAutomationSession&, WebPageProxy&) override;
    5054    void dismissCurrentJavaScriptDialogOnPage(WebAutomationSession&, WebPageProxy&) override;
     
    6064
    6165        bool requestNewWebViewWithOptions : 1;
     66        bool requestSwitchToWebView : 1;
     67        bool requestHideWindowOfWebView : 1;
     68        bool requestRestoreWindowOfWebView : 1;
    6269        bool isShowingJavaScriptDialogForWebView : 1;
    6370        bool dismissCurrentJavaScriptDialogForWebView : 1;
     
    6976        // FIXME 37408718: these delegate methods should be removed.
    7077        bool requestNewPageWithOptions : 1;
     78        bool requestSwitchToPage : 1;
     79        bool requestHideWindowOfPage : 1;
     80        bool requestRestoreWindowOfPage : 1;
    7181        bool isShowingJavaScriptDialogOnPage : 1;
    7282        bool dismissCurrentJavaScriptDialogOnPage : 1;
  • trunk/Source/WebKit/UIProcess/Cocoa/AutomationSessionClient.mm

    r229984 r229998  
    4545
    4646    m_delegateMethods.requestNewWebViewWithOptions = [delegate respondsToSelector:@selector(_automationSession:requestNewWebViewWithOptions:completionHandler:)];
     47    m_delegateMethods.requestSwitchToWebView = [delegate respondsToSelector:@selector(_automationSession:requestSwitchToWebView:completionHandler:)];
     48    m_delegateMethods.requestHideWindowOfWebView = [delegate respondsToSelector:@selector(_automationSession:requestHideWindowOfWebView:completionHandler:)];
     49    m_delegateMethods.requestRestoreWindowOfWebView = [delegate respondsToSelector:@selector(_automationSession:requestRestoreWindowOfWebView:completionHandler:)];
    4750    m_delegateMethods.isShowingJavaScriptDialogForWebView = [delegate respondsToSelector:@selector(_automationSession:isShowingJavaScriptDialogForWebView:)];
    4851    m_delegateMethods.dismissCurrentJavaScriptDialogForWebView = [delegate respondsToSelector:@selector(_automationSession:dismissCurrentJavaScriptDialogForWebView:)];
     
    5457    // FIXME 37408718: these delegate methods should be removed.
    5558    m_delegateMethods.requestNewPageWithOptions = [delegate respondsToSelector:@selector(_automationSession:requestNewPageWithOptions:completionHandler:)];
     59    m_delegateMethods.requestSwitchToPage = [delegate respondsToSelector:@selector(_automationSession:requestSwitchToPage:completionHandler:)];
     60    m_delegateMethods.requestHideWindowOfPage = [delegate respondsToSelector:@selector(_automationSession:requestHideWindowOfPage:completionHandler:)];
     61    m_delegateMethods.requestRestoreWindowOfPage = [delegate respondsToSelector:@selector(_automationSession:requestRestoreWindowOfPage:completionHandler:)];
    5662    m_delegateMethods.isShowingJavaScriptDialogOnPage = [delegate respondsToSelector:@selector(_automationSession:isShowingJavaScriptDialogOnPage:)];
    5763    m_delegateMethods.dismissCurrentJavaScriptDialogOnPage = [delegate respondsToSelector:@selector(_automationSession:dismissCurrentJavaScriptDialogOnPage:)];
     
    9399}
    94100
     101void AutomationSessionClient::requestSwitchToPage(WebAutomationSession& session, WebPageProxy& page, CompletionHandler<void()>&& completionHandler)
     102{
     103    if (!m_delegateMethods.requestSwitchToWebView && !m_delegateMethods.requestSwitchToPage) {
     104        completionHandler();
     105        return;
     106    }
     107
     108    auto completionBlock = BlockPtr<void()>::fromCallable([completionHandler = WTFMove(completionHandler)]() { completionHandler(); });
     109    if (m_delegateMethods.requestSwitchToWebView)
     110        [m_delegate.get() _automationSession:wrapper(session) requestSwitchToWebView:fromWebPageProxy(page) completionHandler:completionBlock.get()];
     111    else if (m_delegateMethods.requestSwitchToPage)
     112        [m_delegate.get() _automationSession:wrapper(session) requestSwitchToPage:toAPI(&page) completionHandler:completionBlock.get()];
     113}
     114
     115void AutomationSessionClient::requestHideWindowOfPage(WebAutomationSession& session, WebPageProxy& page, CompletionHandler<void()>&& completionHandler)
     116{
     117    if (!m_delegateMethods.requestHideWindowOfWebView && !m_delegateMethods.requestHideWindowOfPage) {
     118        completionHandler();
     119        return;
     120    }
     121
     122    auto completionBlock = BlockPtr<void()>::fromCallable([completionHandler = WTFMove(completionHandler)]() { completionHandler(); });
     123    if (m_delegateMethods.requestHideWindowOfWebView)
     124        [m_delegate.get() _automationSession:wrapper(session) requestHideWindowOfWebView:fromWebPageProxy(page) completionHandler:completionBlock.get()];
     125    else if (m_delegateMethods.requestHideWindowOfPage)
     126        [m_delegate.get() _automationSession:wrapper(session) requestHideWindowOfPage:toAPI(&page) completionHandler:completionBlock.get()];
     127}
     128
     129void AutomationSessionClient::requestRestoreWindowOfPage(WebAutomationSession& session, WebPageProxy& page, CompletionHandler<void()>&& completionHandler)
     130{
     131    if (!m_delegateMethods.requestRestoreWindowOfWebView && !m_delegateMethods.requestRestoreWindowOfPage) {
     132        completionHandler();
     133        return;
     134    }
     135
     136    auto completionBlock = BlockPtr<void()>::fromCallable([completionHandler = WTFMove(completionHandler)]() { completionHandler(); });
     137    if (m_delegateMethods.requestRestoreWindowOfWebView)
     138        [m_delegate.get() _automationSession:wrapper(session) requestRestoreWindowOfWebView:fromWebPageProxy(page) completionHandler:completionBlock.get()];
     139    else if (m_delegateMethods.requestRestoreWindowOfPage)
     140        [m_delegate.get() _automationSession:wrapper(session) requestRestoreWindowOfPage:toAPI(&page) completionHandler:completionBlock.get()];
     141}
     142
    95143bool AutomationSessionClient::isShowingJavaScriptDialogOnPage(WebAutomationSession& session, WebPageProxy& page)
    96144{
    97145    if (m_delegateMethods.isShowingJavaScriptDialogForWebView)
    98146        return [m_delegate.get() _automationSession:wrapper(session) isShowingJavaScriptDialogForWebView:fromWebPageProxy(page)];
    99 
    100     if (m_delegateMethods.isShowingJavaScriptDialogOnPage)
     147    else if (m_delegateMethods.isShowingJavaScriptDialogOnPage)
    101148        return [m_delegate.get() _automationSession:wrapper(session) isShowingJavaScriptDialogOnPage:toAPI(&page)];
    102 
     149   
    103150    return false;
    104151}
  • trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp

    r229475 r229998  
    3030
    3131#include "APIFullscreenClient.h"
     32#include "WebAutomationSession.h"
    3233#include "WebFullScreenManagerMessages.h"
    3334#include "WebFullScreenManagerProxyMessages.h"
    3435#include "WebPageProxy.h"
     36#include "WebProcessPool.h"
    3537#include "WebProcessProxy.h"
    3638#include <WebCore/IntRect.h>
     
    6668    m_page->fullscreenClient().didEnterFullscreen(m_page);
    6769    m_page->process().send(Messages::WebFullScreenManager::DidEnterFullScreen(), m_page->pageID());
     70
     71    if (m_page->isControlledByAutomation()) {
     72        if (WebAutomationSession* automationSession = m_page->process().processPool().automationSession())
     73            automationSession->didEnterFullScreenForPage(*m_page);
     74    }
    6875}
    6976
     
    7885    m_page->fullscreenClient().didExitFullscreen(m_page);
    7986    m_page->process().send(Messages::WebFullScreenManager::DidExitFullScreen(), m_page->pageID());
     87   
     88    if (m_page->isControlledByAutomation()) {
     89        if (WebAutomationSession* automationSession = m_page->process().processPool().automationSession())
     90            automationSession->didExitFullScreenForPage(*m_page);
     91    }
    8092}
    8193
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r229960 r229998  
    15481548                99C81D5A1C20E7E2005C4C82 /* AutomationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 99C81D551C20DFBE005C4C82 /* AutomationClient.h */; };
    15491549                99C81D5D1C21F38B005C4C82 /* APIAutomationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 99C81D5B1C20E817005C4C82 /* APIAutomationClient.h */; };
     1550                99CA66CA2036685D0074F35E /* EnterFullscreen.js in Copy WebDriver Atoms */ = {isa = PBXBuildFile; fileRef = 99CA66C8203668220074F35E /* EnterFullscreen.js */; };
    15501551                99E714C51C124A0400665B3A /* _WKAutomationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E714C11C1249E600665B3A /* _WKAutomationDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
    15511552                9F54F88F16488E87007DF81A /* ChildProcessMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9F54F88E16488E87007DF81A /* ChildProcessMac.mm */; };
     
    23442345                        dstSubfolderSpec = 1;
    23452346                        files = (
     2347                                99CA66CA2036685D0074F35E /* EnterFullscreen.js in Copy WebDriver Atoms */,
    23462348                                99B750F21F33ED5B00C1CFB5 /* ElementAttribute.js in Copy WebDriver Atoms */,
    23472349                                99B750F31F33ED5B00C1CFB5 /* ElementDisplayed.js in Copy WebDriver Atoms */,
     
    40344036                99C81D561C20DFBE005C4C82 /* AutomationClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutomationClient.mm; sourceTree = "<group>"; };
    40354037                99C81D5B1C20E817005C4C82 /* APIAutomationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIAutomationClient.h; sourceTree = "<group>"; };
     4038                99CA66C8203668220074F35E /* EnterFullscreen.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = EnterFullscreen.js; sourceTree = "<group>"; };
    40364039                99E714C11C1249E600665B3A /* _WKAutomationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKAutomationDelegate.h; sourceTree = "<group>"; };
    40374040                99F642D21FABE378009621E9 /* CoordinateSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoordinateSystem.h; sourceTree = "<group>"; };
     
    69196922                                990657341F323CBF00944F9C /* ElementAttribute.js */,
    69206923                                990657331F323CBF00944F9C /* ElementDisplayed.js */,
     6924                                99CA66C8203668220074F35E /* EnterFullscreen.js */,
    69216925                                990657311F323CBF00944F9C /* FindNodes.js */,
    69226926                                990657321F323CBF00944F9C /* FormElementClear.js */,
Note: See TracChangeset for help on using the changeset viewer.