[GTK] [WK2] Implement the policy client
authormrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jan 2012 20:15:20 +0000 (20:15 +0000)
committermrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jan 2012 20:15:20 +0000 (20:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76343

Reviewed by Gustavo Noronha Silva.

Source/WebKit2:

Implement the abstract WebKitPolicyDecision, WebKitNavigationPolicyDecision,
and add the decide-policy signal to WebKitWebView.

* GNUmakefile.am: Add new files to the source list.
* UIProcess/API/gtk/WebKitError.cpp: Use the WebCore namespace because
of changes to ASSERT_MATCHING_ENUMS.
* UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp: Added.
* UIProcess/API/gtk/WebKitNavigationPolicyDecision.h: Added.
* UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h: Added.
* UIProcess/API/gtk/WebKitPolicyClient.cpp: Added.
* UIProcess/API/gtk/WebKitPolicyClientPrivate.h: Added.
* UIProcess/API/gtk/WebKitPolicyDecision.cpp: Added.
* UIProcess/API/gtk/WebKitPolicyDecision.h: Added.
* UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h: Added.
* UIProcess/API/gtk/WebKitPrivate.h: Modify ASSERT_MATCHING_ENUMS to make
it useful for non-WebCore enums.
* UIProcess/API/gtk/WebKitWebView.cpp:
(webkitWebViewConstructed): Attach the policy client callbacks to the page.
(webkit_web_view_class_init): Add the decide-policy signal definition.
(webkitWebViewMakePolicyDecision): Added this private method to fire the signal.
* UIProcess/API/gtk/WebKitWebView.h: Added new signal to the list.
* UIProcess/API/gtk/WebKitWebViewPrivate.h: Added new method declaration.
* UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Added new classes to the docs.
* UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Ditto.
* UIProcess/API/gtk/tests/GNUmakefile.am: Added new test to the source list.
* UIProcess/API/gtk/tests/TestWebKitPolicyClient.cpp: Added.
* UIProcess/API/gtk/webkit2marshal.list: decide-policy has a new signature.

Tools:

* gtk/generate-gtkdoc:
(get_webkit2_options): Update the list of skipped source files to include all clients.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@106142 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
Source/WebKit2/ChangeLog
Source/WebKit2/GNUmakefile.am
Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitPolicyClient.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list
Tools/ChangeLog
Tools/gtk/generate-gtkdoc

index b44589d..7b6add0 100644 (file)
@@ -1,3 +1,38 @@
+2012-01-27  Martin Robinson  <mrobinson@igalia.com>
+
+        [GTK] [WK2] Implement the policy client
+        https://bugs.webkit.org/show_bug.cgi?id=76343
+
+        Reviewed by Gustavo Noronha Silva.
+
+        Implement the abstract WebKitPolicyDecision, WebKitNavigationPolicyDecision,
+        and add the decide-policy signal to WebKitWebView.
+
+        * GNUmakefile.am: Add new files to the source list.
+        * UIProcess/API/gtk/WebKitError.cpp: Use the WebCore namespace because
+        of changes to ASSERT_MATCHING_ENUMS.
+        * UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp: Added.
+        * UIProcess/API/gtk/WebKitNavigationPolicyDecision.h: Added.
+        * UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h: Added.
+        * UIProcess/API/gtk/WebKitPolicyClient.cpp: Added.
+        * UIProcess/API/gtk/WebKitPolicyClientPrivate.h: Added.
+        * UIProcess/API/gtk/WebKitPolicyDecision.cpp: Added.
+        * UIProcess/API/gtk/WebKitPolicyDecision.h: Added.
+        * UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h: Added.
+        * UIProcess/API/gtk/WebKitPrivate.h: Modify ASSERT_MATCHING_ENUMS to make
+        it useful for non-WebCore enums.
+        * UIProcess/API/gtk/WebKitWebView.cpp:
+        (webkitWebViewConstructed): Attach the policy client callbacks to the page.
+        (webkit_web_view_class_init): Add the decide-policy signal definition.
+        (webkitWebViewMakePolicyDecision): Added this private method to fire the signal.
+        * UIProcess/API/gtk/WebKitWebView.h: Added new signal to the list.
+        * UIProcess/API/gtk/WebKitWebViewPrivate.h: Added new method declaration.
+        * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Added new classes to the docs.
+        * UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Ditto.
+        * UIProcess/API/gtk/tests/GNUmakefile.am: Added new test to the source list.
+        * UIProcess/API/gtk/tests/TestWebKitPolicyClient.cpp: Added.
+        * UIProcess/API/gtk/webkit2marshal.list: decide-policy has a new signature.
+
 2012-01-27  Ada Chan  <adachan@apple.com>
 
         Add API to get the parent frame in WKBundleFrameRef
index e562845..73c0e45 100644 (file)
@@ -85,10 +85,12 @@ libwebkit2gtkinclude_HEADERS = \
        $(WebKit2)/UIProcess/API/gtk/WebKitDefines.h \
        $(WebKit2)/UIProcess/API/gtk/WebKitDownload.h \
        $(WebKit2)/UIProcess/API/gtk/WebKitError.h \
-       $(WebKit2)/UIProcess/API/gtk/WebKitWebContext.h \
+       $(WebKit2)/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h \
+       $(WebKit2)/UIProcess/API/gtk/WebKitPolicyDecision.h \
        $(WebKit2)/UIProcess/API/gtk/WebKitSettings.h \
        $(WebKit2)/UIProcess/API/gtk/WebKitURIRequest.h \
        $(WebKit2)/UIProcess/API/gtk/WebKitURIResponse.h \
+       $(WebKit2)/UIProcess/API/gtk/WebKitWebContext.h \
        $(WebKit2)/UIProcess/API/gtk/WebKitWebView.h \
        $(WebKit2)/UIProcess/API/gtk/WebKitWebViewBase.h \
        $(WebKit2)/UIProcess/API/gtk/WebKitWindowProperties.h \
@@ -532,6 +534,13 @@ libwebkit2gtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_SOU
        Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp \
        Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.h \
        Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp \
+       Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp \
+       Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h \
+       Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h \
+       Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp \
+       Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.h \
+       Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp \
+       Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.h \
        Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h \
        Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp \
        Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h \
index addcf1b..42cf0ab 100644 (file)
@@ -24,6 +24,8 @@
 #include "WebKitPrivate.h"
 #include <WebCore/ErrorsGtk.h>
 
+using namespace WebCore;
+
 GQuark webkit_network_error_quark()
 {
     return g_quark_from_static_string(WebCore::errorDomainNetwork);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp
new file mode 100644 (file)
index 0000000..fcd57b4
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include "config.h"
+#include "WebKitNavigationPolicyDecision.h"
+
+#include "WebKitEnumTypes.h"
+#include "WebKitPolicyDecisionPrivate.h"
+#include "WebKitPrivate.h"
+#include "WebKitURIRequestPrivate.h"
+#include "WebURLRequest.h"
+#include <gdk/gdk.h>
+#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+
+/**
+ * SECTION: WebKitNavigationPolicyDecision
+ * @Short_description: A policy decision for navigation actions
+ * @Title: WebKitNavigationPolicyDecision
+ * @See_also: #WebKitPolicyDecision, #WebKitWebView
+ *
+ * WebKitNavigationPolicyDecision represents a policy decision for events associated with
+ * navigations. If the value of WebKitNavigationPolicyDecision:mouse-button is not 0, then
+ * the navigation was triggered by a mouse event.
+ */
+
+G_DEFINE_TYPE(WebKitNavigationPolicyDecision, webkit_navigation_policy_decision, WEBKIT_TYPE_POLICY_DECISION)
+
+struct _WebKitNavigationPolicyDecisionPrivate {
+    WebKitNavigationType navigationType;
+    unsigned modifiers;
+    unsigned mouseButton;
+    GRefPtr<WebKitURIRequest> request;
+    CString frameName;
+};
+
+enum {
+    PROP_0,
+    PROP_NAVIGATION_TYPE,
+    PROP_MOUSE_BUTTON,
+    PROP_MODIFIERS,
+    PROP_REQUEST,
+    PROP_FRAME_NAME,
+};
+
+static void webkit_navigation_policy_decision_init(WebKitNavigationPolicyDecision* decision)
+{
+    decision->priv = G_TYPE_INSTANCE_GET_PRIVATE(decision, WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, WebKitNavigationPolicyDecisionPrivate);
+    new (decision->priv) WebKitNavigationPolicyDecisionPrivate();
+}
+
+static void webkitNavigationPolicyDecisionFinalize(GObject* object)
+{
+    WEBKIT_NAVIGATION_POLICY_DECISION(object)->priv->~WebKitNavigationPolicyDecisionPrivate();
+    G_OBJECT_CLASS(webkit_navigation_policy_decision_parent_class)->finalize(object);
+}
+
+static void webkitNavigationPolicyDecisionGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+    WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(object);
+    switch (propId) {
+    case PROP_NAVIGATION_TYPE:
+        g_value_set_enum(value, webkit_navigation_policy_decision_get_navigation_type(decision));
+        break;
+    case PROP_MOUSE_BUTTON:
+        g_value_set_enum(value, webkit_navigation_policy_decision_get_mouse_button(decision));
+        break;
+    case PROP_MODIFIERS:
+        g_value_set_uint(value, webkit_navigation_policy_decision_get_modifiers(decision));
+        break;
+    case PROP_REQUEST:
+        g_value_set_object(value, webkit_navigation_policy_decision_get_request(decision));
+        break;
+    case PROP_FRAME_NAME:
+        g_value_set_string(value, webkit_navigation_policy_decision_get_frame_name(decision));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+        break;
+    }
+}
+
+static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyDecisionClass* decisionClass)
+{
+    GObjectClass* objectClass = G_OBJECT_CLASS(decisionClass);
+    objectClass->finalize = webkitNavigationPolicyDecisionFinalize;
+    objectClass->get_property = webkitNavigationPolicyDecisionGetProperty;
+    g_type_class_add_private(decisionClass, sizeof(WebKitNavigationPolicyDecisionPrivate));
+
+    /**
+     * WebKitNavigationPolicyDecision:navigation-type:
+     *
+     * The type of navigation that triggered this policy decision. This is
+     * useful for enacting different policies depending on what type of user
+     * action caused the navigation.
+     */
+    g_object_class_install_property(objectClass,
+                                    PROP_NAVIGATION_TYPE,
+                                    g_param_spec_enum("navigation-type",
+                                                      _("Navigation type"),
+                                                      _("The type of navigation triggering this decision"),
+                                                      WEBKIT_TYPE_NAVIGATION_TYPE,
+                                                      WEBKIT_NAVIGATION_TYPE_LINK_CLICKED,
+                                                      WEBKIT_PARAM_READABLE));
+
+    /**
+     * WebKitNavigationPolicyDecision:mouse-button:
+     *
+     * If the navigation associated with this policy decision was originally
+     * triggered by a mouse event, this property contains non-zero button number
+     * of the button triggering that event. The button numbers match those from GDK.
+     * If the navigation was not triggered by a mouse event, the value of this
+     * property will be 0.
+     */
+    g_object_class_install_property(objectClass,
+                                    PROP_MOUSE_BUTTON,
+                                    g_param_spec_uint("mouse-button",
+                                                      _("Mouse button"),
+                                                      _("The mouse button used if this decision was triggered by a mouse event"),
+                                                      0, G_MAXUINT, 0,
+                                                      WEBKIT_PARAM_READABLE));
+
+    /**
+     * WebKitNavigationPolicyDecision:modifiers:
+     *
+     * If the navigation associated with this policy decision was originally
+     * triggered by a mouse event, this property contains a bitmask of various
+     * GdkModifierType values describing the modifiers used for that click.
+     * If the navigation was not triggered by a mouse event or no modifiers
+     * were active, the value of this property will be zero.
+     */
+    g_object_class_install_property(objectClass,
+                                    PROP_MODIFIERS,
+                                    g_param_spec_uint("modifiers",
+                                                      _("Mouse event modifiers"),
+                                                      _("The modifiers active if this decision was triggered by a mouse event"),
+                                                      0, G_MAXUINT, 0,
+                                                      WEBKIT_PARAM_READABLE));
+
+    /**
+     * WebKitNavigationPolicyDecision:request:
+     *
+     * This property contains the #WebKitURIRequest associated with this
+     * navigation.
+     */
+    g_object_class_install_property(objectClass,
+                                    PROP_REQUEST,
+                                    g_param_spec_object("request",
+                                                      _("Navigation URI request"),
+                                                      _("The URI request that is associated with this navigation"),
+                                                      WEBKIT_TYPE_URI_REQUEST,
+                                                      WEBKIT_PARAM_READABLE));
+
+    /**
+     * WebKitNavigationPolicyDecision:frame-name:
+     *
+     * If this navigation request targets a new frame, this property contains
+     * the name of that frame. For example if the decision was triggered by clicking a
+     * link with a target attribute equal to "_blank", this property will contain the
+     * value of that attribute. In all other cases, this value will be %NULL.
+     */
+    g_object_class_install_property(objectClass,
+                                    PROP_FRAME_NAME,
+                                    g_param_spec_string("frame-name",
+                                                      _("Frame name"),
+                                                      _("The name of the new frame this navigation action targets"),
+                                                      0,
+                                                      WEBKIT_PARAM_READABLE));
+}
+
+/**
+ * webkit_navigation_policy_decision_get_navigation_type:
+ * @decision: a #WebKitNavigationPolicyDecision
+ *
+ * Gets the value of the #WebKitNavigationPolicyDecision:navigation-type property.
+ *
+ * Returns: The type of navigation triggering this policy decision.
+ */
+WebKitNavigationType webkit_navigation_policy_decision_get_navigation_type(WebKitNavigationPolicyDecision* decision)
+{
+    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), WEBKIT_NAVIGATION_TYPE_OTHER);
+    return decision->priv->navigationType;
+}
+
+/**
+ * webkit_navigation_policy_decision_get_mouse_button:
+ * @decision: a #WebKitNavigationPolicyDecision
+ *
+ * Gets the value of the #WebKitNavigationPolicyDecision:mouse-button property.
+ *
+ * Returns: The mouse button used if this decision was triggered by a mouse event or 0 otherwise
+ */
+guint webkit_navigation_policy_decision_get_mouse_button(WebKitNavigationPolicyDecision* decision)
+{
+    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
+    return decision->priv->mouseButton;
+}
+
+/**
+ * webkit_navigation_policy_decision_get_modifiers:
+ * @decision: a #WebKitNavigationPolicyDecision
+ *
+ * Gets the value of the #WebKitNavigationPolicyDecision:modifiers property.
+ *
+ * Returns: The modifiers active if this decision was triggered by a mouse event
+ */
+unsigned webkit_navigation_policy_decision_get_modifiers(WebKitNavigationPolicyDecision* decision)
+{
+    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
+    return decision->priv->modifiers;
+}
+
+/**
+ * webkit_navigation_policy_decision_get_request:
+ * @decision: a #WebKitNavigationPolicyDecision
+ *
+ * Gets the value of the #WebKitNavigationPolicyDecision:request property.
+ *
+ * Returns: (transfer none): The URI request that is associated with this navigation
+ */
+WebKitURIRequest* webkit_navigation_policy_decision_get_request(WebKitNavigationPolicyDecision* decision)
+{
+    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
+    return decision->priv->request.get();
+}
+
+/**
+ * webkit_navigation_policy_decision_get_frame_name:
+ * @decision: a #WebKitNavigationPolicyDecision
+ *
+ * Gets the value of the #WebKitNavigationPolicyDecision:frame-name property.
+ *
+ * Returns: The name of the new frame this navigation action targets or %NULL 
+ */
+const char* webkit_navigation_policy_decision_get_frame_name(WebKitNavigationPolicyDecision* decision)
+{
+    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
+    return decision->priv->frameName.data();
+}
+
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_LINK_CLICKED, kWKFrameNavigationTypeLinkClicked);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED, kWKFrameNavigationTypeFormSubmitted);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_BACK_FORWARD, kWKFrameNavigationTypeBackForward);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_RELOAD, kWKFrameNavigationTypeReload);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED, kWKFrameNavigationTypeFormResubmitted);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_OTHER, kWKFrameNavigationTypeOther);
+
+static unsigned wkEventMouseButtonToWebKitMouseButton(WKEventMouseButton wkButton)
+{
+    switch (wkButton) {
+    case kWKEventMouseButtonNoButton:
+        return 0;
+    case kWKEventMouseButtonLeftButton:
+        return 1;
+    case kWKEventMouseButtonMiddleButton:
+        return 2;
+    case kWKEventMouseButtonRightButton:
+        return 3;
+    }
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+unsigned wkEventModifiersToUnsigned(WKEventModifiers wkModifiers)
+{
+    unsigned modifiers = 0;
+    if (wkModifiers & kWKEventModifiersShiftKey)
+        modifiers |= GDK_SHIFT_MASK;
+    if (wkModifiers & kWKEventModifiersControlKey)
+        modifiers |= GDK_CONTROL_MASK;
+    if (wkModifiers & kWKEventModifiersAltKey)
+        modifiers |= GDK_MOD1_MASK;
+    if (wkModifiers & kWKEventModifiersMetaKey)
+        modifiers |= GDK_META_MASK;
+    return modifiers;
+}
+
+WebKitNavigationPolicyDecision* webkitNavigationPolicyDecisionCreate(WKFrameNavigationType navigationType, WKEventMouseButton mouseButton, WKEventModifiers modifiers, WKURLRequestRef request, const char* frameName, WKFramePolicyListenerRef listener)
+{
+    WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(g_object_new(WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, NULL));
+    decision->priv->navigationType = static_cast<WebKitNavigationType>(navigationType);
+    decision->priv->mouseButton = wkEventMouseButtonToWebKitMouseButton(mouseButton);
+    decision->priv->modifiers = wkEventModifiersToUnsigned(modifiers);
+    decision->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(toImpl(request)->resourceRequest()));
+    decision->priv->frameName = frameName;
+    webkitPolicyDecisionSetListener(WEBKIT_POLICY_DECISION(decision), listener);
+    return decision;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h
new file mode 100644 (file)
index 0000000..bbf2412
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitNavigationPolicyDecision_h
+#define WebKitNavigationPolicyDecision_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+#include <webkit2/WebKitPolicyDecision.h>
+#include <webkit2/WebKitURIRequest.h>
+
+G_BEGIN_DECLS
+
+/**
+ * WebKitNavigationType:
+ * @WEBKIT_NAVIGATION_TYPE_LINK_CLICKED: The navigation was triggered by clicking a link.
+ * @WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED: The navigation was triggered by submitting a form.
+ * @WEBKIT_NAVIGATION_TYPE_BACK_FORWARD: The navigation was triggered by navigating forward or backward.
+ * @WEBKIT_NAVIGATION_TYPE_RELOAD: The navigation was triggered by reloading.
+ * @WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED: The navigation was triggered by resubmitting a form.
+ * @WEBKIT_NAVIGATION_TYPE_OTHER: The navigation was triggered by some other action.
+ *
+ * Enum values used to denote the various navigation types.
+ */
+typedef enum {
+    WEBKIT_NAVIGATION_TYPE_LINK_CLICKED,
+    WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED,
+    WEBKIT_NAVIGATION_TYPE_BACK_FORWARD,
+    WEBKIT_NAVIGATION_TYPE_RELOAD,
+    WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED,
+    WEBKIT_NAVIGATION_TYPE_OTHER,
+} WebKitNavigationType;
+
+#define WEBKIT_TYPE_NAVIGATION_POLICY_DECISION            (webkit_navigation_policy_decision_get_type())
+#define WEBKIT_NAVIGATION_POLICY_DECISION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, WebKitNavigationPolicyDecision))
+#define WEBKIT_NAVIGATION_POLICY_DECISION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, WebKitNavigationPolicyDecisionClass))
+#define WEBKIT_IS_NAVIGATION_POLICY_DECISION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_NAVIGATION_POLICY_DECISION))
+#define WEBKIT_IS_NAVIGATION_POLICY_DECISION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  WEBKIT_TYPE_NAVIGATION_POLICY_DECISION))
+#define WEBKIT_NAVIGATION_POLICY_DECISION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, WebKitNavigationPolicyDecisionClass))
+
+typedef struct _WebKitNavigationPolicyDecision        WebKitNavigationPolicyDecision;
+typedef struct _WebKitNavigationPolicyDecisionClass   WebKitNavigationPolicyDecisionClass;
+typedef struct _WebKitNavigationPolicyDecisionPrivate WebKitNavigationPolicyDecisionPrivate;
+
+struct _WebKitNavigationPolicyDecision {
+    WebKitPolicyDecision parent;
+
+    /*< private >*/
+    WebKitNavigationPolicyDecisionPrivate *priv;
+};
+
+struct _WebKitNavigationPolicyDecisionClass {
+    WebKitPolicyDecisionClass parent_class;
+};
+
+WEBKIT_API GType
+webkit_navigation_policy_decision_get_type            (void);
+
+WEBKIT_API WebKitNavigationType
+webkit_navigation_policy_decision_get_navigation_type (WebKitNavigationPolicyDecision *decision);
+WEBKIT_API guint
+webkit_navigation_policy_decision_get_mouse_button    (WebKitNavigationPolicyDecision *decision);
+WEBKIT_API guint
+webkit_navigation_policy_decision_get_modifiers       (WebKitNavigationPolicyDecision *decision);
+WEBKIT_API WebKitURIRequest *
+webkit_navigation_policy_decision_get_request         (WebKitNavigationPolicyDecision *decision);
+WEBKIT_API const gchar *
+webkit_navigation_policy_decision_get_frame_name      (WebKitNavigationPolicyDecision *decision);
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h
new file mode 100644 (file)
index 0000000..f3c0e1f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 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 WebKitNavigationPolicyDecisionPrivate_h
+#define WebKitNavigationPolicyDecisionPrivate_h
+
+#include "WebKitNavigationPolicyDecision.h"
+#include "WebKitPrivate.h"
+
+WebKitNavigationPolicyDecision* webkitNavigationPolicyDecisionCreate(WKFrameNavigationType, WKEventMouseButton, WKEventModifiers, WKURLRequestRef, const char* frameName, WKFramePolicyListenerRef);
+
+#endif // WebKitNavigationPolicyDecisionPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp
new file mode 100644 (file)
index 0000000..61757d4
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include "config.h"
+#include "WebKitPolicyClient.h"
+
+#include "WebKitNavigationPolicyDecisionPrivate.h"
+#include "WebKitPolicyDecision.h"
+#include "WebKitPrivate.h"
+#include "WebKitWebViewBasePrivate.h"
+#include "WebKitWebViewPrivate.h"
+#include <wtf/gobject/GRefPtr.h>
+
+using namespace WebKit;
+
+static void decidePolicyForNavigationActionCallback(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo)
+{
+    GRefPtr<WebKitNavigationPolicyDecision> decision =
+        adoptGRef(webkitNavigationPolicyDecisionCreate(navigationType,
+                                                       mouseButton,
+                                                       modifiers,
+                                                       request,
+                                                       0, /* frame name */
+                                                       listener));
+    webkitWebViewMakePolicyDecision(WEBKIT_WEB_VIEW(clientInfo),
+                                    WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION,
+                                    WEBKIT_POLICY_DECISION(decision.get()));
+}
+
+static void decidePolicyForNewWindowActionCallback(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKStringRef frameName, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo)
+{
+    GRefPtr<WebKitNavigationPolicyDecision> decision =
+        adoptGRef(webkitNavigationPolicyDecisionCreate(navigationType,
+                                                       mouseButton,
+                                                       modifiers,
+                                                       request,
+                                                       toImpl(frameName)->string().utf8().data(),
+                                                       listener));
+    webkitWebViewMakePolicyDecision(WEBKIT_WEB_VIEW(clientInfo),
+                                    WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION,
+                                    WEBKIT_POLICY_DECISION(decision.get()));
+}
+
+void attachPolicyClientToPage(WebKitWebView* webView)
+{
+    WKPagePolicyClient policyClient = {
+        kWKPagePolicyClientCurrentVersion,
+        webView, // clientInfo
+        decidePolicyForNavigationActionCallback,
+        decidePolicyForNewWindowActionCallback,
+        0, // decidePolicyForResponseCallback,
+        0, // unableToImplementPolicy
+    };
+    WKPageSetPagePolicyClient(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))), &policyClient);
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.h
new file mode 100644 (file)
index 0000000..90d8d62
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 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 WebKitPolicyClient_h
+#define WebKitPolicyClient_h
+
+#include "WebKitWebView.h"
+
+void attachPolicyClientToPage(WebKitWebView*);
+
+#endif // WebKitPolicyClient_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp
new file mode 100644 (file)
index 0000000..6b67590
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include "config.h"
+#include "WebKitPolicyDecision.h"
+
+#include "WebKitPolicyDecisionPrivate.h"
+#include "WebKitPrivate.h"
+
+
+/**
+ * SECTION: WebKitPolicyDecision
+ * @Short_description: A pending policy decision
+ * @Title: WebKitPolicyDecision
+ * @See_also: #WebKitWebView
+ *
+ * Often WebKit allows the client to decide the policy for certain
+ * operations. For instance, a client may want to open a link in a new
+ * tab, block a navigation entirely, query the user or trigger a download
+ * instead of a navigation. In these cases WebKit will fire the
+ * #WebKitWebView::decide-policy signal with a #WebKitPolicyDecision
+ * object. If the signal handler does nothing, WebKit will act as if
+ * webkit_policy_decision_use() was called as soon as signal handling
+ * completes. To make a policy decision asynchronously, simply increment
+ * the reference count of the #WebKitPolicyDecision object.
+ */
+G_DEFINE_ABSTRACT_TYPE(WebKitPolicyDecision, webkit_policy_decision, G_TYPE_OBJECT)
+
+struct _WebKitPolicyDecisionPrivate {
+    WKRetainPtr<WKFramePolicyListenerRef> listener;
+    bool madePolicyDecision;
+};
+
+static void webkit_policy_decision_init(WebKitPolicyDecision* decision)
+{
+    decision->priv = G_TYPE_INSTANCE_GET_PRIVATE(decision, WEBKIT_TYPE_POLICY_DECISION, WebKitPolicyDecisionPrivate);
+    new (decision->priv) WebKitPolicyDecisionPrivate();
+    decision->priv->madePolicyDecision = false;
+}
+
+static void webkitPolicyDecisionFinalize(GObject* object)
+{
+     WebKitPolicyDecisionPrivate* priv = WEBKIT_POLICY_DECISION(object)->priv;
+
+    // This is the default choice for all policy decisions in WebPageProxy.cpp.
+    if (!priv->madePolicyDecision)
+        WKFramePolicyListenerUse(priv->listener.get());
+
+    priv->~WebKitPolicyDecisionPrivate();
+    G_OBJECT_CLASS(webkit_policy_decision_parent_class)->finalize(object);
+}
+
+void webkitPolicyDecisionSetListener(WebKitPolicyDecision* decision, WKFramePolicyListenerRef listener)
+{
+     decision->priv->listener = listener;
+}
+
+static void webkit_policy_decision_class_init(WebKitPolicyDecisionClass* decisionClass)
+{
+    GObjectClass* objectClass = G_OBJECT_CLASS(decisionClass);
+    objectClass->finalize = webkitPolicyDecisionFinalize;
+    g_type_class_add_private(decisionClass, sizeof(WebKitPolicyDecisionPrivate));
+}
+
+/**
+ * webkit_policy_decision_use:
+ * @decision: a #WebKitPolicyDecision
+ *
+ * Accept the action which triggerd this decision.
+ */
+void webkit_policy_decision_use(WebKitPolicyDecision* decision)
+{
+    g_return_if_fail(WEBKIT_IS_POLICY_DECISION(decision));
+    WKFramePolicyListenerUse(decision->priv->listener.get());
+    decision->priv->madePolicyDecision = true;
+}
+
+/**
+ * webkit_policy_decision_ignore:
+ * @decision: a #WebKitPolicyDecision
+ *
+ * Ignore the action which triggerd this decision. For instance, for a
+ * #WebKitResponsePolicyDecision, this would cancel the request.
+ */
+void webkit_policy_decision_ignore(WebKitPolicyDecision* decision)
+{
+    g_return_if_fail(WEBKIT_IS_POLICY_DECISION(decision));
+    WKFramePolicyListenerIgnore(decision->priv->listener.get());
+    decision->priv->madePolicyDecision = true;
+}
+
+/**
+ * webkit_policy_decision_download:
+ * @decision: a #WebKitPolicyDecision
+ *
+ * Spawn a download from this decision.
+ */
+void webkit_policy_decision_download(WebKitPolicyDecision* decision)
+{
+    g_return_if_fail(WEBKIT_IS_POLICY_DECISION(decision));
+    WKFramePolicyListenerDownload(decision->priv->listener.get());
+    decision->priv->madePolicyDecision = true;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.h
new file mode 100644 (file)
index 0000000..ecca5f9
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitPolicyDecision_h
+#define WebKitPolicyDecision_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_POLICY_DECISION            (webkit_policy_decision_get_type())
+#define WEBKIT_POLICY_DECISION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_POLICY_DECISION, WebKitPolicyDecision))
+#define WEBKIT_POLICY_DECISION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  WEBKIT_TYPE_POLICY_DECISION, WebKitPolicyDecisionClass))
+#define WEBKIT_IS_POLICY_DECISION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_POLICY_DECISION))
+#define WEBKIT_IS_POLICY_DECISION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  WEBKIT_TYPE_POLICY_DECISION))
+#define WEBKIT_POLICY_DECISION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  WEBKIT_TYPE_POLICY_DECISION, WebKitPolicyDecisionClass))
+
+typedef struct _WebKitPolicyDecision        WebKitPolicyDecision;
+typedef struct _WebKitPolicyDecisionClass   WebKitPolicyDecisionClass;
+typedef struct _WebKitPolicyDecisionPrivate WebKitPolicyDecisionPrivate;
+
+struct _WebKitPolicyDecision {
+    GObject parent;
+
+    /*< private >*/
+    WebKitPolicyDecisionPrivate *priv;
+};
+
+struct _WebKitPolicyDecisionClass {
+    GObjectClass parent_class;
+};
+
+WEBKIT_API GType
+webkit_policy_decision_get_type (void);
+
+WEBKIT_API void
+webkit_policy_decision_use      (WebKitPolicyDecision *decision);
+
+WEBKIT_API void
+webkit_policy_decision_ignore   (WebKitPolicyDecision *decision);
+
+WEBKIT_API void
+webkit_policy_decision_download (WebKitPolicyDecision *decision);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h
new file mode 100644 (file)
index 0000000..62580c8
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 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 WebKitPolicyDecisionPrivate_h
+#define WebKitPolicyDecisionPrivate_h
+
+#include "WebKitPolicyDecision.h"
+#include <WebKit2/WebKit2.h>
+
+void webkitPolicyDecisionSetListener(WebKitPolicyDecision*, WKFramePolicyListenerRef);
+
+#endif // WebKitResponsePolicyDecisionPrivate_h
index 3db61a7..13280d6 100644 (file)
 #include <glib.h>
 #include <wtf/Assertions.h>
 
-G_BEGIN_DECLS
-
 #define WEBKIT_PARAM_READABLE (static_cast<GParamFlags>(G_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB))
 #define WEBKIT_PARAM_WRITABLE (static_cast<GParamFlags>(G_PARAM_WRITABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB))
 #define WEBKIT_PARAM_READWRITE (static_cast<GParamFlags>(G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB))
 
 #define COMPILE_ASSERT_MATCHING_ENUM(webkitName, webcoreName) \
-        COMPILE_ASSERT(int(webkitName) == int(WebCore::webcoreName), mismatchingEnums)
-
-G_END_DECLS
+        COMPILE_ASSERT(int(webkitName) == int(webcoreName), mismatchingEnums)
 
 #endif // WebKitPrivate_h
index 9dc472a..e8bcaee 100644 (file)
@@ -26,6 +26,7 @@
 #include "WebKitError.h"
 #include "WebKitLoaderClient.h"
 #include "WebKitMarshal.h"
+#include "WebKitPolicyClient.h"
 #include "WebKitSettingsPrivate.h"
 #include "WebKitUIClient.h"
 #include "WebKitWebContextPrivate.h"
@@ -55,6 +56,8 @@ enum {
     SCRIPT_CONFIRM,
     SCRIPT_PROMPT,
 
+    DECIDE_POLICY,
+
     LAST_SIGNAL
 };
 
@@ -144,6 +147,12 @@ static gboolean webkitWebViewScriptPrompt(WebKitWebView* webView, const char* me
     return TRUE;
 }
 
+static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType)
+{
+    webkit_policy_decision_use(decision);
+    return TRUE;
+}
+
 static void webkitWebViewConstructed(GObject* object)
 {
     if (G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed)
@@ -157,6 +166,7 @@ static void webkitWebViewConstructed(GObject* object)
 
     attachLoaderClientToView(webView);
     attachUIClientToView(webView);
+    attachPolicyClientToPage(webView);
 
     WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase);
     priv->backForwardList = adoptGRef(webkitBackForwardListCreate(WKPageGetBackForwardList(toAPI(page))));
@@ -243,6 +253,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
     webViewClass->script_alert = webkitWebViewScriptAlert;
     webViewClass->script_confirm = webkitWebViewScriptConfirm;
     webViewClass->script_prompt = webkitWebViewScriptPrompt;
+    webViewClass->decide_policy = webkitWebViewDecidePolicy;
 
     g_type_class_add_private(webViewClass, sizeof(WebKitWebViewPrivate));
 
@@ -541,6 +552,66 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
                          G_TYPE_BOOLEAN, 3,
                          G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
 
+    /**
+     * WebKitPolicyClient::decide-policy
+     * @web_view: the #WebKitWebView on which the signal is emitted
+     * @decision: the #WebKitNavigationPolicyDecision
+     * @decision_type: a #WebKitPolicyDecisionType denoting the type of @decision
+     *
+     * This signal is emitted when WebKit is requesting the client to decide a policy
+     * decision, such as whether to navigate to a page, open a new window or whether or
+     * not to download a resource. The #WebKitNavigationPolicyDecision passed in the
+     * @decision argument is a generic type, but should be casted to a more
+     * specific type when making the decision. For example:
+     *
+     * <informalexample><programlisting>
+     * static gboolean
+     * decide_policy_cb (WebKitWebView *web_view,
+     *                   WebKitPolicyDecision *decision,
+     *                   WebKitPolicyDecisionType type)
+     * {
+     *     switch (type) {
+     *     case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION:
+     *         WebKitNavigationPolicyDecision *navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
+     *         /<!-- -->* Make a policy decision here. *<!-- -->/
+     *         break;
+     *     case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION:
+     *         WebKitNavigationPolicyDecision *navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
+     *         /<!-- -->* Make a policy decision here. *<!-- -->/
+     *         break;
+     *     case WEBKIT_POLICY_DECISION_TYPE_RESPONSE:
+     *         WebKitResponsePolicyDecision *response = WEBKIT_RESPONSE_POLICY_DECISION (decision);
+     *         /<!-- -->* Make a policy decision here. *<!-- -->/
+     *         break;
+     *     default:
+     *         /<!-- -->* Making no decision results in webkit_policy_decision_use(). *<!-- -->/
+     *         return FALSE;
+     *     }
+     *     return TRUE;
+     * }
+     * </programlisting></informalexample>
+     *
+     * It is possible to make policy decision asynchronously, by simply calling g_object_ref()
+     * on the @decision argument and returning %TRUE to block the default signal handler.
+     * If the last reference is removed on a #WebKitPolicyDecision and no decision has been
+     * made explicitly, webkit_policy_decision_use() will be the default policy decision. The
+     * default signal handler will simply call webkit_policy_decision_use(). Only the first
+     * policy decision chosen for a given #WebKitPolicyDecision will have any affect.
+     *
+     * Returns: %TRUE to stop other handlers from being invoked for the event.
+     *   %FALSE to propagate the event further.
+     *
+     */
+    signals[DECIDE_POLICY] =
+        g_signal_new("decide-policy",
+                     G_TYPE_FROM_CLASS(webViewClass),
+                     G_SIGNAL_RUN_LAST,
+                     G_STRUCT_OFFSET(WebKitWebViewClass, decide_policy),
+                     g_signal_accumulator_true_handled, 0 /* accumulator data */,
+                     webkit_marshal_BOOLEAN__OBJECT_ENUM,
+                     G_TYPE_BOOLEAN, 2, /* number of parameters */
+                     WEBKIT_TYPE_POLICY_DECISION,
+                     WEBKIT_TYPE_POLICY_DECISION_TYPE);
 }
 
 void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
@@ -646,6 +717,12 @@ WKStringRef webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CStri
     return text ? WKStringCreateWithUTF8CString(text.get()) : 0;
 }
 
+void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision)
+{
+    gboolean returnValue;
+    g_signal_emit(webView, signals[DECIDE_POLICY], 0, decision, type, &returnValue);
+}
+
 /**
  * webkit_web_view_new:
  *
index a25c438..697fcdc 100644 (file)
 #include <webkit2/WebKitURIRequest.h>
 #include <webkit2/WebKitWebViewBase.h>
 #include <webkit2/WebKitWindowProperties.h>
+#include <webkit2/WebKitPolicyDecision.h>
 
 G_BEGIN_DECLS
 
+/**
+ * WebKitPolicyDecisionType:
+ * @WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION: This type of policy decision
+ *   is requested when WebKit is about to navigate to a new page in either the
+ *   main frame or a subframe. Acceptable policy decisions are either
+ *   webkit_policy_decision_use() or webkit_policy_decision_ignore(). This
+ *   type of policy decision is always a #WebKitNavigationPolicyDecision.
+ * @WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION: This type of policy decision
+ *   is requested when WebKit is about to create a new window. Acceptable policy
+ *   decisions are either webkit_policy_decision_use() or
+ *   webkit_policy_decision_ignore(). This type of policy decision is always
+ *   a #WebKitNavigationPolicyDecision. These decisions are useful for implementing
+ *   special actions for new windows, such as forcing the new window to open
+ *   in a tab when a keyboard modifier is active or handling a special
+ *   target attribute on &lt;a&gt; elements.
+ * @WEBKIT_POLICY_DECISION_TYPE_RESPONSE: This type of decision is used when WebKit has
+ *   received a response for a network resource and is about to start the load.
+ *   Note that these resources include all subresources of a page such as images
+ *   and stylesheets as well as main documents. Appropriate policy responses to
+ *   this decision are webkit_policy_decision_use(), webkit_policy_decision_ignore(),
+ *   or webkit_policy_decision_download(). This type of policy decision is always
+ *   a #WebKitResponsePolicyDecision. This decision is useful for forcing
+ *   some types of resources to be downloaded rather than rendered in the WebView
+ *   or to block the transfer of resources entirely.
+ *
+ * Enum values used for determining the type of a policy decision during
+ * WebKitWebView::decide-policy.
+ */
+typedef enum {
+    WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION,
+    WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION,
+    WEBKIT_POLICY_DECISION_TYPE_RESPONSE,
+} WebKitPolicyDecisionType;
+
 #define WEBKIT_TYPE_WEB_VIEW            (webkit_web_view_get_type())
 #define WEBKIT_WEB_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_WEB_VIEW, WebKitWebView))
 #define WEBKIT_WEB_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  WEBKIT_TYPE_WEB_VIEW, WebKitWebViewClass))
@@ -81,26 +116,29 @@ struct _WebKitWebView {
 struct _WebKitWebViewClass {
     WebKitWebViewBaseClass parent;
 
-    void       (* load_changed)   (WebKitWebView  *web_view,
-                                   WebKitLoadEvent load_event);
-    gboolean   (* load_failed)    (WebKitWebView  *web_view,
-                                   WebKitLoadEvent load_event,
-                                   const gchar    *failing_uri,
-                                   GError         *error);
-
-    GtkWidget *(* create)         (WebKitWebView  *web_view);
-    void       (* ready_to_show)  (WebKitWebView  *web_view);
-    void       (* close)          (WebKitWebView  *web_view);
-
-    gboolean   (* script_alert)   (WebKitWebView  *web_view,
-                                   const gchar    *message);
-    gboolean   (* script_confirm) (WebKitWebView  *web_view,
-                                   const gchar    *message,
-                                   gboolean       *confirmed);
-    gboolean   (* script_prompt)  (WebKitWebView  *web_view,
-                                   const gchar    *message,
-                                   const gchar    *default_text,
-                                   gchar         **text);
+    void       (* load_changed)   (WebKitWebView             *web_view,
+                                   WebKitLoadEvent            load_event);
+    gboolean   (* load_failed)    (WebKitWebView             *web_view,
+                                   WebKitLoadEvent            load_event,
+                                   const gchar               *failing_uri,
+                                   GError                    *error);
+
+    GtkWidget *(* create)         (WebKitWebView             *web_view);
+    void       (* ready_to_show)  (WebKitWebView             *web_view);
+    void       (* close)          (WebKitWebView             *web_view);
+
+    gboolean   (* script_alert)   (WebKitWebView             *web_view,
+                                   const gchar               *message);
+    gboolean   (* script_confirm) (WebKitWebView             *web_view,
+                                   const gchar               *message,
+                                   gboolean                  *confirmed);
+    gboolean   (* script_prompt)  (WebKitWebView             *web_view,
+                                   const gchar               *message,
+                                   const gchar               *default_text,
+                                   gchar                    **text);
+    gboolean   (* decide_policy)  (WebKitWebView             *web_view,
+                                   WebKitPolicyDecision      *decision,
+                                   WebKitPolicyDecisionType  type);
 
     /* Padding for future expansion */
     void (*_webkit_reserved0) (void);
index 5c8161a..66386d0 100644 (file)
@@ -42,5 +42,6 @@ void webkitWebViewClosePage(WebKitWebView*);
 void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message);
 bool webkitWebViewRunJavaScriptConfirm(WebKitWebView*, const CString& message);
 WKStringRef webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText);
+void webkitWebViewMakePolicyDecision(WebKitWebView*, WebKitPolicyDecisionType, WebKitPolicyDecision*);
 
 #endif // WebKitWebViewPrivate_h
index 6c0ec46..c6f943a 100644 (file)
@@ -21,6 +21,8 @@
     <xi:include href="xml/WebKitURIResponse.xml"/>
     <xi:include href="xml/WebKitWindowProperties.xml"/>
     <xi:include href="xml/WebKitDownload.xml"/>
+    <xi:include href="xml/WebKitPolicyDecision.xml"/>
+    <xi:include href="xml/WebKitNavigationPolicyDecision.xml"/>
     <xi:include href="xml/WebKitError.xml"/>
   </chapter>
 
index 478979b..ef44b2b 100644 (file)
@@ -48,6 +48,7 @@ webkit_web_context_get_type
 <TITLE>WebKitWebView</TITLE>
 WebKitWebView
 WebKitLoadEvent
+WebKitPolicyDecisionType
 webkit_web_view_new
 webkit_web_view_new_with_context
 webkit_web_view_get_context
@@ -312,6 +313,51 @@ webkit_download_get_type
 </SECTION>
 
 <SECTION>
+<FILE>WebKitPolicyDecision</FILE>
+WebKitPolicyDecision
+webkit_policy_decision_download
+webkit_policy_decision_ignore
+webkit_policy_decision_use
+
+<SUBSECTION Standard>
+WebKitPolicyDecisionClass
+WEBKIT_TYPE_POLICY_DECISION
+WEBKIT_POLICY_DECISION
+WEBKIT_IS_POLICY_DECISION
+WEBKIT_POLICY_DECISION_CLASS
+WEBKIT_IS_POLICY_DECISION_CLASS
+WEBKIT_POLICY_DECISION_GET_CLASS
+
+<SUBSECTION Private>
+WebKitPolicyDecisionPrivate
+webkit_policy_decision_get_type
+</SECTION>
+
+<SECTION>
+<FILE>WebKitNavigationPolicyDecision</FILE>
+WebKitNavigationPolicyDecision
+WebKitNavigationType
+webkit_navigation_policy_decision_get_frame_name
+webkit_navigation_policy_decision_get_modifiers
+webkit_navigation_policy_decision_get_mouse_button
+webkit_navigation_policy_decision_get_navigation_type
+webkit_navigation_policy_decision_get_request
+
+<SUBSECTION Standard>
+WebKitNavigationPolicyDecisionClass
+WEBKIT_TYPE_NAVIGATION_POLICY_DECISION
+WEBKIT_NAVIGATION_POLICY_DECISION
+WEBKIT_IS_NAVIGATION_POLICY_DECISION
+WEBKIT_NAVIGATION_POLICY_DECISION_CLASS
+WEBKIT_IS_NAVIGATION_POLICY_DECISION_CLASS
+WEBKIT_NAVIGATION_POLICY_DECISION_GET_CLASS
+
+<SUBSECTION Private>
+WebKitNavigationPolicyDecisionPrivate
+webkit_navigation_policy_decision_get_type
+</SECTION>
+
+<SECTION>
 <FILE>WebKitError</FILE>
 WEBKIT_NETWORK_ERROR
 WEBKIT_PLUGIN_ERROR
index df537ca..175a149 100644 (file)
@@ -4,7 +4,8 @@ TEST_PROGS += \
        Programs/WebKit2APITests/TestLoaderClient \
        Programs/WebKit2APITests/TestWebKitSettings \
        Programs/WebKit2APITests/TestBackForwardList \
-       Programs/WebKit2APITests/TestDownloads
+       Programs/WebKit2APITests/TestDownloads \
+       Programs/WebKit2APITests/TestWebKitPolicyClient
 
 noinst_PROGRAMS += $(TEST_PROGS)
 
@@ -85,6 +86,12 @@ Programs_WebKit2APITests_TestBackForwardList_CPPFLAGS = $(webkit2_tests_cppflags
 Programs_WebKit2APITests_TestBackForwardList_LDADD = $(webkit2_tests_ldadd)
 Programs_WebKit2APITests_TestBackForwardList_LDFLAGS = $(webkit2_tests_ldflags)
 
+Programs_WebKit2APITests_TestWebKitPolicyClient_SOURCES = \
+        Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitPolicyClient.cpp
+Programs_WebKit2APITests_TestWebKitPolicyClient_CPPFLAGS = $(webkit2_tests_cppflags)
+Programs_WebKit2APITests_TestWebKitPolicyClient_LDADD = $(webkit2_tests_ldadd)
+Programs_WebKit2APITests_TestWebKitPolicyClient_LDFLAGS = $(webkit2_tests_ldflags)
+
 if HAVE_ATSPI2
 Programs_WebKit2APITests_AccessibilityTestServer_SOURCES = \
        Source/WebKit2/UIProcess/API/gtk/tests/AccessibilityTestServer.cpp
@@ -104,4 +111,3 @@ Programs_WebKit2APITests_TestDownloads_SOURCES = \
 Programs_WebKit2APITests_TestDownloads_CPPFLAGS = $(webkit2_tests_cppflags)
 Programs_WebKit2APITests_TestDownloads_LDADD = $(webkit2_tests_ldadd)
 Programs_WebKit2APITests_TestDownloads_LDFLAGS = $(webkit2_tests_ldflags)
-
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitPolicyClient.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitPolicyClient.cpp
new file mode 100644 (file)
index 0000000..7cbe4e7
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include "config.h"
+
+#include "LoadTrackingTest.h"
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+class PolicyClientTest: public LoadTrackingTest {
+public:
+    MAKE_GLIB_TEST_FIXTURE(PolicyClientTest);
+
+    enum PolicyDecisionResponse {
+        Use,
+        Ignore,
+        Download,
+        None
+    };
+
+    PolicyClientTest()
+        : LoadTrackingTest()
+        , m_policyDecisionResponse(None)
+        , m_policyDecisionTypeFilter(0)
+        , m_respondToPolicyDecisionAsynchronously(false)
+        , m_haltMainLoopAfterMakingDecision(false)
+    {
+        g_signal_connect(m_webView, "decide-policy", G_CALLBACK(decidePolicyCallback), this);
+    }
+
+    static gboolean quitMainLoopLater(GMainLoop* loop)
+    {
+        g_main_loop_quit(loop);
+        return FALSE;
+    }
+
+    static void respondToPolicyDecision(PolicyClientTest* test, WebKitPolicyDecision* decision)
+    {
+        switch (test->m_policyDecisionResponse) {
+        case Use:
+            webkit_policy_decision_use(decision);
+            break;
+        case Ignore:
+            webkit_policy_decision_ignore(decision);
+            break;
+        case Download:
+            webkit_policy_decision_download(decision);
+            break;
+        case None:
+            break;
+        }
+
+        if (test->m_haltMainLoopAfterMakingDecision)
+            g_idle_add(reinterpret_cast<GSourceFunc>(quitMainLoopLater), test->m_mainLoop);
+    }
+
+    static gboolean respondToPolicyDecisionLater(PolicyClientTest* test)
+    {
+        respondToPolicyDecision(test, test->m_previousPolicyDecision.get());
+        test->m_previousPolicyDecision = 0;
+        return FALSE;
+    }
+
+    static gboolean decidePolicyCallback(WebKitWebView* webView, WebKitPolicyDecision* decision, WebKitPolicyDecisionType type, PolicyClientTest* test)
+    {
+        if (test->m_policyDecisionTypeFilter != type)
+            return FALSE;
+
+        test->m_previousPolicyDecision = decision;
+        if (test->m_respondToPolicyDecisionAsynchronously) {
+            g_idle_add(reinterpret_cast<GSourceFunc>(respondToPolicyDecisionLater), test);
+            return TRUE;
+        }
+
+        respondToPolicyDecision(test, decision);
+
+        // We return FALSE here to ensure that the default policy decision
+        // handler doesn't override whatever we use here.
+        return FALSE;
+    }
+
+    PolicyDecisionResponse m_policyDecisionResponse;
+    int m_policyDecisionTypeFilter;
+    bool m_respondToPolicyDecisionAsynchronously;
+    bool m_haltMainLoopAfterMakingDecision;
+    GRefPtr<WebKitPolicyDecision> m_previousPolicyDecision;
+};
+
+static void testNavigationPolicy(PolicyClientTest* test, gconstpointer)
+{
+    test->m_policyDecisionTypeFilter = WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION;
+
+    test->m_policyDecisionResponse = PolicyClientTest::Use;
+    test->loadHtml("<html/>", "http://webkitgtk.org/");
+    test->waitUntilLoadFinished();
+    g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
+
+    // Ideally we'd like to have a more intensive test here, but it's still pretty tricky
+    // to trigger different types of navigations with the GTK+ WebKit2 API.
+    WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(test->m_previousPolicyDecision.get());
+    g_assert_cmpint(webkit_navigation_policy_decision_get_navigation_type(decision), ==, WEBKIT_NAVIGATION_TYPE_OTHER);
+    g_assert_cmpint(webkit_navigation_policy_decision_get_mouse_button(decision), ==, 0);
+    g_assert_cmpint(webkit_navigation_policy_decision_get_modifiers(decision), ==, 0);
+    g_assert_cmpstr(webkit_navigation_policy_decision_get_frame_name(decision), ==, 0);
+    WebKitURIRequest* request = webkit_navigation_policy_decision_get_request(decision);
+    g_assert_cmpstr(webkit_uri_request_get_uri(request), ==, "http://webkitgtk.org/");
+
+    test->m_policyDecisionResponse = PolicyClientTest::Use;
+    test->m_respondToPolicyDecisionAsynchronously = true;
+    test->loadHtml("<html/>", "http://webkitgtk.org/");
+    test->waitUntilLoadFinished();
+    g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
+
+    // If we are waiting until load completion, it will never complete if we ignore the
+    // navigation. So we tell the main loop to quit sometime later.
+    test->m_policyDecisionResponse = PolicyClientTest::Ignore;
+    test->m_respondToPolicyDecisionAsynchronously = false;
+    test->m_haltMainLoopAfterMakingDecision = true;
+    test->loadHtml("<html/>", "http://webkitgtk.org/");
+    test->waitUntilLoadFinished();
+    g_assert_cmpint(test->m_loadEvents.size(), ==, 0);
+
+    test->m_policyDecisionResponse = PolicyClientTest::Ignore;
+    test->loadHtml("<html/>", "http://webkitgtk.org/");
+    test->waitUntilLoadFinished();
+    g_assert_cmpint(test->m_loadEvents.size(), ==, 0);
+}
+
+struct CreateCallbackData {
+    bool triedToOpenWindow;
+    GMainLoop* mainLoop;
+};
+
+static WebKitWebView* createCallback(WebKitWebView* webView, CreateCallbackData* data)
+{
+    data->triedToOpenWindow = true;
+    g_main_loop_quit(data->mainLoop);
+    return 0;
+}
+
+static void testNewWindowPolicy(PolicyClientTest* test, gconstpointer)
+{
+    static const char* windowOpeningHTML =
+        "<html><body>"
+        "    <a id=\"link\" href=\"http://www.google.com\" target=\"_blank\">Link</a>"
+        "    <script>"
+        "        var event = document.createEvent('MouseEvents');"
+        "        event.initEvent('click', true, false);"
+        "        document.getElementById('link').dispatchEvent(event);"
+        "    </script>"
+        "</body></html>";
+    test->m_policyDecisionTypeFilter = WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION;
+    webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(test->m_webView), TRUE);
+
+    CreateCallbackData data;
+    data.triedToOpenWindow = false;
+    data.mainLoop = test->m_mainLoop;
+
+    g_signal_connect(test->m_webView, "create", G_CALLBACK(createCallback), &data);
+    test->m_policyDecisionResponse = PolicyClientTest::Use;
+    test->loadHtml(windowOpeningHTML, "http://webkitgtk.org/");
+    test->wait(1);
+    g_assert(data.triedToOpenWindow);
+
+    WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(test->m_previousPolicyDecision.get());
+    g_assert_cmpstr(webkit_navigation_policy_decision_get_frame_name(decision), ==, "_blank");
+
+    // Using a short timeout is a bit ugly here, but it's hard to get around because if we block
+    // the new window signal we cannot halt the main loop in the create callback. If we
+    // halt the main loop in the policy decision, the create callback never executes.
+    data.triedToOpenWindow = false;
+    test->m_policyDecisionResponse = PolicyClientTest::Ignore;
+    test->loadHtml(windowOpeningHTML, "http://webkitgtk.org/");
+    test->wait(.2);
+    g_assert(!data.triedToOpenWindow);
+}
+
+void beforeAll()
+{
+    PolicyClientTest::add("WebKitPolicyClient", "navigation-policy", testNavigationPolicy);
+    PolicyClientTest::add("WebKitPolicyClient", "new-window-policy", testNewWindowPolicy);
+}
+
+void afterAll()
+{
+}
index e6dda10..5918d09 100644 (file)
@@ -1,5 +1,6 @@
 BOOLEAN:ENUM,STRING,POINTER
 BOOLEAN:OBJECT
+BOOLEAN:OBJECT,ENUM
 BOOLEAN:OBJECT,STRING,POINTER
 BOOLEAN:POINTER
 BOOLEAN:STRING
index d6d33c0..90fc73a 100644 (file)
@@ -1,3 +1,13 @@
+2012-01-27  Martin Robinson  <mrobinson@igalia.com>
+
+        [GTK] [WK2] Implement the policy client
+        https://bugs.webkit.org/show_bug.cgi?id=76343
+
+        Reviewed by Gustavo Noronha Silva.
+
+        * gtk/generate-gtkdoc:
+        (get_webkit2_options): Update the list of skipped source files to include all clients.
+
 2012-01-27  Ada Chan  <adachan@apple.com>
 
         Add test for WKBundleFrameGetParentFrame().
index f698afa..a58345c 100755 (executable)
@@ -59,10 +59,7 @@ def get_webkit2_options():
                    ' -I' + common.top_level_path('Source') + \
                    ' -I' + src_path(),
         'ignored_files': glob.glob(src_path('*Private.h')) + \
-                         glob.glob(src_path('PageClientImpl.*')) + \
-                         glob.glob(src_path('WebKitDownloadClient.*')) + \
-                         glob.glob(src_path('WebKitUIClient.*')) + \
-                         glob.glob(src_path('WebKitLoaderClient.*')) + \
+                         glob.glob(src_path('*Client*')) + \
                          glob.glob(src_path('WebKitWebViewBaseAccessible.*')) + \
                          glob.glob(src_path('tests/*.h'))
     })