1/*
2 * Copyright (C) 2012 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "WebKitNavigationPolicyDecision.h"
22
23#include "WebEvent.h"
24#include "WebKitEnumTypes.h"
25#include "WebKitPolicyDecisionPrivate.h"
26#include "WebKitURIRequestPrivate.h"
27#include "WebURLRequest.h"
28#include <glib/gi18n-lib.h>
29#include <wtf/gobject/GRefPtr.h>
30#include <wtf/text/CString.h>
31
32using namespace WebKit;
33using namespace WebCore;
34
35/**
36 * SECTION: WebKitNavigationPolicyDecision
37 * @Short_description: A policy decision for navigation actions
38 * @Title: WebKitNavigationPolicyDecision
39 * @See_also: #WebKitPolicyDecision, #WebKitWebView
40 *
41 * WebKitNavigationPolicyDecision represents a policy decision for events associated with
42 * navigations. If the value of #WebKitNavigationPolicyDecision:mouse-button is not 0, then
43 * the navigation was triggered by a mouse event.
44 */
45
46struct _WebKitNavigationPolicyDecisionPrivate {
47    WebKitNavigationType navigationType;
48    unsigned modifiers;
49    unsigned mouseButton;
50    GRefPtr<WebKitURIRequest> request;
51    CString frameName;
52};
53
54WEBKIT_DEFINE_TYPE(WebKitNavigationPolicyDecision, webkit_navigation_policy_decision, WEBKIT_TYPE_POLICY_DECISION)
55
56enum {
57    PROP_0,
58    PROP_NAVIGATION_TYPE,
59    PROP_MOUSE_BUTTON,
60    PROP_MODIFIERS,
61    PROP_REQUEST,
62    PROP_FRAME_NAME,
63};
64
65static void webkitNavigationPolicyDecisionGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
66{
67    WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(object);
68    switch (propId) {
69    case PROP_NAVIGATION_TYPE:
70        g_value_set_enum(value, webkit_navigation_policy_decision_get_navigation_type(decision));
71        break;
72    case PROP_MOUSE_BUTTON:
73        g_value_set_enum(value, webkit_navigation_policy_decision_get_mouse_button(decision));
74        break;
75    case PROP_MODIFIERS:
76        g_value_set_uint(value, webkit_navigation_policy_decision_get_modifiers(decision));
77        break;
78    case PROP_REQUEST:
79        g_value_set_object(value, webkit_navigation_policy_decision_get_request(decision));
80        break;
81    case PROP_FRAME_NAME:
82        g_value_set_string(value, webkit_navigation_policy_decision_get_frame_name(decision));
83        break;
84    default:
85        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
86        break;
87    }
88}
89
90static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyDecisionClass* decisionClass)
91{
92    GObjectClass* objectClass = G_OBJECT_CLASS(decisionClass);
93    objectClass->get_property = webkitNavigationPolicyDecisionGetProperty;
94
95    /**
96     * WebKitNavigationPolicyDecision:navigation-type:
97     *
98     * The type of navigation that triggered this policy decision. This is
99     * useful for enacting different policies depending on what type of user
100     * action caused the navigation.
101     */
102    g_object_class_install_property(objectClass,
103                                    PROP_NAVIGATION_TYPE,
104                                    g_param_spec_enum("navigation-type",
105                                                      _("Navigation type"),
106                                                      _("The type of navigation triggering this decision"),
107                                                      WEBKIT_TYPE_NAVIGATION_TYPE,
108                                                      WEBKIT_NAVIGATION_TYPE_LINK_CLICKED,
109                                                      WEBKIT_PARAM_READABLE));
110
111    /**
112     * WebKitNavigationPolicyDecision:mouse-button:
113     *
114     * If the navigation associated with this policy decision was originally
115     * triggered by a mouse event, this property contains non-zero button number
116     * of the button triggering that event. The button numbers match those from GDK.
117     * If the navigation was not triggered by a mouse event, the value of this
118     * property will be 0.
119     */
120    g_object_class_install_property(objectClass,
121                                    PROP_MOUSE_BUTTON,
122                                    g_param_spec_uint("mouse-button",
123                                                      _("Mouse button"),
124                                                      _("The mouse button used if this decision was triggered by a mouse event"),
125                                                      0, G_MAXUINT, 0,
126                                                      WEBKIT_PARAM_READABLE));
127
128    /**
129     * WebKitNavigationPolicyDecision:modifiers:
130     *
131     * If the navigation associated with this policy decision was originally
132     * triggered by a mouse event, this property contains a bitmask of various
133     * #GdkModifierType values describing the modifiers used for that click.
134     * If the navigation was not triggered by a mouse event or no modifiers
135     * were active, the value of this property will be zero.
136     */
137    g_object_class_install_property(objectClass,
138                                    PROP_MODIFIERS,
139                                    g_param_spec_uint("modifiers",
140                                                      _("Mouse event modifiers"),
141                                                      _("The modifiers active if this decision was triggered by a mouse event"),
142                                                      0, G_MAXUINT, 0,
143                                                      WEBKIT_PARAM_READABLE));
144
145    /**
146     * WebKitNavigationPolicyDecision:request:
147     *
148     * This property contains the #WebKitURIRequest associated with this
149     * navigation.
150     */
151    g_object_class_install_property(objectClass,
152                                    PROP_REQUEST,
153                                    g_param_spec_object("request",
154                                                      _("Navigation URI request"),
155                                                      _("The URI request that is associated with this navigation"),
156                                                      WEBKIT_TYPE_URI_REQUEST,
157                                                      WEBKIT_PARAM_READABLE));
158
159    /**
160     * WebKitNavigationPolicyDecision:frame-name:
161     *
162     * If this navigation request targets a new frame, this property contains
163     * the name of that frame. For example if the decision was triggered by clicking a
164     * link with a target attribute equal to "_blank", this property will contain the
165     * value of that attribute. In all other cases, this value will be %NULL.
166     */
167    g_object_class_install_property(objectClass,
168                                    PROP_FRAME_NAME,
169                                    g_param_spec_string("frame-name",
170                                                      _("Frame name"),
171                                                      _("The name of the new frame this navigation action targets"),
172                                                      0,
173                                                      WEBKIT_PARAM_READABLE));
174}
175
176/**
177 * webkit_navigation_policy_decision_get_navigation_type:
178 * @decision: a #WebKitNavigationPolicyDecision
179 *
180 * Gets the value of the #WebKitNavigationPolicyDecision:navigation-type property.
181 *
182 * Returns: The type of navigation triggering this policy decision.
183 */
184WebKitNavigationType webkit_navigation_policy_decision_get_navigation_type(WebKitNavigationPolicyDecision* decision)
185{
186    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), WEBKIT_NAVIGATION_TYPE_OTHER);
187    return decision->priv->navigationType;
188}
189
190/**
191 * webkit_navigation_policy_decision_get_mouse_button:
192 * @decision: a #WebKitNavigationPolicyDecision
193 *
194 * Gets the value of the #WebKitNavigationPolicyDecision:mouse-button property.
195 *
196 * Returns: The mouse button used if this decision was triggered by a mouse event or 0 otherwise
197 */
198guint webkit_navigation_policy_decision_get_mouse_button(WebKitNavigationPolicyDecision* decision)
199{
200    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
201    return decision->priv->mouseButton;
202}
203
204/**
205 * webkit_navigation_policy_decision_get_modifiers:
206 * @decision: a #WebKitNavigationPolicyDecision
207 *
208 * Gets the value of the #WebKitNavigationPolicyDecision:modifiers property.
209 *
210 * Returns: The modifiers active if this decision was triggered by a mouse event
211 */
212unsigned webkit_navigation_policy_decision_get_modifiers(WebKitNavigationPolicyDecision* decision)
213{
214    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
215    return decision->priv->modifiers;
216}
217
218/**
219 * webkit_navigation_policy_decision_get_request:
220 * @decision: a #WebKitNavigationPolicyDecision
221 *
222 * Gets the value of the #WebKitNavigationPolicyDecision:request property.
223 *
224 * Returns: (transfer none): The URI request that is associated with this navigation
225 */
226WebKitURIRequest* webkit_navigation_policy_decision_get_request(WebKitNavigationPolicyDecision* decision)
227{
228    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
229    return decision->priv->request.get();
230}
231
232/**
233 * webkit_navigation_policy_decision_get_frame_name:
234 * @decision: a #WebKitNavigationPolicyDecision
235 *
236 * Gets the value of the #WebKitNavigationPolicyDecision:frame-name property.
237 *
238 * Returns: The name of the new frame this navigation action targets or %NULL
239 */
240const char* webkit_navigation_policy_decision_get_frame_name(WebKitNavigationPolicyDecision* decision)
241{
242    g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
243    return decision->priv->frameName.data();
244}
245
246COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_LINK_CLICKED, NavigationTypeLinkClicked);
247COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED, NavigationTypeFormSubmitted);
248COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_BACK_FORWARD, NavigationTypeBackForward);
249COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_RELOAD, NavigationTypeReload);
250COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED, NavigationTypeFormResubmitted);
251COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_OTHER, NavigationTypeOther);
252
253WebKitNavigationPolicyDecision* webkitNavigationPolicyDecisionCreate(WebKitNavigationType navigationType, unsigned mouseButton, unsigned modifiers, WebURLRequest* request, const char* frameName, WebFramePolicyListenerProxy* listener)
254{
255    WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(g_object_new(WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, NULL));
256    decision->priv->navigationType = navigationType;
257    decision->priv->mouseButton = mouseButton;
258    decision->priv->modifiers = modifiers;
259    decision->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request->resourceRequest()));
260    decision->priv->frameName = frameName;
261    webkitPolicyDecisionSetListener(WEBKIT_POLICY_DECISION(decision), listener);
262    return decision;
263}
264