Skip to content

Commit

Permalink
[GTK] Support script message handlers WebKitUserContentManager
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=133730

Patch by Adrian Perez de Castro <aperez@igalia.com> 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):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@175414 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
commit-queue@webkit.org committed Oct 31, 2014
1 parent ec38f42 commit 388d291
Show file tree
Hide file tree
Showing 16 changed files with 390 additions and 12 deletions.
21 changes: 21 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
2014-10-31 Adrian Perez de Castro <aperez@igalia.com>

[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 <rakuco@FreeBSD.org>

[GTK] Bump libsoup's minimum version to 2.42.0.
Expand Down
15 changes: 15 additions & 0 deletions Source/WebCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3107,6 +3107,21 @@ if (ENABLE_WEB_REPLAY)
)
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"
Expand Down
19 changes: 19 additions & 0 deletions Source/WebCore/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
2014-10-31 Adrian Perez de Castro <aperez@igalia.com>

[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 <a.badowski@samsung.com>

[ATK] Improve AccessibilityTableCell's determineAccessibilityRole function.
Expand Down
36 changes: 36 additions & 0 deletions Source/WebKit2/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
2014-10-31 Adrian Perez de Castro <aperez@igalia.com>

[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 <mhock@apple.com>

Unreviewed, iOS build fix since 175406.
Expand Down
6 changes: 3 additions & 3 deletions Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -42,7 +42,7 @@ struct _WebKitJavascriptResult {

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
121 changes: 120 additions & 1 deletion Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -59,8 +63,39 @@ struct _WebKitUserContentManagerPrivate {

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);
}

/**
Expand Down Expand Up @@ -141,6 +176,90 @@ void webkit_user_content_manager_remove_all_scripts(WebKitUserContentManager* ma
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();
Expand Down
17 changes: 12 additions & 5 deletions Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,23 @@ struct _WebKitUserContentManagerClass {


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,
Expand Down
4 changes: 3 additions & 1 deletion Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include "WebKitWebViewBasePrivate.h"
#include "WebKitWebViewPrivate.h"
#include "WebKitWindowPropertiesPrivate.h"
#include "WebSerializedScriptValue.h"
#include <JavaScriptCore/APICast.h>
#include <WebCore/CertificateInfo.h>
#include <WebCore/DragIcon.h>
Expand Down Expand Up @@ -2778,7 +2779,8 @@ static void webkitWebViewRunJavaScriptCallback(WebSerializedScriptValue* wkSeria
}

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));
}

Expand Down
2 changes: 2 additions & 0 deletions Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ webkit_user_content_manager_add_style_sheet
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
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ webkit_authentication_request_get_type
webkit_credential_get_type
webkit_frame_get_type
webkit_certificate_info_get_type
webkit_user_content_manager_get_type
1 change: 1 addition & 0 deletions Source/cmake/OptionsGTK.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SUBTLE_CRYPTO OFF)
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)
Expand Down
1 change: 1 addition & 0 deletions Source/cmake/WebKitFeatures.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ macro(WEBKIT_OPTION_BEGIN)
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)
Expand Down
1 change: 1 addition & 0 deletions Source/cmakeconfig.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 388d291

Please sign in to comment.