Diff
Modified: trunk/Source/WebKit2/ChangeLog (175693 => 175694)
--- trunk/Source/WebKit2/ChangeLog 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/ChangeLog 2014-11-06 15:08:07 UTC (rev 175694)
@@ -1,3 +1,58 @@
+2014-11-06 Carlos Garcia Campos <cgar...@igalia.com>
+
+ [GTK] Add context menu API to Web Process Extensions
+ https://bugs.webkit.org/show_bug.cgi?id=138311
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Add WebKitWebPage::context-menu signal, similar to the
+ WebKitWebView one, but that receives a WebKitWebHitTestResult, a
+ class that extends WebKitTestResult to provide the WebKitDOMNode
+ from the Web Process Extensions API. This makes WebKitContextMenu,
+ WebKitContextMenuItem and WebKitTestResult classes shared between
+ UI and Web Extensions APIs. In addition to be able to customize
+ the context menu, it also provides API to set user data, as a
+ GVariant, in the Web Process that is sent to the UI Process.
+
+ * PlatformGTK.cmake: Add new files.
+ * UIProcess/API/gtk/WebKitContextMenu.cpp:
+ (webkit_context_menu_set_user_data): Add user data to the context
+ menu as a GVariant.
+ (webkit_context_menu_get_user_data): Get the user data previously
+ set with webkit_context_menu_set_user_data() either from the Web
+ or UI processes.
+ * UIProcess/API/gtk/WebKitContextMenu.h:
+ * UIProcess/API/gtk/WebKitContextMenuActions.h:
+ * UIProcess/API/gtk/WebKitContextMenuClient.cpp:
+ (getContextMenuFromProposedMenu): Convert the received user data
+ into a GVariant and pass it to webkitWebViewPopulateContextMenu().
+ * UIProcess/API/gtk/WebKitContextMenuItem.h:
+ * UIProcess/API/gtk/WebKitForwardDeclarations.h:
+ * UIProcess/API/gtk/WebKitHitTestResult.h:
+ * UIProcess/API/gtk/WebKitWebView.cpp:
+ (webkitWebViewPopulateContextMenu): Set the user data received
+ from the Web Process to the WebKitContextMenu before emitting
+ WebKitWebView::context-menu.
+ * UIProcess/API/gtk/WebKitWebViewPrivate.h:
+ * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Add new section for WebKitWebHitTestResult.
+ * UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Add new symbols.
+ * UIProcess/API/gtk/docs/webkit2gtk.types: Add webkit_web_hit_test_result_get_type.
+ * WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.cpp: Added.
+ (webkitWebHitTestResultGetProperty): Add getter for node property.
+ (webkitWebHitTestResultSetProperty): Add setter for node property.
+ (webkit_web_hit_test_result_class_init): Add node property.
+ (webkitWebHitTestResultCreate): Create a new
+ WebKitWebHitTestResult for the given InjectedBundleHitTestResult.
+ (webkit_web_hit_test_result_get_node): Return the WebKitDOMNode.
+ * WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.h: Added.
+ * WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResultPrivate.h: Added.
+ * WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp:
+ (getContextMenuFromDefaultMenu): Build a WebKitContextMenu and
+ WebKitWebHitTestResult and emit WebKitWebPage::context-menu signal.
+ (webkit_web_page_class_init): Add WebKitWebPage::context-menu signal.
+ (webkitWebPageCreate): Add implementation for getContextMenuFromDefaultMenu.
+ * WebProcess/InjectedBundle/API/gtk/webkit-web-extension.h:
+
2014-11-06 Ryuan Choi <ryuan.c...@gmail.com>
[EFL] Remove m_scrollPosition from CoordinatedGraphicsScene
Modified: trunk/Source/WebKit2/PlatformGTK.cmake (175693 => 175694)
--- trunk/Source/WebKit2/PlatformGTK.cmake 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/PlatformGTK.cmake 2014-11-06 15:08:07 UTC (rev 175694)
@@ -274,6 +274,7 @@
WebProcess/InjectedBundle/API/gtk/WebKitFrame.cpp
WebProcess/InjectedBundle/API/gtk/WebKitScriptWorld.cpp
WebProcess/InjectedBundle/API/gtk/WebKitWebExtension.cpp
+ WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.cpp
WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp
WebProcess/InjectedBundle/gtk/InjectedBundleGtk.cpp
@@ -372,6 +373,7 @@
${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk/WebKitFrame.h
${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk/WebKitScriptWorld.h
${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk/WebKitWebExtension.h
+ ${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.h
${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.h
${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk/webkit-web-extension.h
)
@@ -797,6 +799,10 @@
-I${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk
${GObjectDOMBindings_GIR_HEADERS}
${WebKit2WebExtension_INSTALLED_HEADERS}
+ ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitContextMenu.h
+ ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitContextMenuActions.h
+ ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitContextMenuItem.h
+ ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitHitTestResult.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitURIRequest.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitURIResponse.h
${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk/*.cpp
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp 2014-11-06 15:08:07 UTC (rev 175694)
@@ -24,6 +24,7 @@
#include "WebContextMenuItem.h"
#include "WebKitContextMenuItemPrivate.h"
#include "WebKitContextMenuPrivate.h"
+#include <wtf/gobject/GRefPtr.h>
using namespace WebKit;
using namespace WebCore;
@@ -50,6 +51,7 @@
struct _WebKitContextMenuPrivate {
GList* items;
WebKitContextMenuItem* parentItem;
+ GRefPtr<GVariant> userData;
};
WEBKIT_DEFINE_TYPE(WebKitContextMenu, webkit_context_menu, G_TYPE_OBJECT)
@@ -316,3 +318,41 @@
g_list_free_full(menu->priv->items, reinterpret_cast<GDestroyNotify>(g_object_unref));
menu->priv->items = 0;
}
+
+/**
+ * webkit_context_menu_set_user_data:
+ * @menu: a #WebKitContextMenu
+ * @user_data: a #GVariant
+ *
+ * Sets user data to @menu.
+ * This function can be used from a Web Process extension to set user data
+ * that can be retrieved from the UI Process using webkit_context_menu_get_user_data().
+ *
+ * Since: 2.8
+ */
+void webkit_context_menu_set_user_data(WebKitContextMenu* menu, GVariant* userData)
+{
+ g_return_if_fail(WEBKIT_IS_CONTEXT_MENU(menu));
+ g_return_if_fail(userData);
+
+ menu->priv->userData = userData;
+}
+
+/**
+ * webkit_context_menu_get_user_data:
+ * @menu: a #WebKitContextMenu
+ *
+ * Gets the user data of @menu.
+ * This function can be used from the UI Process to get user data previously set
+ * from the Web Process with webkit_context_menu_set_user_data().
+ *
+ * Returns: (transfer none): the user data of @menu, or %NULL if @menu doesn't have user data
+ *
+ * Since: 2.8
+ */
+GVariant* webkit_context_menu_get_user_data(WebKitContextMenu* menu)
+{
+ g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(menu), nullptr);
+
+ return menu->priv->userData.get();
+}
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h 2014-11-06 15:08:07 UTC (rev 175694)
@@ -17,7 +17,7 @@
* Boston, MA 02110-1301, USA.
*/
-#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__)
#error "Only <webkit2/webkit2.h> can be included directly."
#endif
@@ -105,6 +105,13 @@
WEBKIT_API void
webkit_context_menu_remove_all (WebKitContextMenu *menu);
+WEBKIT_API void
+webkit_context_menu_set_user_data (WebKitContextMenu *menu,
+ GVariant *user_data);
+
+WEBKIT_API GVariant *
+webkit_context_menu_get_user_data (WebKitContextMenu *menu);
+
G_END_DECLS
#endif
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h 2014-11-06 15:08:07 UTC (rev 175694)
@@ -17,7 +17,7 @@
* Boston, MA 02110-1301, USA.
*/
-#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__)
#error "Only <webkit2/webkit2.h> can be included directly."
#endif
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp 2014-11-06 15:08:07 UTC (rev 175694)
@@ -26,9 +26,15 @@
using namespace WebKit;
-static void getContextMenuFromProposedMenu(WKPageRef, WKArrayRef proposedMenu, WKArrayRef*, WKHitTestResultRef hitTestResult, WKTypeRef /* userData */, const void* clientInfo)
+static void getContextMenuFromProposedMenu(WKPageRef, WKArrayRef proposedMenu, WKArrayRef*, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo)
{
- webkitWebViewPopulateContextMenu(WEBKIT_WEB_VIEW(clientInfo), toImpl(proposedMenu), toImpl(hitTestResult));
+ GRefPtr<GVariant> variant;
+ if (userData) {
+ ASSERT(WKGetTypeID(userData) == WKStringGetTypeID());
+ CString userDataString = toImpl(static_cast<WKStringRef>(userData))->string().utf8();
+ variant = adoptGRef(g_variant_parse(nullptr, userDataString.data(), userDataString.data() + userDataString.length(), nullptr, nullptr));
+ }
+ webkitWebViewPopulateContextMenu(WEBKIT_WEB_VIEW(clientInfo), toImpl(proposedMenu), toImpl(hitTestResult), variant.get());
}
void attachContextMenuClientToView(WebKitWebView* webView)
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h 2014-11-06 15:08:07 UTC (rev 175694)
@@ -17,7 +17,7 @@
* Boston, MA 02110-1301, USA.
*/
-#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__)
#error "Only <webkit2/webkit2.h> can be included directly."
#endif
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h 2014-11-06 15:08:07 UTC (rev 175694)
@@ -23,7 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__)
#error "Only <webkit2/webkit2.h> can be included directly."
#endif
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h 2014-11-06 15:08:07 UTC (rev 175694)
@@ -17,7 +17,7 @@
* Boston, MA 02110-1301, USA.
*/
-#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__)
#error "Only <webkit2/webkit2.h> can be included directly."
#endif
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp 2014-11-06 15:08:07 UTC (rev 175694)
@@ -1891,7 +1891,7 @@
g_signal_emit(webView, signals[CONTEXT_MENU_DISMISSED], 0, NULL);
}
-void webkitWebViewPopulateContextMenu(WebKitWebView* webView, API::Array* proposedMenu, WebHitTestResult* webHitTestResult)
+void webkitWebViewPopulateContextMenu(WebKitWebView* webView, API::Array* proposedMenu, WebHitTestResult* webHitTestResult, GVariant* userData)
{
WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView);
WebContextMenuProxyGtk* contextMenuProxy = webkitWebViewBaseGetActiveContextMenuProxy(webViewBase);
@@ -1917,6 +1917,9 @@
GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(data));
GUniquePtr<GdkEvent> contextMenuEvent(webkitWebViewBaseTakeContextMenuEvent(webViewBase));
+ if (userData)
+ webkit_context_menu_set_user_data(WEBKIT_CONTEXT_MENU(contextMenu.get()), userData);
+
gboolean returnValue;
g_signal_emit(webView, signals[CONTEXT_MENU], 0, contextMenu.get(), contextMenuEvent.get(), hitTestResult.get(), &returnValue);
if (returnValue)
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h 2014-11-06 15:08:07 UTC (rev 175694)
@@ -53,7 +53,7 @@
void webkitWebViewRemoveLoadingWebResource(WebKitWebView*, uint64_t resourceIdentifier);
bool webkitWebViewEnterFullScreen(WebKitWebView*);
bool webkitWebViewLeaveFullScreen(WebKitWebView*);
-void webkitWebViewPopulateContextMenu(WebKitWebView*, API::Array* proposedMenu, WebKit::WebHitTestResult*);
+void webkitWebViewPopulateContextMenu(WebKitWebView*, API::Array* proposedMenu, WebKit::WebHitTestResult*, GVariant*);
void webkitWebViewSubmitFormRequest(WebKitWebView*, WebKitFormSubmissionRequest*);
void webkitWebViewHandleAuthenticationChallenge(WebKitWebView*, WebKit::AuthenticationChallengeProxy*);
void webkitWebViewInsecureContentDetected(WebKitWebView*, WebKitInsecureContentEvent);
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml 2014-11-06 15:08:07 UTC (rev 175694)
@@ -53,6 +53,7 @@
<xi:include href=""
<xi:include href=""
<xi:include href=""
+ <xi:include href=""
</chapter>
<index id="index-all">
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt 2014-11-06 15:08:07 UTC (rev 175694)
@@ -982,6 +982,8 @@
webkit_context_menu_get_item_at_position
webkit_context_menu_remove
webkit_context_menu_remove_all
+webkit_context_menu_set_user_data
+webkit_context_menu_get_user_data
<SUBSECTION Standard>
WebKitContextMenuClass
@@ -1160,3 +1162,22 @@
WebKitScriptWorldPrivate
webkit_script_world_get_type
</SECTION>
+
+<SECTION>
+<FILE>WebKitWebHitTestResult</FILE>
+WebKitWebHitTestResult
+webkit_web_hit_test_result_get_node
+
+<SUBSECTION Standard>
+WebKitWebHitTestResultClass
+WEBKIT_TYPE_WEB_HIT_TEST_RESULT
+WEBKIT_WEB_HIT_TEST_RESULT
+WEBKIT_IS_WEB_HIT_TEST_RESULT
+WEBKIT_WEB_HIT_TEST_RESULT_CLASS
+WEBKIT_IS_WEB_HIT_TEST_RESULT_CLASS
+WEBKIT_WEB_HIT_TEST_RESULT_GET_CLASS
+
+<SUBSECTION Private>
+WebKitWebHitTestResultPrivate
+webkit_web_hit_test_result_get_type
+</SECTION>
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types (175693 => 175694)
--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types 2014-11-06 15:08:07 UTC (rev 175694)
@@ -28,3 +28,4 @@
webkit_frame_get_type
webkit_certificate_info_get_type
webkit_user_content_manager_get_type
+webkit_web_hit_test_result_get_type
Added: trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.cpp (0 => 175694)
--- trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.cpp (rev 0)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.cpp 2014-11-06 15:08:07 UTC (rev 175694)
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WebKitWebHitTestResult.h"
+
+#include "InjectedBundleHitTestResult.h"
+#include "WebKitDOMNodePrivate.h"
+#include "WebKitPrivate.h"
+#include "WebKitWebHitTestResultPrivate.h"
+#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+using namespace WebCore;
+
+/**
+ * SECTION: WebKitWebHitTestResult
+ * @Short_description: Result of a Hit Test (Web Process Extensions)
+ * @Title: WebKitWebHitTestResult
+ * @See_also: #WebKitHitTestResult, #WebKitWebPage
+ *
+ * WebKitWebHitTestResult extends #WebKitHitTestResult to provide information
+ * about the #WebKitDOMNode in the coordinates of the Hit Test.
+ *
+ * Since: 2.8
+ */
+
+enum {
+ PROP_0,
+
+ PROP_NODE
+};
+
+struct _WebKitWebHitTestResultPrivate {
+ GRefPtr<WebKitDOMNode> node;
+};
+
+WEBKIT_DEFINE_TYPE(WebKitWebHitTestResult, webkit_web_hit_test_result, WEBKIT_TYPE_HIT_TEST_RESULT)
+
+static void webkitWebHitTestResultGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+ WebKitWebHitTestResult* webHitTestResult = WEBKIT_WEB_HIT_TEST_RESULT(object);
+
+ switch (propId) {
+ case PROP_NODE:
+ g_value_set_object(value, webkit_web_hit_test_result_get_node(webHitTestResult));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+ }
+}
+
+static void webkitWebHitTestResultSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
+{
+ WebKitWebHitTestResult* webHitTestResult = WEBKIT_WEB_HIT_TEST_RESULT(object);
+
+ switch (propId) {
+ case PROP_NODE: {
+ gpointer node = g_value_get_object(value);
+ webHitTestResult->priv->node = node ? WEBKIT_DOM_NODE(node) : nullptr;
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+ }
+}
+
+static void webkit_web_hit_test_result_class_init(WebKitWebHitTestResultClass* klass)
+{
+ GObjectClass* gObjectClass = G_OBJECT_CLASS(klass);
+
+ gObjectClass->get_property = webkitWebHitTestResultGetProperty;
+ gObjectClass->set_property = webkitWebHitTestResultSetProperty;
+
+ /**
+ * WebKitWebHitTestResult:node:
+ *
+ * The #WebKitDOMNode
+ */
+ g_object_class_install_property(
+ gObjectClass,
+ PROP_NODE,
+ g_param_spec_object(
+ "node",
+ _("Node"),
+ _("The WebKitDOMNode"),
+ WEBKIT_DOM_TYPE_NODE,
+ static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
+}
+
+WebKitWebHitTestResult* webkitWebHitTestResultCreate(const InjectedBundleHitTestResult& hitTestResult)
+{
+ unsigned context = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT;
+ if (!hitTestResult.absoluteLinkURL().isEmpty())
+ context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK;
+ if (!hitTestResult.absoluteImageURL().isEmpty())
+ context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE;
+ if (!hitTestResult.absoluteMediaURL().isEmpty())
+ context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA;
+ if (hitTestResult.coreHitTestResult().isContentEditable())
+ context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;
+ if (hitTestResult.coreHitTestResult().scrollbar())
+ context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR;
+ if (hitTestResult.isSelected())
+ context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION;
+
+ return WEBKIT_WEB_HIT_TEST_RESULT(g_object_new(WEBKIT_TYPE_WEB_HIT_TEST_RESULT,
+ "context", context,
+ "link-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK ? hitTestResult.absoluteLinkURL().utf8().data() : nullptr,
+ "image-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE ? hitTestResult.absoluteImageURL().utf8().data() : nullptr,
+ "media-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA ? hitTestResult.absoluteMediaURL().utf8().data() : nullptr,
+ "link-title", !hitTestResult.linkTitle().isEmpty() ? hitTestResult.linkTitle().utf8().data() : nullptr,
+ "link-label", !hitTestResult.linkLabel().isEmpty() ? hitTestResult.linkLabel().utf8().data() : nullptr,
+ "node", kit(hitTestResult.coreHitTestResult().innerNonSharedNode()),
+ nullptr));
+}
+
+/**
+ * webkit_web_hit_test_result_get_node:
+ * @hit_test_result: a #WebKitWebHitTestResult
+ *
+ * Get the #WebKitDOMNode in the coordinates of the Hit Test.
+ *
+ * Returns: (transfer none): a #WebKitDOMNode
+ *
+ * Since: 2.8
+ */
+WebKitDOMNode* webkit_web_hit_test_result_get_node(WebKitWebHitTestResult* webHitTestResult)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_HIT_TEST_RESULT(webHitTestResult), nullptr);
+
+ return webHitTestResult->priv->node.get();
+}
Added: trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.h (0 => 175694)
--- trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.h (rev 0)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResult.h 2014-11-06 15:08:07 UTC (rev 175694)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit-web-extension.h> can be included directly."
+#endif
+
+#ifndef WebKitWebHitTestResult_h
+#define WebKitWebHitTestResult_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+#include <webkit2/WebKitHitTestResult.h>
+#include <webkitdom/webkitdom.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_WEB_HIT_TEST_RESULT (webkit_web_hit_test_result_get_type())
+#define WEBKIT_WEB_HIT_TEST_RESULT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_WEB_HIT_TEST_RESULT, WebKitWebHitTestResult))
+#define WEBKIT_IS_WEB_HIT_TEST_RESULT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_WEB_HIT_TEST_RESULT))
+#define WEBKIT_WEB_HIT_TEST_RESULT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_WEB_HIT_TEST_RESULT, WebKitWebHitTestResultClass))
+#define WEBKIT_IS_WEB_HIT_TEST_RESULT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEB_HIT_TEST_RESULT))
+#define WEBKIT_WEB_HIT_TEST_RESULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEB_HIT_TEST_RESULT, WebKitWebHitTestResultClass))
+
+typedef struct _WebKitWebHitTestResult WebKitWebHitTestResult;
+typedef struct _WebKitWebHitTestResultClass WebKitWebHitTestResultClass;
+typedef struct _WebKitWebHitTestResultPrivate WebKitWebHitTestResultPrivate;
+
+struct _WebKitWebHitTestResult {
+ WebKitHitTestResult parent;
+
+ WebKitWebHitTestResultPrivate *priv;
+};
+
+struct _WebKitWebHitTestResultClass {
+ WebKitHitTestResultClass parent_class;
+
+ void (*_webkit_reserved0) (void);
+ void (*_webkit_reserved1) (void);
+ void (*_webkit_reserved2) (void);
+ void (*_webkit_reserved3) (void);
+};
+
+WEBKIT_API GType
+webkit_web_hit_test_result_get_type (void);
+
+WEBKIT_API WebKitDOMNode *
+webkit_web_hit_test_result_get_node (WebKitWebHitTestResult *hit_test_result);
+
+G_END_DECLS
+
+#endif
Added: trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResultPrivate.h (0 => 175694)
--- trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResultPrivate.h (rev 0)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebHitTestResultPrivate.h 2014-11-06 15:08:07 UTC (rev 175694)
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebKitWebHitTestResultPrivate_h
+#define WebKitWebHitTestResultPrivate_h
+
+#include "InjectedBundleHitTestResult.h"
+#include "WebKitWebHitTestResult.h"
+
+WebKitWebHitTestResult* webkitWebHitTestResultCreate(const WebKit::InjectedBundleHitTestResult&);
+
+#endif // WebKitWebHitTestResultPrivate_h
Modified: trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp (175693 => 175694)
--- trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.cpp 2014-11-06 15:08:07 UTC (rev 175694)
@@ -20,12 +20,15 @@
#include "config.h"
#include "WebKitWebPage.h"
+#include "APIArray.h"
#include "ImageOptions.h"
#include "ImmutableDictionary.h"
#include "InjectedBundle.h"
#include "WKBundleAPICast.h"
#include "WKBundleFrame.h"
+#include "WebContextMenuItem.h"
#include "WebImage.h"
+#include "WebKitContextMenuPrivate.h"
#include "WebKitDOMDocumentPrivate.h"
#include "WebKitFramePrivate.h"
#include "WebKitMarshal.h"
@@ -33,6 +36,7 @@
#include "WebKitScriptWorldPrivate.h"
#include "WebKitURIRequestPrivate.h"
#include "WebKitURIResponsePrivate.h"
+#include "WebKitWebHitTestResultPrivate.h"
#include "WebKitWebPagePrivate.h"
#include "WebProcess.h"
#include <WebCore/Document.h>
@@ -50,6 +54,7 @@
enum {
DOCUMENT_LOADED,
SEND_REQUEST,
+ CONTEXT_MENU,
LAST_SIGNAL
};
@@ -223,6 +228,36 @@
WebProcess::shared().injectedBundle()->postMessage(String::fromUTF8("WebPage.DidFailLoadForResource"), ImmutableDictionary::create(WTF::move(message)).get());
}
+static void getContextMenuFromDefaultMenu(WKBundlePageRef, WKBundleHitTestResultRef wkHitTestResult, WKArrayRef wkDefaultMenu, WKArrayRef* wkNewMenu, WKTypeRef* wkUserData, const void* clientInfo)
+{
+ GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(toImpl(wkDefaultMenu)));
+ GRefPtr<WebKitWebHitTestResult> webHitTestResult = adoptGRef(webkitWebHitTestResultCreate(*toImpl(wkHitTestResult)));
+ gboolean returnValue;
+ g_signal_emit(WEBKIT_WEB_PAGE(clientInfo), signals[CONTEXT_MENU], 0, contextMenu.get(), webHitTestResult.get(), &returnValue);
+ if (GVariant* userData = webkit_context_menu_get_user_data(contextMenu.get())) {
+ GUniquePtr<gchar> dataString(g_variant_print(userData, TRUE));
+ *wkUserData = static_cast<WKTypeRef>(WKStringCreateWithUTF8CString(dataString.get()));
+ }
+
+ if (!returnValue) {
+ WKRetain(wkDefaultMenu);
+ *wkNewMenu = wkDefaultMenu;
+ return;
+ }
+
+ Vector<ContextMenuItem> contextMenuItems;
+ webkitContextMenuPopulate(contextMenu.get(), contextMenuItems);
+
+ Vector<RefPtr<API::Object>> newMenuItems;
+ newMenuItems.reserveInitialCapacity(contextMenuItems.size());
+ for (const auto& item : contextMenuItems)
+ newMenuItems.uncheckedAppend(WebContextMenuItem::create(item));
+
+ RefPtr<API::Array> array = API::Array::create(WTF::move(newMenuItems));
+ *wkNewMenu = toAPI(array.get());
+ WKRetain(*wkNewMenu);
+}
+
static void webkitWebPageGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
{
WebKitWebPage* webPage = WEBKIT_WEB_PAGE(object);
@@ -305,6 +340,36 @@
G_TYPE_BOOLEAN, 2,
WEBKIT_TYPE_URI_REQUEST,
WEBKIT_TYPE_URI_RESPONSE);
+
+ /**
+ * WebKitWebPage::context-menu:
+ * @web_page: the #WebKitWebPage on which the signal is emitted
+ * @context_menu: the proposed #WebKitContextMenu
+ * @hit_test_result: a #WebKitWebHitTestResult
+ *
+ * Emmited before a context menu is displayed in the UI Process to
+ * give the application a chance to customize the proposed menu,
+ * build its own context menu or pass user data to the UI Process.
+ * This signal is useful when the information available in the UI Process
+ * is not enough to build or customize the context menu, for example, to
+ * add menu entries depending on the #WebKitDOMNode at the coordinates of the
+ * @hit_test_result. Otherwise, it's recommened to use #WebKitWebView::context-menu
+ * signal instead.
+ *
+ * Returns: %TRUE if the proposed @context_menu has been modified, or %FALSE otherwise.
+ *
+ * Since: 2.8
+ */
+ signals[CONTEXT_MENU] = g_signal_new(
+ "context-menu",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__OBJECT_OBJECT,
+ G_TYPE_BOOLEAN, 2,
+ WEBKIT_TYPE_CONTEXT_MENU,
+ WEBKIT_TYPE_WEB_HIT_TEST_RESULT);
}
WebKitWebPage* webkitWebPageCreate(WebPage* webPage)
@@ -371,6 +436,15 @@
};
WKBundlePageSetResourceLoadClient(toAPI(webPage), &resourceLoadClient.base);
+ WKBundlePageContextMenuClientV0 contextMenuClient = {
+ {
+ 0, // version
+ page, // clientInfo
+ },
+ getContextMenuFromDefaultMenu,
+ };
+ WKBundlePageSetContextMenuClient(toAPI(webPage), &contextMenuClient.base);
+
return page;
}
Modified: trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/webkit-web-extension.h (175693 => 175694)
--- trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/webkit-web-extension.h 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/API/gtk/webkit-web-extension.h 2014-11-06 15:08:07 UTC (rev 175694)
@@ -26,12 +26,16 @@
#define __WEBKIT_WEB_EXTENSION_H_INSIDE__
+#include <webkit2/WebKitContextMenu.h>
+#include <webkit2/WebKitContextMenuActions.h>
+#include <webkit2/WebKitContextMenuItem.h>
#include <webkit2/WebKitFrame.h>
#include <webkit2/WebKitScriptWorld.h>
#include <webkit2/WebKitURIRequest.h>
#include <webkit2/WebKitURIResponse.h>
#include <webkit2/WebKitVersion.h>
#include <webkit2/WebKitWebExtension.h>
+#include <webkit2/WebKitWebHitTestResult.h>
#include <webkit2/WebKitWebPage.h>
#undef __WEBKIT_WEB_EXTENSION_H_INSIDE__
Modified: trunk/Tools/ChangeLog (175693 => 175694)
--- trunk/Tools/ChangeLog 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Tools/ChangeLog 2014-11-06 15:08:07 UTC (rev 175694)
@@ -1,3 +1,22 @@
+2014-11-06 Carlos Garcia Campos <cgar...@igalia.com>
+
+ [GTK] Add context menu API to Web Process Extensions
+ https://bugs.webkit.org/show_bug.cgi?id=138311
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Add tests cases for WebKitWebPage::context-menu signal.
+
+ * TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp:
+ (testContextMenuWebExtensionMenu):
+ (testContextMenuWebExtensionNode):
+ (beforeAll):
+ * TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp:
+ (serializeContextMenu):
+ (serializeNode):
+ (contextMenuCallback):
+ (pageCreatedCallback):
+
2014-11-06 Commit Queue <commit-qu...@webkit.org>
Unreviewed, rolling out r175690.
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp (175693 => 175694)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp 2014-11-06 15:08:07 UTC (rev 175694)
@@ -19,6 +19,7 @@
#include "config.h"
#include "WebViewTest.h"
+#include <wtf/Vector.h>
#include <wtf/gobject/GRefPtr.h>
class ContextMenuTest: public WebViewTest {
@@ -882,8 +883,164 @@
g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_widget_get_visible(item));
}
+class ContextMenuWebExtensionTest: public ContextMenuTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(ContextMenuWebExtensionTest);
+
+ void deserializeContextMenuFromUserData(GVariant* userData)
+ {
+ m_actions.clear();
+ if (!userData)
+ return;
+
+ GVariantIter iter;
+ g_variant_iter_init(&iter, userData);
+ m_actions.reserveInitialCapacity(g_variant_iter_n_children(&iter));
+
+ uint32_t item;
+ while (g_variant_iter_next(&iter, "u", &item))
+ m_actions.uncheckedAppend(static_cast<WebKitContextMenuAction>(item));
+ }
+
+ bool contextMenu(WebKitContextMenu* menu, GdkEvent*, WebKitHitTestResult*)
+ {
+ deserializeContextMenuFromUserData(webkit_context_menu_get_user_data(menu));
+ GList* items = webkit_context_menu_get_items(menu);
+ g_assert_cmpuint(g_list_length(items), ==, m_actions.size());
+
+ unsigned actionIndex = 0;
+ for (GList* it = items; it; it = g_list_next(it)) {
+ WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(it->data);
+ g_assert_cmpuint(webkit_context_menu_item_get_stock_action(item), ==, m_actions[actionIndex++]);
+ }
+
+ quitMainLoop();
+
+ return true;
+ }
+
+ Vector<WebKitContextMenuAction> m_actions;
+};
+
+static void testContextMenuWebExtensionMenu(ContextMenuWebExtensionTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped();
+ test->loadHtml("<html><body>WebKitGTK+ Context menu tests<br>"
+ "<a style='position:absolute; left:1; top:10' href=''>WebKitGTK+ Website</a></body></html>",
+ "ContextMenuTestDefault");
+ test->waitUntilLoadFinished();
+
+ // Default context menu.
+ test->showContextMenuAtPositionAndWaitUntilFinished(1, 1);
+ g_assert_cmpuint(test->m_actions.size(), ==, 4);
+ g_assert_cmpuint(test->m_actions[0], ==, WEBKIT_CONTEXT_MENU_ACTION_GO_BACK);
+ g_assert_cmpuint(test->m_actions[1], ==, WEBKIT_CONTEXT_MENU_ACTION_GO_FORWARD);
+ g_assert_cmpuint(test->m_actions[2], ==, WEBKIT_CONTEXT_MENU_ACTION_STOP);
+ g_assert_cmpuint(test->m_actions[3], ==, WEBKIT_CONTEXT_MENU_ACTION_RELOAD);
+
+ // Link menu.
+ test->showContextMenuAtPositionAndWaitUntilFinished(1, 11);
+ g_assert_cmpuint(test->m_actions.size(), ==, 4);
+ g_assert_cmpuint(test->m_actions[0], ==, WEBKIT_CONTEXT_MENU_ACTION_OPEN_LINK);
+ g_assert_cmpuint(test->m_actions[1], ==, WEBKIT_CONTEXT_MENU_ACTION_OPEN_LINK_IN_NEW_WINDOW);
+ g_assert_cmpuint(test->m_actions[2], ==, WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_LINK_TO_DISK);
+ g_assert_cmpuint(test->m_actions[3], ==, WEBKIT_CONTEXT_MENU_ACTION_COPY_LINK_TO_CLIPBOARD);
+
+ // Custom menu.
+ test->loadHtml("<html><body></body></html>", "ContextMenuTestCustom");
+ test->showContextMenuAndWaitUntilFinished();
+ g_assert_cmpuint(test->m_actions.size(), ==, 4);
+ g_assert_cmpuint(test->m_actions[0], ==, WEBKIT_CONTEXT_MENU_ACTION_STOP);
+ g_assert_cmpuint(test->m_actions[1], ==, WEBKIT_CONTEXT_MENU_ACTION_RELOAD);
+ g_assert_cmpuint(test->m_actions[2], ==, WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION);
+ g_assert_cmpuint(test->m_actions[3], ==, WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT);
+
+ // Menu cleared by the web process.
+ test->loadHtml("<html><body></body></html>", "ContextMenuTestClear");
+ test->showContextMenuAndWaitUntilFinished();
+ g_assert_cmpuint(test->m_actions.size(), ==, 0);
+}
+
+class ContextMenuWebExtensionNodeTest: public ContextMenuTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(ContextMenuWebExtensionNodeTest);
+
+ struct Node {
+ enum {
+ NodeUnknown = 0,
+ NodeElement = 1,
+ NodeText = 3
+ };
+ typedef unsigned Type;
+
+ CString name;
+ Type type;
+ CString contents;
+ CString parentName;
+ };
+
+ void deserializeNodeFromUserData(GVariant* userData)
+ {
+ GVariantIter iter;
+ g_variant_iter_init(&iter, userData);
+
+ const char* key;
+ GVariant* value;
+ while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
+ if (!strcmp(key, "Name") && g_variant_classify(value) == G_VARIANT_CLASS_STRING)
+ m_node.name = g_variant_get_string(value, nullptr);
+ else if (!strcmp(key, "Type") && g_variant_classify(value) == G_VARIANT_CLASS_UINT32)
+ m_node.type = g_variant_get_uint32(value);
+ else if (!strcmp(key, "Contents") && g_variant_classify(value) == G_VARIANT_CLASS_STRING)
+ m_node.contents = g_variant_get_string(value, nullptr);
+ else if (!strcmp(key, "Parent") && g_variant_classify(value) == G_VARIANT_CLASS_STRING)
+ m_node.parentName = g_variant_get_string(value, nullptr);
+ g_variant_unref(value);
+ }
+ }
+
+ bool contextMenu(WebKitContextMenu* menu, GdkEvent*, WebKitHitTestResult*)
+ {
+ deserializeNodeFromUserData(webkit_context_menu_get_user_data(menu));
+ quitMainLoop();
+
+ return true;
+ }
+
+ Node m_node;
+};
+
+static void testContextMenuWebExtensionNode(ContextMenuWebExtensionNodeTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped();
+ test->loadHtml("<html><body><p style='position:absolute; left:1; top:1'>WebKitGTK+ Context menu tests</p><br>"
+ "<a style='position:absolute; left:1; top:100' href=''>WebKitGTK+ Website</a></body></html>",
+ "ContextMenuTestNode");
+ test->waitUntilLoadFinished();
+
+ test->showContextMenuAtPositionAndWaitUntilFinished(0, 0);
+ g_assert_cmpstr(test->m_node.name.data(), ==, "HTML");
+ g_assert_cmpuint(test->m_node.type, ==, ContextMenuWebExtensionNodeTest::Node::NodeElement);
+ g_assert_cmpstr(test->m_node.contents.data(), ==, "WebKitGTK+ Context menu testsWebKitGTK+ Website");
+ g_assert_cmpstr(test->m_node.parentName.data(), ==, "#document");
+
+ test->showContextMenuAtPositionAndWaitUntilFinished(1, 20);
+ g_assert_cmpstr(test->m_node.name.data(), ==, "#text");
+ g_assert_cmpuint(test->m_node.type, ==, ContextMenuWebExtensionNodeTest::Node::NodeText);
+ g_assert_cmpstr(test->m_node.contents.data(), ==, "WebKitGTK+ Context menu tests");
+ g_assert_cmpstr(test->m_node.parentName.data(), ==, "P");
+
+ // Link menu.
+ test->showContextMenuAtPositionAndWaitUntilFinished(1, 101);
+ g_assert_cmpstr(test->m_node.name.data(), ==, "#text");
+ g_assert_cmpuint(test->m_node.type, ==, ContextMenuWebExtensionNodeTest::Node::NodeText);
+ g_assert_cmpstr(test->m_node.contents.data(), ==, "WebKitGTK+ Website");
+ g_assert_cmpstr(test->m_node.parentName.data(), ==, "A");
+}
+
void beforeAll()
{
+ webkit_web_context_set_web_extensions_directory(webkit_web_context_get_default(), WEBKIT_TEST_WEB_EXTENSIONS_DIR);
ContextMenuDefaultTest::add("WebKitWebView", "default-menu", testContextMenuDefaultMenu);
ContextMenuCustomTest::add("WebKitWebView", "populate-menu", testContextMenuPopulateMenu);
ContextMenuCustomFullTest::add("WebKitWebView", "custom-menu", testContextMenuCustomMenu);
@@ -891,6 +1048,8 @@
ContextMenuSubmenuTest::add("WebKitWebView", "submenu", testContextMenuSubMenu);
ContextMenuDismissedTest::add("WebKitWebView", "menu-dismissed", testContextMenuDismissed);
ContextMenuSmartSeparatorsTest::add("WebKitWebView", "smart-separators", testContextMenuSmartSeparators);
+ ContextMenuWebExtensionTest::add("WebKitWebPage", "context-menu", testContextMenuWebExtensionMenu);
+ ContextMenuWebExtensionNodeTest::add("WebKitWebPage", "context-menu-node", testContextMenuWebExtensionNode);
}
void afterAll()
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp (175693 => 175694)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp 2014-11-06 10:31:53 UTC (rev 175693)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp 2014-11-06 15:08:07 UTC (rev 175694)
@@ -159,11 +159,67 @@
return FALSE;
}
+static GVariant* serializeContextMenu(WebKitContextMenu* menu)
+{
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ GList* items = webkit_context_menu_get_items(menu);
+ for (GList* it = items; it; it = g_list_next(it))
+ g_variant_builder_add(&builder, "u", webkit_context_menu_item_get_stock_action(WEBKIT_CONTEXT_MENU_ITEM(it->data)));
+ return g_variant_builder_end(&builder);
+}
+
+static GVariant* serializeNode(WebKitDOMNode* node)
+{
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add(&builder, "{sv}", "Name", g_variant_new_take_string(webkit_dom_node_get_node_name(node)));
+ g_variant_builder_add(&builder, "{sv}", "Type", g_variant_new_uint32(webkit_dom_node_get_node_type(node)));
+ g_variant_builder_add(&builder, "{sv}", "Contents", g_variant_new_take_string(webkit_dom_node_get_text_content(node)));
+ WebKitDOMNode* parent = webkit_dom_node_get_parent_node(node);
+ g_variant_builder_add(&builder, "{sv}", "Parent", parent ? g_variant_new_take_string(webkit_dom_node_get_node_name(parent)) : g_variant_new_string("ROOT"));
+ return g_variant_builder_end(&builder);
+}
+
+static gboolean contextMenuCallback(WebKitWebPage* page, WebKitContextMenu* menu, WebKitWebHitTestResult* hitTestResult, gpointer)
+{
+ const char* pageURI = webkit_web_page_get_uri(page);
+ if (!g_strcmp0(pageURI, "ContextMenuTestDefault")) {
+ webkit_context_menu_set_user_data(menu, serializeContextMenu(menu));
+ return FALSE;
+ }
+
+ if (!g_strcmp0(pageURI, "ContextMenuTestCustom")) {
+ // Remove Back and Forward, and add Inspector action.
+ webkit_context_menu_remove(menu, webkit_context_menu_first(menu));
+ webkit_context_menu_remove(menu, webkit_context_menu_first(menu));
+ webkit_context_menu_append(menu, webkit_context_menu_item_new_separator());
+ webkit_context_menu_append(menu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT));
+ webkit_context_menu_set_user_data(menu, serializeContextMenu(menu));
+ return TRUE;
+ }
+
+ if (!g_strcmp0(pageURI, "ContextMenuTestClear")) {
+ webkit_context_menu_remove_all(menu);
+ return TRUE;
+ }
+
+ if (!g_strcmp0(pageURI, "ContextMenuTestNode")) {
+ WebKitDOMNode* node = webkit_web_hit_test_result_get_node(hitTestResult);
+ g_assert(WEBKIT_DOM_IS_NODE(node));
+ webkit_context_menu_set_user_data(menu, serializeNode(node));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void pageCreatedCallback(WebKitWebExtension* extension, WebKitWebPage* webPage, gpointer)
{
g_signal_connect(webPage, "document-loaded", G_CALLBACK(documentLoadedCallback), extension);
g_signal_connect(webPage, "notify::uri", G_CALLBACK(uriChangedCallback), extension);
- g_signal_connect(webPage, "send-request", G_CALLBACK(sendRequestCallback), 0);
+ g_signal_connect(webPage, "send-request", G_CALLBACK(sendRequestCallback), nullptr);
+ g_signal_connect(webPage, "context-menu", G_CALLBACK(contextMenuCallback), nullptr);
}
static JSValueRef echoCallback(JSContextRef jsContext, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*)