Title: [175414] trunk
Revision
175414
Author
[email protected]
Date
2014-10-31 12:04:19 -0700 (Fri, 31 Oct 2014)

Log Message

[GTK] Support script message handlers WebKitUserContentManager
https://bugs.webkit.org/show_bug.cgi?id=133730

Patch by Adrian Perez de Castro <[email protected]> on 2014-10-31
Reviewed by Carlos Garcia Campos.

Support user script message handlers in WebKitUserContentManager.
This needs building with ENABLE_USER_MESSAGE_HANDLERS, for which
an option is added to the CMake build files. The option is disabled
globally by default, and the WebKitGTK port enables it. On the API
level, two new methods to register and unregister names are provided
in the "window.webkit" namespace, and on message reception the
"WebKitUserContentManager::script-message-received" signal is
emitted, using the registered names as signal detail.

.:

* Source/cmake/OptionsGTK.cmake: For the GTK port, enable the
ENABLE_USER_MESSAGE_HANDLERS feature by default.
* Source/cmake/WebKitFeatures.cmake: Add feature description for
ENABLE_USER_MESSAGE_HANDLERS, disabled by default.

Source/WebCore:

* CMakeLists.txt: Conditionally add the needed files to the build
when the ENABLE_USER_MESSAGE_HANDLERS feature is enabled.

Source/WebKit2:

* UIProcess/API/gtk/WebKitJavascriptResult.cpp: Add a new private
function to construct a WebKitJavascriptResult directly from a
WebCore::SerializedScriptValue.
(_WebKitJavascriptResult::_WebKitJavascriptResult): Ditto.
(webkitJavascriptResultCreate): Ditto.
* UIProcess/API/gtk/WebKitJavascriptResultPrivate.h: Ditto.
* UIProcess/API/gtk/WebKitUserContentManager.cpp:
(webkit_user_content_manager_class_init): Install the
"script-message-received" signal.
(webkit_user_content_manager_register_script_message_handler):
Added.
(webkit_user_content_manager_unregister_script_message_handler):
Added.
* UIProcess/API/gtk/WebKitUserContentManager.h: Added the new
public API methods.
* UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Ditto.
* UIProcess/API/gtk/docs/webkit2gtk.types: Add
webkit_user_content_manager_get_type() to the list in order to make
gtk-doc to generate documentation for signals.

Tools:

* TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitUserContentManager.cpp:
Add test case for user script message handlers.
(scriptMessageReceived):
(testUserContentManagerScriptMessageReceived):
(beforeAll):

Modified Paths

Diff

Modified: trunk/ChangeLog (175413 => 175414)


--- trunk/ChangeLog	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/ChangeLog	2014-10-31 19:04:19 UTC (rev 175414)
@@ -1,3 +1,24 @@
+2014-10-31  Adrian Perez de Castro  <[email protected]>
+
+        [GTK] Support script message handlers WebKitUserContentManager
+        https://bugs.webkit.org/show_bug.cgi?id=133730
+
+        Reviewed by Carlos Garcia Campos.
+
+        Support user script message handlers in WebKitUserContentManager.
+        This needs building with ENABLE_USER_MESSAGE_HANDLERS, for which
+        an option is added to the CMake build files. The option is disabled
+        globally by default, and the WebKitGTK port enables it. On the API
+        level, two new methods to register and unregister names are provided
+        in the "window.webkit" namespace, and on message reception the
+        "WebKitUserContentManager::script-message-received" signal is
+        emitted, using the registered names as signal detail.
+
+        * Source/cmake/OptionsGTK.cmake: For the GTK port, enable the
+        ENABLE_USER_MESSAGE_HANDLERS feature by default.
+        * Source/cmake/WebKitFeatures.cmake: Add feature description for
+        ENABLE_USER_MESSAGE_HANDLERS, disabled by default.
+
 2014-10-29  Raphael Kubo da Costa  <[email protected]>
 
         [GTK] Bump libsoup's minimum version to 2.42.0.

Modified: trunk/Source/WebCore/CMakeLists.txt (175413 => 175414)


--- trunk/Source/WebCore/CMakeLists.txt	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebCore/CMakeLists.txt	2014-10-31 19:04:19 UTC (rev 175414)
@@ -3107,6 +3107,21 @@
     )
 endif ()
 
+if (ENABLE_USER_MESSAGE_HANDLERS)
+    list(APPEND WebCore_IDL_FILES
+        page/UserMessageHandler.idl
+        page/UserMessageHandlersNamespace.idl
+        page/WebKitNamespace.idl
+    )
+    list(APPEND WebCore_SOURCES
+        bindings/js/JSUserMessageHandlersNamespaceCustom.cpp
+        page/UserMessageHandler.cpp
+        page/UserMessageHandlerDescriptor.cpp
+        page/UserMessageHandlersNamespace.cpp
+        page/WebKitNamespace.cpp
+    )
+endif ()
+
 set(WebCoreTestSupport_INCLUDE_DIRECTORIES
     "${WEBCORE_DIR}/platform/mock"
     "${WEBCORE_DIR}/testing"

Modified: trunk/Source/WebCore/ChangeLog (175413 => 175414)


--- trunk/Source/WebCore/ChangeLog	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebCore/ChangeLog	2014-10-31 19:04:19 UTC (rev 175414)
@@ -1,3 +1,22 @@
+2014-10-31  Adrian Perez de Castro  <[email protected]>
+
+        [GTK] Support script message handlers WebKitUserContentManager
+        https://bugs.webkit.org/show_bug.cgi?id=133730
+
+        Reviewed by Carlos Garcia Campos.
+
+        Support user script message handlers in WebKitUserContentManager.
+        This needs building with ENABLE_USER_MESSAGE_HANDLERS, for which
+        an option is added to the CMake build files. The option is disabled
+        globally by default, and the WebKitGTK port enables it. On the API
+        level, two new methods to register and unregister names are provided
+        in the "window.webkit" namespace, and on message reception the
+        "WebKitUserContentManager::script-message-received" signal is
+        emitted, using the registered names as signal detail.
+
+        * CMakeLists.txt: Conditionally add the needed files to the build
+        when the ENABLE_USER_MESSAGE_HANDLERS feature is enabled.
+
 2014-10-31  Andrzej Badowski  <[email protected]>
 
         [ATK] Improve AccessibilityTableCell's determineAccessibilityRole function.

Modified: trunk/Source/WebKit2/ChangeLog (175413 => 175414)


--- trunk/Source/WebKit2/ChangeLog	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebKit2/ChangeLog	2014-10-31 19:04:19 UTC (rev 175414)
@@ -1,3 +1,39 @@
+2014-10-31  Adrian Perez de Castro  <[email protected]>
+
+        [GTK] Support script message handlers WebKitUserContentManager
+        https://bugs.webkit.org/show_bug.cgi?id=133730
+
+        Reviewed by Carlos Garcia Campos.
+
+        Support user script message handlers in WebKitUserContentManager.
+        This needs building with ENABLE_USER_MESSAGE_HANDLERS, for which
+        an option is added to the CMake build files. The option is disabled
+        globally by default, and the WebKitGTK port enables it. On the API
+        level, two new methods to register and unregister names are provided
+        in the "window.webkit" namespace, and on message reception the
+        "WebKitUserContentManager::script-message-received" signal is
+        emitted, using the registered names as signal detail.
+
+        * UIProcess/API/gtk/WebKitJavascriptResult.cpp: Add a new private
+        function to construct a WebKitJavascriptResult directly from a
+        WebCore::SerializedScriptValue.
+        (_WebKitJavascriptResult::_WebKitJavascriptResult): Ditto.
+        (webkitJavascriptResultCreate): Ditto.
+        * UIProcess/API/gtk/WebKitJavascriptResultPrivate.h: Ditto.
+        * UIProcess/API/gtk/WebKitUserContentManager.cpp:
+        (webkit_user_content_manager_class_init): Install the
+        "script-message-received" signal.
+        (webkit_user_content_manager_register_script_message_handler):
+        Added.
+        (webkit_user_content_manager_unregister_script_message_handler):
+        Added.
+        * UIProcess/API/gtk/WebKitUserContentManager.h: Added the new
+        public API methods.
+        * UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Ditto.
+        * UIProcess/API/gtk/docs/webkit2gtk.types: Add
+        webkit_user_content_manager_get_type() to the list in order to make
+        gtk-doc to generate documentation for signals.
+
 2014-10-31  Martin Hock  <[email protected]>
 
         Unreviewed, iOS build fix since 175406.

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp (175413 => 175414)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp	2014-10-31 19:04:19 UTC (rev 175414)
@@ -27,11 +27,11 @@
 using namespace WebKit;
 
 struct _WebKitJavascriptResult {
-    _WebKitJavascriptResult(WebKitWebView* view, WebSerializedScriptValue* serializedScriptValue)
+    _WebKitJavascriptResult(WebKitWebView* view, WebCore::SerializedScriptValue& serializedScriptValue)
         : webView(view)
         , referenceCount(1)
     {
-        value = serializedScriptValue->deserialize(webkit_web_view_get_javascript_global_context(view), 0);
+        value = serializedScriptValue.deserialize(webkit_web_view_get_javascript_global_context(view), nullptr);
     }
 
     GRefPtr<WebKitWebView> webView;
@@ -42,7 +42,7 @@
 
 G_DEFINE_BOXED_TYPE(WebKitJavascriptResult, webkit_javascript_result, webkit_javascript_result_ref, webkit_javascript_result_unref)
 
-WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView* webView, WebSerializedScriptValue* serializedScriptValue)
+WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView* webView, WebCore::SerializedScriptValue& serializedScriptValue)
 {
     WebKitJavascriptResult* result = g_slice_new(WebKitJavascriptResult);
     new (result) WebKitJavascriptResult(webView, serializedScriptValue);

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h (175413 => 175414)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h	2014-10-31 19:04:19 UTC (rev 175414)
@@ -20,10 +20,11 @@
 #ifndef WebKitJavascriptResultPrivate_h
 #define WebKitJavascriptResultPrivate_h
 
+#include <WebCore/SerializedScriptValue.h>
 #include "WebKitJavascriptResult.h"
 #include "WebKitPrivate.h"
 #include "WebKitWebView.h"
 
-WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView*, WebKit::WebSerializedScriptValue*);
+WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView*, WebCore::SerializedScriptValue&);
 
 #endif // WebKitJavascriptResultPrivate_h

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp (175413 => 175414)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp	2014-10-31 19:04:19 UTC (rev 175414)
@@ -20,9 +20,13 @@
 #include "config.h"
 #include "WebKitUserContentManager.h"
 
+#include "WebKitJavascriptResultPrivate.h"
 #include "WebKitPrivate.h"
 #include "WebKitUserContentManagerPrivate.h"
 #include "WebKitUserContentPrivate.h"
+#include "WebKitWebContextPrivate.h"
+#include "WebScriptMessageHandler.h"
+#include "WebSerializedScriptValue.h"
 #include <wtf/gobject/GRefPtr.h>
 
 using namespace WebCore;
@@ -59,8 +63,39 @@
 
 WEBKIT_DEFINE_TYPE(WebKitUserContentManager, webkit_user_content_manager, G_TYPE_OBJECT)
 
-static void webkit_user_content_manager_class_init(WebKitUserContentManagerClass*)
+enum {
+    SCRIPT_MESSAGE_RECEIVED,
+
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+static void webkit_user_content_manager_class_init(WebKitUserContentManagerClass* klass)
 {
+    GObjectClass* gObjectClass = G_OBJECT_CLASS(klass);
+
+    /**
+     * WebKitUserContentManager::script-message-received:
+     * @manager: the #WebKitUserContentManager
+     * @js_result: the #WebKitJavascriptResult holding the value received from the _javascript_ world.
+     *
+     * This signal is emitted when _javascript_ in a web view calls
+     * <code>window.webkit.messageHandlers.&lt;name&gt;.postMessage()</code>, after registering
+     * <code>&lt;name&gt;</code> using
+     * webkit_user_content_manager_register_script_message_handler()
+     *
+     * Since: 2.8
+     */
+    signals[SCRIPT_MESSAGE_RECEIVED] =
+        g_signal_new(
+            "script-message-received",
+            G_TYPE_FROM_CLASS(gObjectClass),
+            static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED),
+            0, nullptr, nullptr,
+            g_cclosure_marshal_VOID__BOXED,
+            G_TYPE_NONE, 1,
+            WEBKIT_TYPE_JAVASCRIPT_RESULT);
 }
 
 /**
@@ -141,6 +176,90 @@
     manager->priv->userContentController->removeAllUserScripts();
 }
 
+class ScriptMessageClientGtk final : public WebScriptMessageHandler::Client {
+public:
+    ScriptMessageClientGtk(WebKitUserContentManager* manager, const char* handlerName)
+        : m_handlerName(g_quark_from_string(handlerName))
+        , m_manager(manager)
+    {
+    }
+
+    virtual void didPostMessage(WebPageProxy& page, WebFrameProxy&, WebCore::SerializedScriptValue& serializedScriptValue)
+    {
+        WebKitJavascriptResult* jsResult = webkitJavascriptResultCreate(WEBKIT_WEB_VIEW(page.viewWidget()), serializedScriptValue);
+        g_signal_emit(m_manager, signals[SCRIPT_MESSAGE_RECEIVED], m_handlerName, jsResult);
+        webkit_javascript_result_unref(jsResult);
+    }
+
+    virtual ~ScriptMessageClientGtk() { }
+
+private:
+    GQuark m_handlerName;
+    WebKitUserContentManager* m_manager;
+};
+
+/**
+ * webkit_user_content_manager_register_script_message_handler:
+ * @manager: A #WebKitUserContentManager
+ * @name: Name of the script message channel
+ *
+ * Registers a new user script message handler. After it is registered,
+ * scripts can use `window.webkit.messageHandlers.&lt;name&gt;.postMessage(value)`
+ * to send messages. Those messages are received by connecting handlers
+ * to the #WebKitUserContentManager::script-message-received signal. The
+ * handler name is used as the detail of the signal. To avoid race
+ * conditions between registering the handler name, and starting to
+ * receive the signals, it is recommended to connect to the signal
+ * *before* registering the handler name:
+ *
+ * <informalexample><programlisting>
+ * WebKitWebView *view = webkit_web_view_new ();
+ * WebKitUserContentManager *manager = webkit_web_view_get_user_content_manager ();
+ * g_signal_connect (manager, "script-message-received::foobar",
+ *                   G_CALLBACK (handle_script_message), NULL);
+ * webkit_user_content_manager_register_script_message_handler (manager, "foobar");
+ * </programlisting></informalexample>
+ *
+ * Registering a script message handler will fail if the requested
+ * name has been already registered before.
+ *
+ * Returns: %TRUE if message handler was registered successfully, or %FALSE otherwise.
+ *
+ * Since: 2.8
+ */
+gboolean webkit_user_content_manager_register_script_message_handler(WebKitUserContentManager* manager, const char* name)
+{
+    g_return_val_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager), FALSE);
+    g_return_val_if_fail(name, FALSE);
+
+    RefPtr<WebScriptMessageHandler> handler =
+        WebScriptMessageHandler::create(std::make_unique<ScriptMessageClientGtk>(manager, name), String::fromUTF8(name));
+    return manager->priv->userContentController->addUserScriptMessageHandler(handler.get());
+}
+
+/**
+ * webkit_user_content_manager_unregister_script_message_handler:
+ * @manager: A #WebKitUserContentManager
+ * @name: Name of the script message channel
+ *
+ * Unregisters a previously registered message handler.
+ *
+ * Note that this does *not* disconnect handlers for the
+ * #WebKitUserContentManager::script-message-received signal,
+ * they will be kept connected, but the signal will not be emitted
+ * unless the handler name is registered again.
+ *
+ * See also webkit_user_content_manager_register_script_message_handler()
+ *
+ * Since: 2.8
+ */
+void webkit_user_content_manager_unregister_script_message_handler(WebKitUserContentManager* manager, const char* name)
+{
+    g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager));
+    g_return_if_fail(name);
+    manager->priv->userContentController->removeUserMessageHandlerForName(String::fromUTF8(name));
+}
+
 WebUserContentControllerProxy* webkitUserContentManagerGetUserContentControllerProxy(WebKitUserContentManager* manager)
 {
     return manager->priv->userContentController.get();

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h (175413 => 175414)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h	2014-10-31 19:04:19 UTC (rev 175414)
@@ -60,18 +60,25 @@
 
 
 WEBKIT_API GType
-webkit_user_content_manager_get_type                (void);
+webkit_user_content_manager_get_type                          (void);
 
 WEBKIT_API WebKitUserContentManager *
-webkit_user_content_manager_new                     (void);
+webkit_user_content_manager_new                               (void);
 
 WEBKIT_API void
-webkit_user_content_manager_add_style_sheet         (WebKitUserContentManager *manager,
-                                                     WebKitUserStyleSheet     *stylesheet);
+webkit_user_content_manager_add_style_sheet                   (WebKitUserContentManager *manager,
+                                                               WebKitUserStyleSheet     *stylesheet);
 WEBKIT_API void
-webkit_user_content_manager_remove_all_style_sheets (WebKitUserContentManager *manager);
+webkit_user_content_manager_remove_all_style_sheets           (WebKitUserContentManager *manager);
 
+WEBKIT_API gboolean
+webkit_user_content_manager_register_script_message_handler   (WebKitUserContentManager *manager,
+                                                               const gchar              *name);
 WEBKIT_API void
+webkit_user_content_manager_unregister_script_message_handler (WebKitUserContentManager *manager,
+                                                               const gchar              *name);
+
+WEBKIT_API void
 webkit_user_content_manager_add_script              (WebKitUserContentManager *manager,
                                                      WebKitUserScript         *script);
 

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp (175413 => 175414)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2014-10-31 19:04:19 UTC (rev 175414)
@@ -57,6 +57,7 @@
 #include "WebKitWebViewBasePrivate.h"
 #include "WebKitWebViewPrivate.h"
 #include "WebKitWindowPropertiesPrivate.h"
+#include "WebSerializedScriptValue.h"
 #include <_javascript_Core/APICast.h>
 #include <WebCore/CertificateInfo.h>
 #include <WebCore/DragIcon.h>
@@ -2778,7 +2779,8 @@
     }
 
     WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task));
-    g_task_return_pointer(task, webkitJavascriptResultCreate(webView, wkSerializedScriptValue),
+    g_task_return_pointer(task, webkitJavascriptResultCreate(webView,
+        *static_cast<WebCore::SerializedScriptValue*>(wkSerializedScriptValue->internalRepresentation())),
         reinterpret_cast<GDestroyNotify>(webkit_javascript_result_unref));
 }
 

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt (175413 => 175414)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt	2014-10-31 19:04:19 UTC (rev 175414)
@@ -106,6 +106,8 @@
 webkit_user_content_manager_remove_all_style_sheets
 webkit_user_content_manager_add_script
 webkit_user_content_manager_remove_all_scripts
+webkit_user_content_manager_register_script_message_handler
+webkit_user_content_manager_unregister_script_message_handler
 
 <SUBSECTION Standard>
 WEBKIT_IS_USER_CONTENT_MANAGER

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types (175413 => 175414)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types	2014-10-31 19:04:19 UTC (rev 175414)
@@ -27,3 +27,4 @@
 webkit_credential_get_type
 webkit_frame_get_type
 webkit_certificate_info_get_type
+webkit_user_content_manager_get_type

Modified: trunk/Source/cmake/OptionsGTK.cmake (175413 => 175414)


--- trunk/Source/cmake/OptionsGTK.cmake	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/cmake/OptionsGTK.cmake	2014-10-31 19:04:19 UTC (rev 175414)
@@ -145,6 +145,7 @@
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TEMPLATE_ELEMENT ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USERSELECT_ALL ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USER_MESSAGE_HANDLERS ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIBRATION OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO_TRACK ON)

Modified: trunk/Source/cmake/WebKitFeatures.cmake (175413 => 175414)


--- trunk/Source/cmake/WebKitFeatures.cmake	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/cmake/WebKitFeatures.cmake	2014-10-31 19:04:19 UTC (rev 175414)
@@ -132,6 +132,7 @@
     WEBKIT_OPTION_DEFINE(ENABLE_TOUCH_SLIDER "Toggle Touch Slider support" OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_TOUCH_ICON_LOADING "Toggle Touch Icon Loading Support" OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_USERSELECT_ALL "Toggle user-select:all support" OFF)
+    WEBKIT_OPTION_DEFINE(ENABLE_USER_MESSAGE_HANDLERS "Toggle user script message handler support" OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_USER_TIMING "Toggle User Timing support" OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_VIBRATION "Toggle Vibration API support" OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_VIDEO "Toggle Video support" OFF)

Modified: trunk/Source/cmakeconfig.h.cmake (175413 => 175414)


--- trunk/Source/cmakeconfig.h.cmake	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Source/cmakeconfig.h.cmake	2014-10-31 19:04:19 UTC (rev 175414)
@@ -120,6 +120,7 @@
 #cmakedefine01 ENABLE_TOUCH_SLIDER
 #cmakedefine01 ENABLE_TOUCH_ICON_LOADING
 #cmakedefine01 ENABLE_USERSELECT_ALL
+#cmakedefine01 ENABLE_USER_MESSAGE_HANDLERS
 #cmakedefine01 ENABLE_USER_TIMING
 #cmakedefine01 ENABLE_VIBRATION
 #cmakedefine01 ENABLE_VIDEO

Modified: trunk/Tools/ChangeLog (175413 => 175414)


--- trunk/Tools/ChangeLog	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Tools/ChangeLog	2014-10-31 19:04:19 UTC (rev 175414)
@@ -1,3 +1,25 @@
+2014-10-31  Adrian Perez de Castro  <[email protected]>
+
+        [GTK] Support script message handlers WebKitUserContentManager
+        https://bugs.webkit.org/show_bug.cgi?id=133730
+
+        Reviewed by Carlos Garcia Campos.
+
+        Support user script message handlers in WebKitUserContentManager.
+        This needs building with ENABLE_USER_MESSAGE_HANDLERS, for which
+        an option is added to the CMake build files. The option is disabled
+        globally by default, and the WebKitGTK port enables it. On the API
+        level, two new methods to register and unregister names are provided
+        in the "window.webkit" namespace, and on message reception the
+        "WebKitUserContentManager::script-message-received" signal is
+        emitted, using the registered names as signal detail.
+
+        * TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitUserContentManager.cpp:
+        Add test case for user script message handlers.
+        (scriptMessageReceived):
+        (testUserContentManagerScriptMessageReceived):
+        (beforeAll):
+
 2014-10-30  Matthew Hanson  <[email protected]>
 
         bisect-builds should support WebKit clients other than Safari

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitUserContentManager.cpp (175413 => 175414)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitUserContentManager.cpp	2014-10-31 19:02:39 UTC (rev 175413)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitUserContentManager.cpp	2014-10-31 19:04:19 UTC (rev 175414)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Igalia S.L.
+ * Copyright (C) 2013-2014 Igalia S.L.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,7 @@
 #include <gtk/gtk.h>
 #include <webkit2/webkit2.h>
 #include <wtf/gobject/GRefPtr.h>
+#include <wtf/gobject/GUniquePtr.h>
 
 class UserContentManagerTest : public WebViewTest {
 public:
@@ -212,6 +213,134 @@
     removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
 }
 
+class UserScriptMessageTest : public UserContentManagerTest {
+public:
+    MAKE_GLIB_TEST_FIXTURE(UserScriptMessageTest);
+
+    UserScriptMessageTest()
+        : UserContentManagerTest()
+        , m_userScriptMessage(nullptr)
+    {
+    }
+
+    ~UserScriptMessageTest()
+    {
+        if (m_userScriptMessage)
+            webkit_javascript_result_unref(m_userScriptMessage);
+    }
+
+    bool registerHandler(const char* handlerName)
+    {
+        return webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), handlerName);
+    }
+
+    void unregisterHandler(const char* handlerName)
+    {
+        webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), handlerName);
+    }
+
+    static void scriptMessageReceived(WebKitUserContentManager* userContentManager, WebKitJavascriptResult* jsResult, UserScriptMessageTest* test)
+    {
+        g_signal_handlers_disconnect_by_func(userContentManager, reinterpret_cast<gpointer>(scriptMessageReceived), test);
+        g_main_loop_quit(test->m_mainLoop);
+
+        g_assert(!test->m_userScriptMessage);
+        test->m_userScriptMessage = webkit_javascript_result_ref(jsResult);
+    }
+
+    WebKitJavascriptResult* postMessageAndWaitUntilReceived(const char* handlerName, const char* _javascript_ValueAsText)
+    {
+        if (m_userScriptMessage) {
+            webkit_javascript_result_unref(m_userScriptMessage);
+            m_userScriptMessage = nullptr;
+        }
+
+        GUniquePtr<char> signalName(g_strdup_printf("script-message-received::%s", handlerName));
+        g_signal_connect(m_userContentManager.get(), signalName.get(), G_CALLBACK(scriptMessageReceived), this);
+
+        GUniquePtr<char> _javascript_Snippet(g_strdup_printf("window.webkit.messageHandlers.%s.postMessage(%s);", handlerName, _javascript_ValueAsText));
+        webkit_web_view_run_javascript(m_webView, _javascript_Snippet.get(), nullptr, nullptr, nullptr);
+        g_main_loop_run(m_mainLoop);
+
+        g_assert(m_userScriptMessage);
+        return m_userScriptMessage;
+    }
+
+private:
+    WebKitJavascriptResult* m_userScriptMessage;
+};
+
+static void testUserContentManagerScriptMessageReceived(UserScriptMessageTest* test, gconstpointer)
+{
+    g_assert(test->registerHandler("msg"));
+
+    // Trying to register the same handler a second time must fail.
+    g_assert(!test->registerHandler("msg"));
+
+    test->loadHtml("<html></html>", nullptr);
+    test->waitUntilLoadFinished();
+
+    // Check that the "window.webkit.messageHandlers" namespace exists.
+    GUniqueOutPtr<GError> error;
+    WebKitJavascriptResult* _javascript_Result = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers ? 'y' : 'n';", &error.outPtr());
+    g_assert(_javascript_Result);
+    g_assert(!error.get());
+    GUniquePtr<char> valueString(WebViewTest::_javascript_ResultToCString(_javascript_Result));
+    g_assert_cmpstr(valueString.get(), ==, "y");
+
+    // Check that the "document.webkit.messageHandlers.msg" namespace exists.
+    _javascript_Result = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg ? 'y' : 'n';", &error.outPtr());
+    g_assert(_javascript_Result);
+    g_assert(!error.get());
+    valueString.reset(WebViewTest::_javascript_ResultToCString(_javascript_Result));
+    g_assert_cmpstr(valueString.get(), ==, "y");
+
+    valueString.reset(WebViewTest::_javascript_ResultToCString(test->postMessageAndWaitUntilReceived("msg", "'user message'")));
+    g_assert_cmpstr(valueString.get(), ==, "user message");
+
+    // Messages should arrive despite of other handlers being registered.
+    g_assert(test->registerHandler("anotherHandler"));
+
+    // Check that the "document.webkit.messageHandlers.msg" namespace still exists.
+    _javascript_Result = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg ? 'y' : 'n';", &error.outPtr());
+    g_assert(_javascript_Result);
+    g_assert(!error.get());
+    valueString.reset(WebViewTest::_javascript_ResultToCString(_javascript_Result));
+    g_assert_cmpstr(valueString.get(), ==, "y");
+
+    // Check that the "document.webkit.messageHandlers.anotherHandler" namespace exists.
+    _javascript_Result = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.anotherHandler ? 'y' : 'n';", &error.outPtr());
+    g_assert(_javascript_Result);
+    g_assert(!error.get());
+    valueString.reset(WebViewTest::_javascript_ResultToCString(_javascript_Result));
+    g_assert_cmpstr(valueString.get(), ==, "y");
+
+    valueString.reset(WebViewTest::_javascript_ResultToCString(test->postMessageAndWaitUntilReceived("msg", "'handler: msg'")));
+    g_assert_cmpstr(valueString.get(), ==, "handler: msg");
+
+    valueString.reset(WebViewTest::_javascript_ResultToCString(test->postMessageAndWaitUntilReceived("anotherHandler", "'handler: anotherHandler'")));
+    g_assert_cmpstr(valueString.get(), ==, "handler: anotherHandler");
+
+    // Unregistering a handler and re-registering again under the same name should work.
+    test->unregisterHandler("msg");
+
+    // FIXME: Enable after https://bugs.webkit.org/show_bug.cgi?id=138142 gets fixed.
+#if 0
+    _javascript_Result = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg.postMessage('42');", &error.outPtr());
+    g_assert(!_javascript_Result);
+    g_assert(error.get());
+
+    // Re-registering a handler that has been unregistered must work
+    g_assert(test->registerHandler("msg"));
+    message = test->postMessageAndWaitUntilReceived("msg", "'handler: msg'");
+    valueString.reset(WebViewTest::_javascript_ResultToCString(message));
+    webkit_javascript_result_unref(message);
+    g_assert_cmpstr(valueString.get(), ==, "handler: msg");
+#endif
+
+    test->unregisterHandler("anotherHandler");
+}
+
 static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
 {
     soup_message_set_status(message, SOUP_STATUS_OK);
@@ -227,6 +356,7 @@
     Test::add("WebKitWebView", "new-with-user-content-manager", testWebViewNewWithUserContentManager);
     UserContentManagerTest::add("WebKitUserContentManager", "injected-style-sheet", testUserContentManagerInjectedStyleSheet);
     UserContentManagerTest::add("WebKitUserContentManager", "injected-script", testUserContentManagerInjectedScript);
+    UserScriptMessageTest::add("WebKitUserContentManager", "script-message-received", testUserContentManagerScriptMessageReceived);
 }
 
 void afterAll()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to