Changeset 120908 in webkit


Ignore:
Timestamp:
Jun 21, 2012 1:07:56 AM (12 years ago)
Author:
mario@webkit.org
Message:

[GTK] Add support for window.showModalDialog in WebKit2GTK+
https://bugs.webkit.org/show_bug.cgi?id=79500

Reviewed by Carlos Garcia Campos.

Source/WebKit2:

Implement runModal in WebKitUIClient to make the WebKitWebView
emit a 'run-as-modal' signal when requested, creating a new
mainloop there to block user interaction with the original window
while the modal dialog is showing.

  • UIProcess/API/gtk/WebKitUIClient.cpp:

(runModal): Call to the new webkitWebViewRunAsModalPage function.
(attachUIClientToView): Add runModal.

  • UIProcess/API/gtk/WebKitWebView.cpp:

(_WebKitWebViewPrivate): Add an atribute for a new main loop.
(webkitWebViewFinalize): Make sure the main loop for main dialogs,
if any, is stopped if it was still running.
(webkit_web_view_class_init): Declare new signal 'run-as-modal'.
(webkitWebViewRunAsModal): Emit the 'run-as-modal' signal and, if
handled, create and run a new main loop.

  • UIProcess/API/gtk/WebKitWebView.h:

(_WebKitWebViewClass): New handler for the 'run-as-modal' signal.

  • UIProcess/API/gtk/WebKitWebViewPrivate.h: Add webkitWebViewRunAsModalPage.

Allow setting and getting the value of WebPage's canRunModal
attribute in the WebProcess from the UIProcess after the creation
of a WebPage, to allow using it from WebKitWebView to allow the
client application to decide whether to allow create modal
dialogs, which would result in launching an additional nested
event loop in the web process, after creating the dialog.

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::WebPageProxy): Initialize the new
m_canRunModal attribute, to cache the current status of the
WebPage in the WebProcess.
(WebKit::WebPageProxy::initializeUIClient): Call the new function
setCanRunModal, instead of manually sending the SetCanRunModal message.
(WebKit::WebPageProxy::creationParameters): Use m_canRunModal
instead of m_uiClient.canRunModal when preparing the parameters.
(WebKit::WebPageProxy::setCanRunModal): New public function, it
sets the value of m_canRunModal and sends a message to the Web
process for updating the WebPage, whenever possible.
(WebKit::WebPageProxy::canRunModal): New public function, returns
the value of the m_canRunModal attribute.

  • UIProcess/WebPageProxy.h:

(WebPageProxy): Added new public functions and private attribute.

New property in WebKitSettings to be able to decide whether it is
allowed to create and run new child webviews as modal dialogs.

  • UIProcess/API/gtk/WebKitSettings.cpp:

(_WebKitSettingsPrivate): New attribute allowModalDialogs.
(webKitSettingsSetProperty): Handle the new property.
(webKitSettingsGetProperty): Ditto.
(webkit_settings_class_init): Install the new property.
(webkitSettingsAttachSettingsToPage): Make sure the WebPage is
initialized with the value of the new property.
(webkit_settings_set_allow_modal_dialogs): New setter.
(webkit_settings_get_allow_modal_dialogs): New getter.

  • UIProcess/API/gtk/WebKitSettings.h:
  • UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Added new accessors.

Connect to the 'notify::allow-modal-dialogs' signal from
WebKitSettings to ensure that canRunModal property of the WebPage
is kept up to date. Ensure that signal handlers for monitoring
settings are disconnected when the webview is finalized.

  • UIProcess/API/gtk/WebKitWebView.cpp:

(webkitWebViewSetSettings): Connect to the new signal
'notify::allow-modal-dialogs', from WebKitSettings.
(allowModalDialogsChanged): Callback to update WebPage's
canRunModal property when updated through WebKitSettings.
(webkitWebViewDisconnectSettingsSignalHandlers): Disconnect signal
handlers for monitoring WebKitSettings properties.
(webkitWebViewFinalize): Ensure signal handlers are disconnected.
(webkit_web_view_set_settings): Ditto.

  • UIProcess/API/gtk/WebKitWebView.h:

Add new unit tests to check the 'run-as-modal' signal is emitted
only when the new property in WebKitSettings is set to TRUE.

  • UIProcess/API/gtk/tests/TestWebKitWebView.cpp:

(testWebViewAllowModalDialogs): New unit test to check that modal
dialogs are properly created from JavaScript when allowed.
(testWebViewDisallowModalDialogs): New unit test to check that
it's not possible to create modal dialogs when not allowed.
(beforeAll): Add the new unit test.

Tools:

Add support for modal dialogs in GTK's MiniBrowser.

  • MiniBrowser/gtk/BrowserWindow.c:

(webViewRunAsModal):
(webViewCreate):
(webViewDecidePolicy):
(browser_window_new):

  • MiniBrowser/gtk/BrowserWindow.h:
  • MiniBrowser/gtk/main.c:

(createBrowserWindow):

Location:
trunk
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r120890 r120908  
     12012-06-21  Mario Sanchez Prada  <msanchez@igalia.com>
     2
     3        [GTK] Add support for window.showModalDialog in WebKit2GTK+
     4        https://bugs.webkit.org/show_bug.cgi?id=79500
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        Implement runModal in WebKitUIClient to make the WebKitWebView
     9        emit a 'run-as-modal' signal when requested, creating a new
     10        mainloop there to block user interaction with the original window
     11        while the modal dialog is showing.
     12
     13        * UIProcess/API/gtk/WebKitUIClient.cpp:
     14        (runModal): Call to the new webkitWebViewRunAsModalPage function.
     15        (attachUIClientToView): Add runModal.
     16        * UIProcess/API/gtk/WebKitWebView.cpp:
     17        (_WebKitWebViewPrivate): Add an atribute for a new main loop.
     18        (webkitWebViewFinalize): Make sure the main loop for main dialogs,
     19        if any, is stopped if it was still running.
     20        (webkit_web_view_class_init): Declare new signal 'run-as-modal'.
     21        (webkitWebViewRunAsModal): Emit the 'run-as-modal' signal and, if
     22        handled, create and run a new main loop.
     23        * UIProcess/API/gtk/WebKitWebView.h:
     24        (_WebKitWebViewClass): New handler for the 'run-as-modal' signal.
     25        * UIProcess/API/gtk/WebKitWebViewPrivate.h: Add webkitWebViewRunAsModalPage.
     26
     27        Allow setting and getting the value of WebPage's canRunModal
     28        attribute in the WebProcess from the UIProcess after the creation
     29        of a WebPage, to allow using it from WebKitWebView to allow the
     30        client application to decide whether to allow create modal
     31        dialogs, which would result in launching an additional nested
     32        event loop in the web process, after creating the dialog.
     33
     34        * UIProcess/WebPageProxy.cpp:
     35        (WebKit::WebPageProxy::WebPageProxy): Initialize the new
     36        m_canRunModal attribute, to cache the current status of the
     37        WebPage in the WebProcess.
     38        (WebKit::WebPageProxy::initializeUIClient): Call the new function
     39        setCanRunModal, instead of manually sending the SetCanRunModal message.
     40        (WebKit::WebPageProxy::creationParameters): Use m_canRunModal
     41        instead of m_uiClient.canRunModal when preparing the parameters.
     42        (WebKit::WebPageProxy::setCanRunModal): New public function, it
     43        sets the value of m_canRunModal and sends a message to the Web
     44        process for updating the WebPage, whenever possible.
     45        (WebKit::WebPageProxy::canRunModal): New public function, returns
     46        the value of the m_canRunModal attribute.
     47        * UIProcess/WebPageProxy.h:
     48        (WebPageProxy): Added new public functions and private attribute.
     49
     50        New property in WebKitSettings to be able to decide whether it is
     51        allowed to create and run new child webviews as modal dialogs.
     52
     53        * UIProcess/API/gtk/WebKitSettings.cpp:
     54        (_WebKitSettingsPrivate): New attribute allowModalDialogs.
     55        (webKitSettingsSetProperty): Handle the new property.
     56        (webKitSettingsGetProperty): Ditto.
     57        (webkit_settings_class_init): Install the new property.
     58        (webkitSettingsAttachSettingsToPage): Make sure the WebPage is
     59        initialized with the value of the new property.
     60        (webkit_settings_set_allow_modal_dialogs): New setter.
     61        (webkit_settings_get_allow_modal_dialogs): New getter.
     62        * UIProcess/API/gtk/WebKitSettings.h:
     63        * UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Added new accessors.
     64
     65        Connect to the 'notify::allow-modal-dialogs' signal from
     66        WebKitSettings to ensure that canRunModal property of the WebPage
     67        is kept up to date. Ensure that signal handlers for monitoring
     68        settings are disconnected when the webview is finalized.
     69
     70        * UIProcess/API/gtk/WebKitWebView.cpp:
     71        (webkitWebViewSetSettings): Connect to the new signal
     72        'notify::allow-modal-dialogs', from WebKitSettings.
     73        (allowModalDialogsChanged): Callback to update WebPage's
     74        canRunModal property when updated through WebKitSettings.
     75        (webkitWebViewDisconnectSettingsSignalHandlers): Disconnect signal
     76        handlers for monitoring WebKitSettings properties.
     77        (webkitWebViewFinalize): Ensure signal handlers are disconnected.
     78        (webkit_web_view_set_settings): Ditto.
     79        * UIProcess/API/gtk/WebKitWebView.h:
     80
     81        Add new unit tests to check the 'run-as-modal' signal is emitted
     82        only when the new property in WebKitSettings is set to TRUE.
     83
     84        * UIProcess/API/gtk/tests/TestWebKitWebView.cpp:
     85        (testWebViewAllowModalDialogs): New unit test to check that modal
     86        dialogs are properly created from JavaScript when allowed.
     87        (testWebViewDisallowModalDialogs): New unit test to check that
     88        it's not possible to create modal dialogs when not allowed.
     89        (beforeAll): Add the new unit test.
     90
    1912012-06-20  Thiago Marcos P. Santos  <thiago.santos@intel.com>
    292
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp

    r118183 r120908  
    3434#include "WebKitPrivate.h"
    3535#include "WebKitSettingsPrivate.h"
     36#include "WebPageProxy.h"
    3637#include <glib/gi18n-lib.h>
    3738#include <wtf/text/CString.h>
     
    4748    CString pictographFontFamily;
    4849    CString defaultCharset;
     50    bool allowModalDialogs;
    4951    bool zoomTextOnly;
    5052};
     
    106108    PROP_ENABLE_WEBAUDIO,
    107109    PROP_ENABLE_WEBGL,
     110    PROP_ALLOW_MODAL_DIALOGS,
    108111    PROP_ZOOM_TEXT_ONLY,
    109112    PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD,
     
    217220        webkit_settings_set_enable_webgl(settings, g_value_get_boolean(value));
    218221        break;
     222    case PROP_ALLOW_MODAL_DIALOGS:
     223        webkit_settings_set_allow_modal_dialogs(settings, g_value_get_boolean(value));
     224        break;
    219225    case PROP_ZOOM_TEXT_ONLY:
    220226        webkit_settings_set_zoom_text_only(settings, g_value_get_boolean(value));
     
    341347    case PROP_ENABLE_WEBGL:
    342348        g_value_set_boolean(value, webkit_settings_get_enable_webgl(settings));
     349        break;
     350    case PROP_ALLOW_MODAL_DIALOGS:
     351        g_value_set_boolean(value, webkit_settings_get_allow_modal_dialogs(settings));
    343352        break;
    344353    case PROP_ZOOM_TEXT_ONLY:
     
    854863
    855864    /**
     865     * WebKitSettings:allow-modal-dialogs:
     866     *
     867     * Determine whether it's allowed to create and run modal dialogs
     868     * from a #WebKitWebView through JavaScript with
     869     * <function>window.showModalDialog</function>. If it's set to
     870     * %FALSE, the associated #WebKitWebView won't be able to create
     871     * new modal dialogs, so not even the #WebKitWebView::create
     872     * signal will be emitted.
     873     */
     874    g_object_class_install_property(gObjectClass,
     875                                    PROP_ALLOW_MODAL_DIALOGS,
     876                                    g_param_spec_boolean("allow-modal-dialogs",
     877                                                         _("Allow modal dialogs"),
     878                                                         _("Whether it is possible to create modal dialogs"),
     879                                                         FALSE,
     880                                                         readWriteConstructParamFlags));
     881
     882    /**
    856883     * WebKitSettings:zoom-text-only:
    857884     *
     
    970997{
    971998    WKPageGroupSetPreferences(WKPageGetPageGroup(wkPage), settings->priv->preferences.get());
     999    WebKit::toImpl(wkPage)->setCanRunModal(settings->priv->allowModalDialogs);
    9721000}
    9731001
     
    21902218
    21912219/**
     2220 * webkit_settings_set_allow_modal_dialogs:
     2221 * @settings: a #WebKitSettings
     2222 * @allowed: Value to be set
     2223 *
     2224 * Set the #WebKitSettings:allow-modal-dialogs property.
     2225 */
     2226void webkit_settings_set_allow_modal_dialogs(WebKitSettings* settings, gboolean allowed)
     2227{
     2228    g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
     2229
     2230    WebKitSettingsPrivate* priv = settings->priv;
     2231    if (priv->allowModalDialogs == allowed)
     2232        return;
     2233
     2234    priv->allowModalDialogs = allowed;
     2235    g_object_notify(G_OBJECT(settings), "allow-modal-dialogs");
     2236}
     2237
     2238/**
     2239 * webkit_settings_get_allow_modal_dialogs:
     2240 * @settings: a #WebKitSettings
     2241 *
     2242 * Get the #WebKitSettings:allow-modal-dialogs property.
     2243 *
     2244 * Returns: %TRUE if it's allowed to create and run modal dialogs or %FALSE otherwise.
     2245 */
     2246gboolean webkit_settings_get_allow_modal_dialogs(WebKitSettings* settings)
     2247{
     2248    g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE);
     2249    return settings->priv->allowModalDialogs;
     2250}
     2251
     2252/**
    21922253 * webkit_settings_set_zoom_text_only:
    21932254 * @settings: a #WebKitSettings
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h

    r118183 r120908  
    309309
    310310WEBKIT_API void
     311webkit_settings_set_allow_modal_dialogs                        (WebKitSettings *settings,
     312                                                                gboolean        allowed);
     313
     314WEBKIT_API gboolean
     315webkit_settings_get_allow_modal_dialogs                        (WebKitSettings *settings);
     316
     317WEBKIT_API void
    311318webkit_settings_set_zoom_text_only                             (WebKitSettings *settings,
    312319                                                                gboolean        zoom_text_only);
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp

    r119475 r120908  
    150150    GRefPtr<WebKitGeolocationPermissionRequest> geolocationPermissionRequest = adoptGRef(webkitGeolocationPermissionRequestCreate(request));
    151151    webkitWebViewMakePermissionRequest(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_PERMISSION_REQUEST(geolocationPermissionRequest.get()));
     152}
     153
     154static void runModal(WKPageRef page, const void* clientInfo)
     155{
     156    webkitWebViewRunAsModal(WEBKIT_WEB_VIEW(clientInfo));
    152157}
    153158
     
    192197        0, // drawFooter
    193198        printFrame,
    194         0, // runModal
     199        runModal,
    195200        0, // didCompleteRubberBandForMainFrame
    196201        0, // saveDataToFileInDownloadsFolder
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp

    r120305 r120908  
    6666    CREATE,
    6767    READY_TO_SHOW,
     68    RUN_AS_MODAL,
    6869    CLOSE,
    6970
     
    118119    GRefPtr<WebKitSettings> settings;
    119120    GRefPtr<WebKitWindowProperties> windowProperties;
     121
     122    GRefPtr<GMainLoop> modalLoop;
    120123
    121124    GRefPtr<WebKitHitTestResult> mouseTargetHitTestResult;
     
    224227}
    225228
     229static void allowModalDialogsChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
     230{
     231    WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
     232    if (!page)
     233        return;
     234    page->setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings));
     235}
     236
    226237static void zoomTextOnlyChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
    227238{
     
    237248    webView->priv->settings = settings;
    238249    webkitSettingsAttachSettingsToPage(webView->priv->settings.get(), wkPage);
     250    g_signal_connect(settings, "notify::allow-modal-dialogs", G_CALLBACK(allowModalDialogsChanged), webView);
    239251    g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView);
     252}
     253
     254static void webkitWebViewDisconnectSettingsSignalHandlers(WebKitWebView* webView)
     255{
     256    WebKitSettings* settings = webView->priv->settings.get();
     257    g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(allowModalDialogsChanged), webView);
     258    g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(zoomTextOnlyChanged), webView);
     259
    240260}
    241261
     
    354374{
    355375    WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(object)->priv;
     376
    356377    if (priv->javascriptGlobalContext)
    357378        JSGlobalContextRelease(priv->javascriptGlobalContext);
     379
     380    // For modal dialogs, make sure the main loop is stopped when finalizing the webView.
     381    if (priv->modalLoop && g_main_loop_is_running(priv->modalLoop.get()))
     382        g_main_loop_quit(priv->modalLoop.get());
     383
     384    webkitWebViewDisconnectSettingsSignalHandlers(WEBKIT_WEB_VIEW(object));
     385
    358386    priv->~WebKitWebViewPrivate();
    359387    G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
     
    605633                     G_TYPE_NONE, 0);
    606634
     635     /**
     636     * WebKitWebView::run-as-modal:
     637     * @web_view: the #WebKitWebView on which the signal is emitted
     638     *
     639     * Emitted after #WebKitWebView::ready-to-show on the newly
     640     * created #WebKitWebView when JavaScript code calls
     641     * <function>window.showModalDialog</function>. The purpose of
     642     * this signal is to allow the client application to prepare the
     643     * new view to behave as modal. Once the signal is emitted a new
     644     * mainloop will be run to block user interaction in the parent
     645     * #WebKitWebView until the new dialog is closed.
     646     */
     647    signals[RUN_AS_MODAL] =
     648            g_signal_new("run-as-modal",
     649                         G_TYPE_FROM_CLASS(webViewClass),
     650                         G_SIGNAL_RUN_LAST,
     651                         G_STRUCT_OFFSET(WebKitWebViewClass, run_as_modal),
     652                         0, 0,
     653                         g_cclosure_marshal_VOID__VOID,
     654                         G_TYPE_NONE, 0);
     655
    607656    /**
    608657     * WebKitWebView::close:
     
    10331082{
    10341083    g_signal_emit(webView, signals[READY_TO_SHOW], 0, NULL);
     1084}
     1085
     1086void webkitWebViewRunAsModal(WebKitWebView* webView)
     1087{
     1088    g_signal_emit(webView, signals[RUN_AS_MODAL], 0, NULL);
     1089
     1090    webView->priv->modalLoop = adoptGRef(g_main_loop_new(0, FALSE));
     1091    GDK_THREADS_ENTER();
     1092    g_main_loop_run(webView->priv->modalLoop.get());
     1093    GDK_THREADS_LEAVE();
    10351094}
    10361095
     
    16851744        return;
    16861745
    1687     g_signal_handlers_disconnect_by_func(webView->priv->settings.get(), reinterpret_cast<gpointer>(zoomTextOnlyChanged), webView);
     1746    webkitWebViewDisconnectSettingsSignalHandlers(webView);
    16881747    webkitWebViewSetSettings(webView, settings, toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))));
    16891748}
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h

    r118786 r120908  
    137137    GtkWidget *(* create)                (WebKitWebView             *web_view);
    138138    void       (* ready_to_show)         (WebKitWebView             *web_view);
     139    void       (* run_as_modal)          (WebKitWebView             *web_view);
    139140    void       (* close)                 (WebKitWebView             *web_view);
    140141
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h

    r120305 r120908  
    3939WKPageRef webkitWebViewCreateNewPage(WebKitWebView*, WKDictionaryRef wkWindowFeatures);
    4040void webkitWebViewReadyToShowPage(WebKitWebView*);
     41void webkitWebViewRunAsModal(WebKitWebView*);
    4142void webkitWebViewClosePage(WebKitWebView*);
    4243void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message);
  • trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt

    r120297 r120908  
    257257webkit_settings_get_enable_webgl
    258258webkit_settings_set_enable_webgl
     259webkit_settings_set_allow_modal_dialogs
     260webkit_settings_get_allow_modal_dialogs
    259261webkit_settings_get_zoom_text_only
    260262webkit_settings_set_zoom_text_only
  • trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp

    r118183 r120908  
    200200    g_assert(webkit_settings_get_enable_webgl(settings));
    201201
     202    // Allow Modal Dialogs is disabled by default.
     203    g_assert(!webkit_settings_get_allow_modal_dialogs(settings));
     204    webkit_settings_set_allow_modal_dialogs(settings, TRUE);
     205    g_assert(webkit_settings_get_allow_modal_dialogs(settings));
     206
    202207    // Zoom text only is disabled by default.
    203208    g_assert(!webkit_settings_get_zoom_text_only(settings));
  • trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp

    r120297 r120908  
    104104        Create,
    105105        ReadyToShow,
     106        RunAsModal,
    106107        Close
    107108    };
     
    179180    }
    180181
    181     static void viewClose(WebKitWebView* webView, UIClientTest* test)
    182     {
    183         g_assert(webView != test->m_webView);
    184 
    185         test->m_webViewEvents.append(Close);
    186         g_object_unref(webView);
    187 
    188         g_main_loop_quit(test->m_mainLoop);
    189     }
    190 
    191     static void viewReadyToShow(WebKitWebView* webView, UIClientTest* test)
    192     {
    193         g_assert(webView != test->m_webView);
    194 
    195         WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(webView);
    196         g_assert(windowProperties);
    197         WindowProperties(windowProperties).assertEqual(test->m_windowProperties);
    198 
    199         test->m_webViewEvents.append(ReadyToShow);
    200     }
    201 
    202     static GtkWidget* viewCreate(WebKitWebView* webView, UIClientTest* test)
    203     {
    204         g_assert(webView == test->m_webView);
    205 
    206         GtkWidget* newWebView = webkit_web_view_new_with_context(webkit_web_view_get_context(webView));
    207         g_object_ref_sink(newWebView);
    208 
    209         test->m_webViewEvents.append(Create);
    210 
    211         WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(newWebView));
    212         g_assert(windowProperties);
    213         test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(windowProperties));
    214         test->m_windowPropertiesChanged.clear();
    215         g_signal_connect(windowProperties, "notify", G_CALLBACK(windowPropertiesNotifyCallback), test);
    216 
    217         g_signal_connect(newWebView, "ready-to-show", G_CALLBACK(viewReadyToShow), test);
    218         g_signal_connect(newWebView, "close", G_CALLBACK(viewClose), test);
    219 
    220         return newWebView;
     182    static GtkWidget* viewCreateCallback(WebKitWebView* webView, UIClientTest* test)
     183    {
     184        return test->viewCreate(webView);
     185    }
     186
     187    static void viewReadyToShowCallback(WebKitWebView* webView, UIClientTest* test)
     188    {
     189        test->viewReadyToShow(webView);
     190    }
     191
     192    static void viewCloseCallback(WebKitWebView* webView, UIClientTest* test)
     193    {
     194        test->viewClose(webView);
    221195    }
    222196
     
    301275    {
    302276        webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(m_webView), TRUE);
    303         g_signal_connect(m_webView, "create", G_CALLBACK(viewCreate), this);
     277        g_signal_connect(m_webView, "create", G_CALLBACK(viewCreateCallback), this);
    304278        g_signal_connect(m_webView, "script-dialog", G_CALLBACK(scriptDialog), this);
    305279        g_signal_connect(m_webView, "mouse-target-changed", G_CALLBACK(mouseTargetChanged), this);
     
    327301        g_main_loop_run(m_mainLoop);
    328302        return m_mouseTargetHitTestResult.get();
     303    }
     304
     305    virtual GtkWidget* viewCreate(WebKitWebView* webView)
     306    {
     307        g_assert(webView == m_webView);
     308
     309        GtkWidget* newWebView = webkit_web_view_new_with_context(webkit_web_view_get_context(webView));
     310        g_object_ref_sink(newWebView);
     311
     312        m_webViewEvents.append(Create);
     313
     314        WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(newWebView));
     315        g_assert(windowProperties);
     316        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(windowProperties));
     317        m_windowPropertiesChanged.clear();
     318
     319        g_signal_connect(windowProperties, "notify", G_CALLBACK(windowPropertiesNotifyCallback), this);
     320        g_signal_connect(newWebView, "ready-to-show", G_CALLBACK(viewReadyToShowCallback), this);
     321        g_signal_connect(newWebView, "close", G_CALLBACK(viewCloseCallback), this);
     322
     323        return newWebView;
     324    }
     325
     326    virtual void viewReadyToShow(WebKitWebView* webView)
     327    {
     328        g_assert(webView != m_webView);
     329
     330        WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(webView);
     331        g_assert(windowProperties);
     332        WindowProperties(windowProperties).assertEqual(m_windowProperties);
     333
     334        m_webViewEvents.append(ReadyToShow);
     335    }
     336
     337    virtual void viewClose(WebKitWebView* webView)
     338    {
     339        g_assert(webView != m_webView);
     340
     341        m_webViewEvents.append(Close);
     342        g_object_unref(webView);
     343
     344        g_main_loop_quit(m_mainLoop);
    329345    }
    330346
     
    357373    filterInfo.mime_type = mimeType;
    358374    return gtk_file_filter_filter(filter, &filterInfo);
     375}
     376
     377class ModalDialogsTest: public UIClientTest {
     378public:
     379    MAKE_GLIB_TEST_FIXTURE(ModalDialogsTest);
     380
     381    static void dialogRunAsModalCallback(WebKitWebView* webView, ModalDialogsTest* test)
     382    {
     383        g_assert(webView != test->m_webView);
     384        test->m_webViewEvents.append(RunAsModal);
     385    }
     386
     387    GtkWidget* viewCreate(WebKitWebView* webView)
     388    {
     389        g_assert(webView == m_webView);
     390
     391        GtkWidget* newWebView = UIClientTest::viewCreate(webView);
     392        g_signal_connect(newWebView, "run-as-modal", G_CALLBACK(dialogRunAsModalCallback), this);
     393        return newWebView;
     394    }
     395
     396    void viewReadyToShow(WebKitWebView* webView)
     397    {
     398        g_assert(webView != m_webView);
     399        m_webViewEvents.append(ReadyToShow);
     400    }
     401};
     402
     403static void testWebViewAllowModalDialogs(ModalDialogsTest* test, gconstpointer)
     404{
     405    WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView);
     406    webkit_settings_set_allow_modal_dialogs(settings, TRUE);
     407
     408    test->loadHtml("<html><body onload=\"window.showModalDialog('data:text/html,<html><body/><script>window.close();</script></html>')\"></body></html>", 0);
     409    test->waitUntilMainLoopFinishes();
     410
     411    Vector<UIClientTest::WebViewEvents>& events = test->m_webViewEvents;
     412    g_assert_cmpint(events.size(), ==, 4);
     413    g_assert_cmpint(events[0], ==, UIClientTest::Create);
     414    g_assert_cmpint(events[1], ==, UIClientTest::ReadyToShow);
     415    g_assert_cmpint(events[2], ==, UIClientTest::RunAsModal);
     416    g_assert_cmpint(events[3], ==, UIClientTest::Close);
     417}
     418
     419static void testWebViewDisallowModalDialogs(ModalDialogsTest* test, gconstpointer)
     420{
     421    WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView);
     422    webkit_settings_set_allow_modal_dialogs(settings, FALSE);
     423
     424    test->loadHtml("<html><body onload=\"window.showModalDialog('data:text/html,<html><body/><script>window.close();</script></html>')\"></body></html>", 0);
     425    // We need to use a timeout here because the viewClose() function
     426    // won't ever be called as the dialog won't be created.
     427    test->wait(1);
     428
     429    Vector<UIClientTest::WebViewEvents>& events = test->m_webViewEvents;
     430    g_assert_cmpint(events.size(), ==, 0);
    359431}
    360432
     
    796868    WebViewTest::add("WebKitWebView", "replace-content", testWebViewReplaceContent);
    797869    UIClientTest::add("WebKitWebView", "create-ready-close", testWebViewCreateReadyClose);
     870    ModalDialogsTest::add("WebKitWebView", "allow-modal-dialogs", testWebViewAllowModalDialogs);
     871    ModalDialogsTest::add("WebKitWebView", "disallow-modal-dialogs", testWebViewDisallowModalDialogs);
    798872    UIClientTest::add("WebKitWebView", "javascript-dialogs", testWebViewJavaScriptDialogs);
    799873    UIClientTest::add("WebKitWebView", "window-properties", testWebViewWindowProperties);
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r120890 r120908  
    188188    , m_isValid(true)
    189189    , m_isClosed(false)
     190    , m_canRunModal(false)
    190191    , m_isInPrintingMode(false)
    191192    , m_isPerformingDOMPrintOperation(false)
     
    306307
    307308    process()->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient.canRunBeforeUnloadConfirmPanel()), m_pageID);
    308     process()->send(Messages::WebPage::SetCanRunModal(m_uiClient.canRunModal()), m_pageID);
     309    setCanRunModal(m_uiClient.canRunModal());
    309310}
    310311
     
    35513552    parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highedUsedItemID();
    35523553    parameters.canRunBeforeUnloadConfirmPanel = m_uiClient.canRunBeforeUnloadConfirmPanel();
    3553     parameters.canRunModal = m_uiClient.canRunModal();
     3554    parameters.canRunModal = m_canRunModal;
    35543555    parameters.deviceScaleFactor = m_intrinsicDeviceScaleFactor;
    35553556    parameters.mediaVolume = m_mediaVolume;
     
    37583759}
    37593760
     3761void WebPageProxy::setCanRunModal(bool canRunModal)
     3762{
     3763    if (!isValid())
     3764        return;
     3765
     3766    // It's only possible to change the state for a WebPage which
     3767    // already qualifies for running modal child web pages, otherwise
     3768    // there's no other possibility than not allowing it.
     3769    m_canRunModal = m_uiClient.canRunModal() && canRunModal;
     3770    process()->send(Messages::WebPage::SetCanRunModal(m_canRunModal), m_pageID);
     3771}
     3772
     3773bool WebPageProxy::canRunModal()
     3774{
     3775    return isValid() ? m_canRunModal : false;
     3776}
     3777
    37603778void WebPageProxy::beginPrinting(WebFrameProxy* frame, const PrintInfo& printInfo)
    37613779{
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r120890 r120908  
    644644    String accessibilityPlugID() const { return m_accessibilityPlugID; }
    645645#endif
     646
     647    void setCanRunModal(bool);
     648    bool canRunModal();
    646649
    647650    void beginPrinting(WebFrameProxy*, const PrintInfo&);
     
    10771080    bool m_isClosed;
    10781081
     1082    // Whether it can run modal child web pages.
     1083    bool m_canRunModal;
     1084
    10791085    bool m_isInPrintingMode;
    10801086    bool m_isPerformingDOMPrintOperation;
  • trunk/Tools/ChangeLog

    r120901 r120908  
     12012-06-21  Mario Sanchez Prada  <msanchez@igalia.com>
     2
     3        [GTK] Add support for window.showModalDialog in WebKit2GTK+
     4        https://bugs.webkit.org/show_bug.cgi?id=79500
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        Add support for modal dialogs in GTK's MiniBrowser.
     9
     10        * MiniBrowser/gtk/BrowserWindow.c:
     11        (webViewRunAsModal):
     12        (webViewCreate):
     13        (webViewDecidePolicy):
     14        (browser_window_new):
     15        * MiniBrowser/gtk/BrowserWindow.h:
     16        * MiniBrowser/gtk/main.c:
     17        (createBrowserWindow):
     18
    1192012-06-20  Brent Fulgham  <bfulgham@webkit.org>
    220
  • trunk/Tools/MiniBrowser/gtk/BrowserWindow.c

    r119475 r120908  
    234234}
    235235
     236static void webViewRunAsModal(WebKitWebView *webView, BrowserWindow *window)
     237{
     238    gtk_window_set_modal(GTK_WINDOW(window), TRUE);
     239}
     240
    236241static void webViewReadyToShow(WebKitWebView *webView, BrowserWindow *window)
    237242{
     
    261266    webkit_web_view_set_settings(newWebView, webkit_web_view_get_settings(webView));
    262267
    263     GtkWidget *newWindow = browser_window_new(newWebView);
     268    GtkWidget *newWindow = browser_window_new(newWebView, GTK_WINDOW(window));
    264269    g_signal_connect(newWebView, "ready-to-show", G_CALLBACK(webViewReadyToShow), newWindow);
     270    g_signal_connect(newWebView, "run-as-modal", G_CALLBACK(webViewRunAsModal), newWindow);
    265271    g_signal_connect(newWebView, "close", G_CALLBACK(webViewClose), newWindow);
    266272    return GTK_WIDGET(newWebView);
     
    285291    WebKitWebView *newWebView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_context(webkit_web_view_get_context(webView)));
    286292    webkit_web_view_set_settings(newWebView, webkit_web_view_get_settings(webView));
    287     GtkWidget *newWindow = browser_window_new(newWebView);
     293    GtkWidget *newWindow = browser_window_new(newWebView, GTK_WINDOW(window));
    288294    webkit_web_view_load_request(newWebView, webkit_navigation_policy_decision_get_request(navigationDecision));
    289295    gtk_widget_show(newWindow);
     
    517523
    518524// Public API.
    519 GtkWidget *browser_window_new(WebKitWebView *view)
     525GtkWidget *browser_window_new(WebKitWebView *view, GtkWindow *parent)
    520526{
    521527    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(view), 0);
    522528
    523529    return GTK_WIDGET(g_object_new(BROWSER_TYPE_WINDOW,
     530                                   "transient-for", parent,
    524531                                   "type", GTK_WINDOW_TOPLEVEL,
    525532                                   "view", view, NULL));
  • trunk/Tools/MiniBrowser/gtk/BrowserWindow.h

    r111511 r120908  
    4444GType browser_window_get_type(void);
    4545
    46 GtkWidget* browser_window_new(WebKitWebView*);
     46GtkWidget* browser_window_new(WebKitWebView*, GtkWindow*);
    4747WebKitWebView* browser_window_get_view(BrowserWindow*);
    4848void browser_window_load_uri(BrowserWindow *, const char *uri);
  • trunk/Tools/MiniBrowser/gtk/main.c

    r111511 r120908  
    4646{
    4747    GtkWidget *webView = webkit_web_view_new();
    48     GtkWidget *mainWindow = browser_window_new(WEBKIT_WEB_VIEW(webView));
     48    GtkWidget *mainWindow = browser_window_new(WEBKIT_WEB_VIEW(webView), NULL);
    4949    gchar *url = argumentToURL(uri);
    5050
Note: See TracChangeset for help on using the changeset viewer.