Changeset 235969 in webkit


Ignore:
Timestamp:
Sep 13, 2018 1:24:17 AM (6 years ago)
Author:
Carlos Garcia Campos
Message:

[GTK][WPE] Allow to run script dialogs asynchronously in the UI process
https://bugs.webkit.org/show_bug.cgi?id=189544

Reviewed by Michael Catanzaro.

Source/WebKit:

Script dialogs are sync in the WebProcess, but we don't need to block the UI process while they are running. Our
current API doesn't allow it, because it always expects the dialog to be closed in the signal handler. API
changes are backwards compatible.

  • UIProcess/API/glib/WebKitScriptDialog.cpp:

(webkitScriptDialogCreate): Added to heap allocate a WebKitScriptDialog.
(webkitScriptDialogIsRunning): Common implementation here, a script dialog is considered to be running if it has
a competion handler pending.
(webkit_script_dialog_ref): WebKitScriptDialog is now refcounted.
(webkit_script_dialog_unref): Ditto.
(webkit_script_dialog_close): New method to notify that we are done with the dialog.

  • UIProcess/API/glib/WebKitScriptDialogPrivate.h:

(_WebKitScriptDialog::_WebKitScriptDialog): Use a single constructor and keep the completion handler.

  • UIProcess/API/glib/WebKitUIClient.cpp: Do not call the completion handler, pass it to the web view.
  • UIProcess/API/glib/WebKitWebView.cpp:

(webkitWebViewDispose): Close the current script dialog if there's any.
(webkit_web_view_class_init): Document how to handle dialogs asynchronously.
(webkitWebViewRunJavaScriptAlert): Do not stack allocate the WebKitScriptDialog, create it with
webkitScriptDialogCreate() passing the completion handler.
(webkitWebViewRunJavaScriptConfirm): Ditto.
(webkitWebViewRunJavaScriptPrompt): Ditto.
(webkitWebViewRunJavaScriptBeforeUnloadConfirm): Ditto.

  • UIProcess/API/glib/WebKitWebViewPrivate.h:
  • UIProcess/API/gtk/WebKitScriptDialog.h:
  • UIProcess/API/gtk/WebKitScriptDialogGtk.cpp:

(scriptDialogResponseCallback): Hnadle the response callback.
(webkitScriptDialogRun): Do not use gtk_dialog_run(), connect to response signal and show the dialogs instead.

  • UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
  • UIProcess/API/gtk/docs/webkit2gtk-docs.sgml:
  • UIProcess/API/wpe/WebKitScriptDialogWPE.cpp:

Tools:

Add test cases for the new API.

  • TestWebKitAPI/Tests/WebKitGLib/TestUIClient.cpp:

(testWebViewJavaScriptDialogs):

Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r235961 r235969  
     12018-09-13  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][WPE] Allow to run script dialogs asynchronously in the UI process
     4        https://bugs.webkit.org/show_bug.cgi?id=189544
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Script dialogs are sync in the WebProcess, but we don't need to block the UI process while they are running. Our
     9        current API doesn't allow it, because it always expects the dialog to be closed in the signal handler. API
     10        changes are backwards compatible.
     11
     12        * UIProcess/API/glib/WebKitScriptDialog.cpp:
     13        (webkitScriptDialogCreate): Added to heap allocate a WebKitScriptDialog.
     14        (webkitScriptDialogIsRunning): Common implementation here, a script dialog is considered to be running if it has
     15        a competion handler pending.
     16        (webkit_script_dialog_ref): WebKitScriptDialog is now refcounted.
     17        (webkit_script_dialog_unref): Ditto.
     18        (webkit_script_dialog_close): New method to notify that we are done with the dialog.
     19        * UIProcess/API/glib/WebKitScriptDialogPrivate.h:
     20        (_WebKitScriptDialog::_WebKitScriptDialog): Use a single constructor and keep the completion handler.
     21        * UIProcess/API/glib/WebKitUIClient.cpp: Do not call the completion handler, pass it to the web view.
     22        * UIProcess/API/glib/WebKitWebView.cpp:
     23        (webkitWebViewDispose): Close the current script dialog if there's any.
     24        (webkit_web_view_class_init): Document how to handle dialogs asynchronously.
     25        (webkitWebViewRunJavaScriptAlert): Do not stack allocate the WebKitScriptDialog, create it with
     26        webkitScriptDialogCreate() passing the completion handler.
     27        (webkitWebViewRunJavaScriptConfirm): Ditto.
     28        (webkitWebViewRunJavaScriptPrompt): Ditto.
     29        (webkitWebViewRunJavaScriptBeforeUnloadConfirm): Ditto.
     30        * UIProcess/API/glib/WebKitWebViewPrivate.h:
     31        * UIProcess/API/gtk/WebKitScriptDialog.h:
     32        * UIProcess/API/gtk/WebKitScriptDialogGtk.cpp:
     33        (scriptDialogResponseCallback): Hnadle the response callback.
     34        (webkitScriptDialogRun): Do not use gtk_dialog_run(), connect to response signal and show the dialogs instead.
     35        * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
     36        * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml:
     37        * UIProcess/API/wpe/WebKitScriptDialogWPE.cpp:
     38
    1392018-09-12  Dan Bernstein  <mitz@apple.com>
    240
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitScriptDialog.cpp

    r218487 r235969  
    2323#include "WebKitScriptDialogPrivate.h"
    2424
    25 static WebKitScriptDialog* webkitScriptDialogCopy(WebKitScriptDialog* dialog)
     25G_DEFINE_BOXED_TYPE(WebKitScriptDialog, webkit_script_dialog, webkit_script_dialog_ref, webkit_script_dialog_unref)
     26
     27WebKitScriptDialog* webkitScriptDialogCreate(unsigned type, const CString& message, const CString& defaultText, Function<void(bool, const String&)>&& completionHandler)
    2628{
    27     WebKitScriptDialog* copy = static_cast<WebKitScriptDialog*>(fastZeroedMalloc(sizeof(WebKitScriptDialog)));
    28     new (copy) WebKitScriptDialog(dialog);
    29     return copy;
     29    auto* dialog = static_cast<WebKitScriptDialog*>(fastMalloc(sizeof(WebKitScriptDialog)));
     30    new (dialog) WebKitScriptDialog(type, message, defaultText, WTFMove(completionHandler));
     31    return dialog;
    3032}
    3133
    32 static void webkitScriptDialogFree(WebKitScriptDialog* dialog)
     34bool webkitScriptDialogIsRunning(WebKitScriptDialog* scriptDialog)
    3335{
    34     dialog->~WebKitScriptDialog();
    35     fastFree(dialog);
     36    return !!scriptDialog->completionHandler;
    3637}
    3738
    38 G_DEFINE_BOXED_TYPE(WebKitScriptDialog, webkit_script_dialog, webkitScriptDialogCopy, webkitScriptDialogFree)
     39/**
     40 * webkit_script_dialog_ref:
     41 * @dialog: a #WebKitScriptDialog
     42 *
     43 * Atomically increments the reference count of @dialog by one. This
     44 * function is MT-safe and may be called from any thread.
     45 *
     46 * Returns: The passed in #WebKitScriptDialog
     47 *
     48 * Since: 2.24
     49 */
     50WebKitScriptDialog* webkit_script_dialog_ref(WebKitScriptDialog* dialog)
     51{
     52    g_atomic_int_inc(&dialog->referenceCount);
     53    return dialog;
     54}
     55
     56/**
     57 * webkit_script_dialog_unref:
     58 * @dialog: a #WebKitScriptDialog
     59 *
     60 * Atomically decrements the reference count of @dialog by one. If the
     61 * reference count drops to 0, all memory allocated by the #WebKitScriptdialog is
     62 * released. This function is MT-safe and may be called from any
     63 * thread.
     64 *
     65 * Since: 2.24
     66 */
     67void webkit_script_dialog_unref(WebKitScriptDialog* dialog)
     68{
     69    if (g_atomic_int_dec_and_test(&dialog->referenceCount)) {
     70        webkit_script_dialog_close(dialog);
     71        dialog->~WebKitScriptDialog();
     72        fastFree(dialog);
     73    }
     74}
    3975
    4076/**
     
    125161    dialog->text = text;
    126162}
     163
     164/**
     165 * webkit_script_dialog_close:
     166 * @dialog: a #WebKitScriptDialog
     167 *
     168 * Close @dialog. When handling a #WebKitScriptDialog asynchronously (webkit_script_dialog_ref()
     169 * was called in #WebKitWebView::script-dialog callback), this function needs to be called to notify
     170 * that we are done with the script dialog. The dialog will be closed on destruction if this function
     171 * hasn't been called before.
     172 *
     173 * Since: 2.24
     174 */
     175void webkit_script_dialog_close(WebKitScriptDialog* dialog)
     176{
     177    g_return_if_fail(dialog);
     178
     179    if (!dialog->completionHandler)
     180        return;
     181
     182    auto completionHandler = std::exchange(dialog->completionHandler, nullptr);
     183
     184    switch (dialog->type) {
     185    case WEBKIT_SCRIPT_DIALOG_ALERT:
     186        completionHandler(false, emptyString());
     187        break;
     188    case WEBKIT_SCRIPT_DIALOG_CONFIRM:
     189    case WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM:
     190        completionHandler(dialog->confirmed, emptyString());
     191        break;
     192    case WEBKIT_SCRIPT_DIALOG_PROMPT:
     193        completionHandler(false, String::fromUTF8(dialog->text.data()));
     194        break;
     195    }
     196}
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitScriptDialogPrivate.h

    r220387 r235969  
    2626
    2727struct _WebKitScriptDialog {
    28     _WebKitScriptDialog(unsigned type, const CString& message)
    29         : type(type)
    30         , message(message)
    31         , confirmed(false)
    32     {
    33     }
    34 
    35     _WebKitScriptDialog(unsigned type, const CString& message, const CString& defaultText)
     28    _WebKitScriptDialog(unsigned type, const CString& message, const CString& defaultText, Function<void(bool, const String&)>&& completionHandler)
    3629        : type(type)
    3730        , message(message)
    3831        , defaultText(defaultText)
    39         , confirmed(false)
    40     {
    41         ASSERT(type == WEBKIT_SCRIPT_DIALOG_PROMPT);
    42     }
    43 
    44     _WebKitScriptDialog(WebKitScriptDialog* dialog)
    45         : type(dialog->type)
    46         , message(dialog->message)
    47         , defaultText(dialog->defaultText)
    48         , confirmed(dialog->confirmed)
    49         , text(dialog->text)
     32        , completionHandler(WTFMove(completionHandler))
    5033    {
    5134    }
     
    5538    CString defaultText;
    5639
    57     bool confirmed;
     40    bool confirmed { false };
    5841    CString text;
     42
     43    Function<void(bool, const String&)> completionHandler;
    5944
    6045#if PLATFORM(GTK)
    6146    GtkWidget* nativeDialog { nullptr };
    6247#endif
     48
     49    int referenceCount { 1 };
    6350};
    6451
     52WebKitScriptDialog* webkitScriptDialogCreate(unsigned type, const CString& message, const CString& defaultText, Function<void(bool, const String&)>&& completionHandler);
    6553void webkitScriptDialogRun(WebKitScriptDialog*, WebKitWebView*);
    6654bool webkitScriptDialogIsRunning(WebKitScriptDialog*);
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp

    r234543 r235969  
    6868    void runJavaScriptAlert(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void()>&& completionHandler) final
    6969    {
    70         webkitWebViewRunJavaScriptAlert(m_webView, message.utf8());
    71         completionHandler();
     70        webkitWebViewRunJavaScriptAlert(m_webView, message.utf8(), WTFMove(completionHandler));
    7271    }
    7372
    7473    void runJavaScriptConfirm(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void(bool)>&& completionHandler) final
    7574    {
    76         completionHandler(webkitWebViewRunJavaScriptConfirm(m_webView, message.utf8()));
     75        webkitWebViewRunJavaScriptConfirm(m_webView, message.utf8(), WTFMove(completionHandler));
    7776    }
    7877
    7978    void runJavaScriptPrompt(WebPageProxy*, const String& message, const String& defaultValue, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void(const String&)>&& completionHandler) final
    8079    {
    81         CString result = webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8());
    82         if (result.isNull()) {
    83             completionHandler(String());
    84             return;
    85         }
    86 
    87         completionHandler(String::fromUTF8(result.data()));
     80        webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8(), WTFMove(completionHandler));
    8881    }
    8982
     
    9285    void runBeforeUnloadConfirmPanel(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void(bool)>&& completionHandler) final
    9386    {
    94         completionHandler(webkitWebViewRunJavaScriptBeforeUnloadConfirm(m_webView, message.utf8()));
     87        webkitWebViewRunJavaScriptBeforeUnloadConfirm(m_webView, message.utf8(), WTFMove(completionHandler));
    9588    }
    9689
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp

    r235935 r235969  
    7272#include <WebCore/URL.h>
    7373#include <glib/gi18n-lib.h>
    74 #include <wtf/SetForScope.h>
    7574#include <wtf/glib/GRefPtr.h>
    7675#include <wtf/glib/WTFGType.h>
     
    806805        webkitWebsiteDataManagerRemoveProcessPool(webView->priv->websiteDataManager.get(), webkitWebContextGetProcessPool(webView->priv->context.get()));
    807806        webView->priv->websiteDataManager = nullptr;
     807    }
     808
     809    if (webView->priv->currentScriptDialog) {
     810        webkit_script_dialog_close(webView->priv->currentScriptDialog);
     811        ASSERT(!webView->priv->currentScriptDialog);
    808812    }
    809813
     
    13561360     * </itemizedlist>
    13571361     *
     1362     * It is possible to handle the script dialog request asynchronously, by simply
     1363     * caling webkit_script_dialog_ref() on the @dialog argument and calling
     1364     * webkit_script_dialog_close() when done.
     1365     * If the last reference is removed on a #WebKitScriptDialog and the dialog has not been
     1366     * closed, webkit_script_dialog_close() will be called.
     1367     *
    13581368     * Returns: %TRUE to stop other handlers from being invoked for the event.
    13591369     *    %FALSE to propagate the event further.
     
    13671377        g_cclosure_marshal_generic,
    13681378        G_TYPE_BOOLEAN, 1,
    1369         WEBKIT_TYPE_SCRIPT_DIALOG | G_SIGNAL_TYPE_STATIC_SCOPE);
     1379        WEBKIT_TYPE_SCRIPT_DIALOG);
    13701380
    13711381    /**
     
    21022112}
    21032113
    2104 void webkitWebViewRunJavaScriptAlert(WebKitWebView* webView, const CString& message)
    2105 {
    2106     WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_ALERT, message);
    2107     SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
     2114void webkitWebViewRunJavaScriptAlert(WebKitWebView* webView, const CString& message, Function<void()>&& completionHandler)
     2115{
     2116    ASSERT(!webView->priv->currentScriptDialog);
     2117    webView->priv->currentScriptDialog = webkitScriptDialogCreate(WEBKIT_SCRIPT_DIALOG_ALERT, message, { }, [webView, completionHandler = WTFMove(completionHandler)](bool, const String&) {
     2118        completionHandler();
     2119        webView->priv->currentScriptDialog = nullptr;
     2120    });
    21082121    gboolean returnValue;
    2109     g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
    2110 }
    2111 
    2112 bool webkitWebViewRunJavaScriptConfirm(WebKitWebView* webView, const CString& message)
    2113 {
    2114     WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_CONFIRM, message);
    2115     SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
     2122    g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, webView->priv->currentScriptDialog, &returnValue);
     2123    webkit_script_dialog_unref(webView->priv->currentScriptDialog);
     2124}
     2125
     2126void webkitWebViewRunJavaScriptConfirm(WebKitWebView* webView, const CString& message, Function<void(bool)>&& completionHandler)
     2127{
     2128    ASSERT(!webView->priv->currentScriptDialog);
     2129    webView->priv->currentScriptDialog = webkitScriptDialogCreate(WEBKIT_SCRIPT_DIALOG_CONFIRM, message, { }, [webView, completionHandler = WTFMove(completionHandler)](bool result, const String&) {
     2130        completionHandler(result);
     2131        webView->priv->currentScriptDialog = nullptr;
     2132    });
    21162133    gboolean returnValue;
    2117     g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
    2118     return dialog.confirmed;
    2119 }
    2120 
    2121 CString webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& message, const CString& defaultText)
    2122 {
    2123     WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_PROMPT, message, defaultText);
    2124     SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
     2134    g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, webView->priv->currentScriptDialog, &returnValue);
     2135    webkit_script_dialog_unref(webView->priv->currentScriptDialog);
     2136}
     2137
     2138void webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& message, const CString& defaultText, Function<void(const String&)>&& completionHandler)
     2139{
     2140    ASSERT(!webView->priv->currentScriptDialog);
     2141    webView->priv->currentScriptDialog = webkitScriptDialogCreate(WEBKIT_SCRIPT_DIALOG_PROMPT, message, defaultText, [webView, completionHandler = WTFMove(completionHandler)](bool, const String& result) {
     2142        completionHandler(result);
     2143        webView->priv->currentScriptDialog = nullptr;
     2144    });
    21252145    gboolean returnValue;
    2126     g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
    2127     return dialog.text;
    2128 }
    2129 
    2130 bool webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const CString& message)
    2131 {
    2132     WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM, message);
    2133     SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
     2146    g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, webView->priv->currentScriptDialog, &returnValue);
     2147    webkit_script_dialog_unref(webView->priv->currentScriptDialog);
     2148}
     2149
     2150void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const CString& message, Function<void(bool)>&& completionHandler)
     2151{
     2152    ASSERT(!webView->priv->currentScriptDialog);
     2153    webView->priv->currentScriptDialog = webkitScriptDialogCreate(WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM, message, { }, [webView, completionHandler = WTFMove(completionHandler)](bool result, const String&) {
     2154        completionHandler(result);
     2155        webView->priv->currentScriptDialog = nullptr;
     2156    });
    21342157    gboolean returnValue;
    2135     g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
    2136     return dialog.confirmed;
     2158    g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, webView->priv->currentScriptDialog, &returnValue);
     2159    webkit_script_dialog_unref(webView->priv->currentScriptDialog);
    21372160}
    21382161
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h

    r232150 r235969  
    5353void webkitWebViewRunAsModal(WebKitWebView*);
    5454void webkitWebViewClosePage(WebKitWebView*);
    55 void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message);
    56 bool webkitWebViewRunJavaScriptConfirm(WebKitWebView*, const CString& message);
    57 CString webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText);
    58 bool webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView*, const CString& message);
     55void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message, Function<void()>&& completionHandler);
     56void webkitWebViewRunJavaScriptConfirm(WebKitWebView*, const CString& message, Function<void(bool)>&& completionHandler);
     57void webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText, Function<void(const String&)>&& completionHandler);
     58void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView*, const CString& message, Function<void(bool)>&& completionHandler);
    5959bool webkitWebViewIsShowingScriptDialog(WebKitWebView*);
    6060bool webkitWebViewIsScriptDialogRunning(WebKitWebView*, WebKitScriptDialog*);
  • trunk/Source/WebKit/UIProcess/API/gtk/WebKitScriptDialog.h

    r193826 r235969  
    5757webkit_script_dialog_get_type                (void);
    5858
     59WEBKIT_API WebKitScriptDialog *
     60webkit_script_dialog_ref                     (WebKitScriptDialog *dialog);
     61
     62WEBKIT_API void
     63webkit_script_dialog_unref                   (WebKitScriptDialog *dialog);
     64
    5965WEBKIT_API WebKitScriptDialogType
    6066webkit_script_dialog_get_dialog_type         (WebKitScriptDialog *dialog);
     
    7480                                              const gchar        *text);
    7581
     82WEBKIT_API void
     83webkit_script_dialog_close                   (WebKitScriptDialog *dialog);
     84
    7685G_END_DECLS
    7786
  • trunk/Source/WebKit/UIProcess/API/gtk/WebKitScriptDialogGtk.cpp

    r220387 r235969  
    2828#include <wtf/glib/GUniquePtr.h>
    2929
     30static void scriptDialogResponseCallback(GtkWidget* dialog, int responseID, WebKitScriptDialog* scriptDialog)
     31{
     32    switch (scriptDialog->type) {
     33    case WEBKIT_SCRIPT_DIALOG_ALERT:
     34        break;
     35    case WEBKIT_SCRIPT_DIALOG_CONFIRM:
     36    case WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM:
     37        scriptDialog->confirmed = responseID == GTK_RESPONSE_OK;
     38        break;
     39    case WEBKIT_SCRIPT_DIALOG_PROMPT:
     40        if (responseID == GTK_RESPONSE_OK) {
     41            if (auto* entry = g_object_get_data(G_OBJECT(dialog), "wk-script-dialog-entry"))
     42                scriptDialog->text = gtk_entry_get_text(GTK_ENTRY(entry));
     43        }
     44        break;
     45    }
     46
     47    scriptDialog->nativeDialog = nullptr;
     48    webkit_script_dialog_close(scriptDialog);
     49    webkit_script_dialog_unref(scriptDialog);
     50    gtk_widget_destroy(dialog);
     51}
     52
    3053static GtkWidget* webkitWebViewCreateJavaScriptDialog(WebKitWebView* webView, GtkMessageType type, GtkButtonsType buttons, int defaultResponse, const char* primaryText, const char* secondaryText = nullptr)
    3154{
     
    5073    case WEBKIT_SCRIPT_DIALOG_ALERT:
    5174        dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_CLOSE, scriptDialog->message.data());
    52         scriptDialog->nativeDialog = dialog;
    53         gtk_dialog_run(GTK_DIALOG(dialog));
    5475        break;
    5576    case WEBKIT_SCRIPT_DIALOG_CONFIRM:
    5677        dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data());
    57         scriptDialog->nativeDialog = dialog;
    58         scriptDialog->confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK;
    5978        break;
    6079    case WEBKIT_SCRIPT_DIALOG_PROMPT: {
    6180        dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data());
    62         scriptDialog->nativeDialog = dialog;
    6381        GtkWidget* entry = gtk_entry_new();
     82        g_object_set_data(G_OBJECT(dialog), "wk-script-dialog-entry", entry);
    6483        gtk_entry_set_text(GTK_ENTRY(entry), scriptDialog->defaultText.data());
    6584        gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry);
    6685        gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
    6786        gtk_widget_show(entry);
    68         if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
    69             scriptDialog->text = gtk_entry_get_text(GTK_ENTRY(entry));
    7087        break;
    7188    }
     
    7390        dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, GTK_RESPONSE_OK,
    7491            _("Are you sure you want to leave this page?"), scriptDialog->message.data());
    75         scriptDialog->nativeDialog = dialog;
    7692        gtk_dialog_add_buttons(GTK_DIALOG(dialog), _("Stay on Page"), GTK_RESPONSE_CLOSE, _("Leave Page"), GTK_RESPONSE_OK, nullptr);
    7793        gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
    78         scriptDialog->confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK;
    7994        break;
    8095    }
    8196
    82     gtk_widget_destroy(dialog);
    83     scriptDialog->nativeDialog = nullptr;
    84 }
    85 
    86 bool webkitScriptDialogIsRunning(WebKitScriptDialog* scriptDialog)
    87 {
    88     return !!scriptDialog->nativeDialog;
     97    ASSERT(dialog);
     98    scriptDialog->nativeDialog = dialog;
     99    g_signal_connect(dialog, "response", G_CALLBACK(scriptDialogResponseCallback), webkit_script_dialog_ref(scriptDialog));
     100    gtk_widget_show(dialog);
    89101}
    90102
  • trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt

    r235282 r235969  
    232232webkit_web_view_get_session_state
    233233webkit_web_view_restore_session_state
     234webkit_web_view_get_main_resource
    234235
    235236<SUBSECTION WebKitJavascriptResult>
     
    244245WebKitScriptDialog
    245246WebKitScriptDialogType
     247webkit_script_dialog_ref
     248webkit_script_dialog_unref
    246249webkit_script_dialog_get_dialog_type
    247250webkit_script_dialog_get_message
     
    249252webkit_script_dialog_prompt_get_default_text
    250253webkit_script_dialog_prompt_set_text
    251 webkit_web_view_get_main_resource
     254webkit_script_dialog_close
    252255
    253256<SUBSECTION WebKitWebViewSessionState>
  • trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml

    r229973 r235969  
    138138  </index>
    139139
     140  <index id="api-index-2-24" role="2.24">
     141    <title>Index of new symbols in 2.24</title>
     142    <xi:include href="xml/api-index-2.24.xml"><xi:fallback /></xi:include>
     143  </index>
     144
    140145  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
    141146</book>
  • trunk/Source/WebKit/UIProcess/API/wpe/WebKitScriptDialog.h

    r218553 r235969  
    5757webkit_script_dialog_get_type                (void);
    5858
     59WEBKIT_API WebKitScriptDialog *
     60webkit_script_dialog_ref                     (WebKitScriptDialog *dialog);
     61
     62WEBKIT_API void
     63webkit_script_dialog_unref                   (WebKitScriptDialog *dialog);
     64
    5965WEBKIT_API WebKitScriptDialogType
    6066webkit_script_dialog_get_dialog_type         (WebKitScriptDialog *dialog);
     
    7480                                              const gchar        *text);
    7581
     82WEBKIT_API void
     83webkit_script_dialog_close                   (WebKitScriptDialog *dialog);
     84
    7685G_END_DECLS
    7786
  • trunk/Source/WebKit/UIProcess/API/wpe/WebKitScriptDialogWPE.cpp

    r220387 r235969  
    2727}
    2828
    29 bool webkitScriptDialogIsRunning(WebKitScriptDialog*)
    30 {
    31     return false;
    32 }
    33 
    3429void webkitScriptDialogAccept(WebKitScriptDialog*)
    3530{
  • trunk/Tools/ChangeLog

    r235965 r235969  
     12018-09-13  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][WPE] Allow to run script dialogs asynchronously in the UI process
     4        https://bugs.webkit.org/show_bug.cgi?id=189544
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Add test cases for the new API.
     9
     10        * TestWebKitAPI/Tests/WebKitGLib/TestUIClient.cpp:
     11        (testWebViewJavaScriptDialogs):
     12
    1132018-09-12  Fujii Hironori  <Hironori.Fujii@sony.com>
    214
  • trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestUIClient.cpp

    r225044 r235969  
    2121#include "WebViewTest.h"
    2222#include <wtf/HashSet.h>
     23#include <wtf/RunLoop.h>
    2324#include <wtf/glib/GRefPtr.h>
    2425#include <wtf/text/StringHash.h>
     
    159160        }
    160161
    161         g_main_loop_quit(m_mainLoop);
     162        if (m_delayedScriptDialogs) {
     163            webkit_script_dialog_ref(dialog);
     164            RunLoop::main().dispatch([this, dialog] {
     165                webkit_script_dialog_close(dialog);
     166                webkit_script_dialog_unref(dialog);
     167                g_main_loop_quit(m_mainLoop);
     168            });
     169        } else
     170            g_main_loop_quit(m_mainLoop);
    162171    }
    163172
     
    366375    WebKitScriptDialogType m_scriptDialogType;
    367376    bool m_scriptDialogConfirmed;
     377    bool m_delayedScriptDialogs { false };
    368378    bool m_allowPermissionRequests;
    369379    gboolean m_verifyMediaTypes;
     
    559569#endif
    560570
    561     test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_ALERT;
    562     GUniquePtr<char> alertDialogMessage(g_strdup_printf(jsAlertFormat, kAlertDialogMessage));
    563     GUniquePtr<char> alertHTML(g_strdup_printf(htmlOnLoadFormat, alertDialogMessage.get()));
    564     test->loadHtml(alertHTML.get(), 0);
    565     test->waitUntilMainLoopFinishes();
    566     webkit_web_view_stop_loading(test->m_webView);
    567     test->waitUntilLoadFinished();
    568 
    569     test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_CONFIRM;
    570     GUniquePtr<char> confirmDialogMessage(g_strdup_printf(jsConfirmFormat, kConfirmDialogMessage));
    571     GUniquePtr<char> confirmHTML(g_strdup_printf(htmlOnLoadFormat, confirmDialogMessage.get()));
    572     test->loadHtml(confirmHTML.get(), 0);
    573     test->waitUntilMainLoopFinishes();
    574     webkit_web_view_stop_loading(test->m_webView);
    575     test->waitUntilLoadFinished();
    576 
    577     test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_PROMPT;
    578     GUniquePtr<char> promptDialogMessage(g_strdup_printf(jsPromptFormat, kPromptDialogMessage));
    579     GUniquePtr<char> promptHTML(g_strdup_printf(htmlOnLoadFormat, promptDialogMessage.get()));
    580     test->loadHtml(promptHTML.get(), 0);
    581     test->waitUntilMainLoopFinishes();
    582     webkit_web_view_stop_loading(test->m_webView);
    583     test->waitUntilLoadFinished();
     571    for (unsigned i = 0; i <= 1; ++i) {
     572        test->m_delayedScriptDialogs = !!i;
     573
     574        test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_ALERT;
     575        GUniquePtr<char> alertDialogMessage(g_strdup_printf(jsAlertFormat, kAlertDialogMessage));
     576        GUniquePtr<char> alertHTML(g_strdup_printf(htmlOnLoadFormat, alertDialogMessage.get()));
     577        test->loadHtml(alertHTML.get(), nullptr);
     578        test->waitUntilMainLoopFinishes();
     579        webkit_web_view_stop_loading(test->m_webView);
     580        test->waitUntilLoadFinished();
     581
     582        test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_CONFIRM;
     583        GUniquePtr<char> confirmDialogMessage(g_strdup_printf(jsConfirmFormat, kConfirmDialogMessage));
     584        GUniquePtr<char> confirmHTML(g_strdup_printf(htmlOnLoadFormat, confirmDialogMessage.get()));
     585        test->loadHtml(confirmHTML.get(), nullptr);
     586        test->waitUntilMainLoopFinishes();
     587        webkit_web_view_stop_loading(test->m_webView);
     588        test->waitUntilLoadFinished();
     589
     590        test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_PROMPT;
     591        GUniquePtr<char> promptDialogMessage(g_strdup_printf(jsPromptFormat, kPromptDialogMessage));
     592        GUniquePtr<char> promptHTML(g_strdup_printf(htmlOnLoadFormat, promptDialogMessage.get()));
     593        test->loadHtml(promptHTML.get(), nullptr);
     594        test->waitUntilMainLoopFinishes();
     595        webkit_web_view_stop_loading(test->m_webView);
     596        test->waitUntilLoadFinished();
     597    }
     598
     599    test->m_delayedScriptDialogs = false;
    584600
    585601    // FIXME: implement simulateUserInteraction in WPE.
Note: See TracChangeset for help on using the changeset viewer.