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 "WebKitEnumTypes.h"
24#include "WebKitNavigationActionPrivate.h"
25#include "WebKitNavigationPolicyDecisionPrivate.h"
26#include "WebKitPolicyDecisionPrivate.h"
27#include "WebKitURIRequestPrivate.h"
28#include <glib/gi18n-lib.h>
29#include <wtf/glib/GRefPtr.h>
30#include <wtf/glib/WTFGType.h>
31#include <wtf/text/CString.h>
32
33using namespace WebKit;
34using namespace WebCore;
35
36/**
37 * SECTION: WebKitNavigationPolicyDecision
38 * @Short_description: A policy decision for navigation actions
39 * @Title: WebKitNavigationPolicyDecision
40 * @See_also: #WebKitPolicyDecision, #WebKitWebView
41 *
42 * WebKitNavigationPolicyDecision represents a policy decision for events associated with
43 * navigations. If the value of #WebKitNavigationPolicyDecision:mouse-button is not 0, then
44 * the navigation was triggered by a mouse event.
45 */
46
47struct _WebKitNavigationPolicyDecisionPrivate {
48 ~_WebKitNavigationPolicyDecisionPrivate()
49 {
50 webkit_navigation_action_free(navigationAction);
51 }
52
53 WebKitNavigationAction* navigationAction;
54 CString frameName;
55};
56
57WEBKIT_DEFINE_TYPE(WebKitNavigationPolicyDecision, webkit_navigation_policy_decision, WEBKIT_TYPE_POLICY_DECISION)
58
59enum {
60 PROP_0,
61 PROP_NAVIGATION_ACTION,
62#if PLATFORM(GTK)
63 PROP_NAVIGATION_TYPE,
64 PROP_MOUSE_BUTTON,
65 PROP_MODIFIERS,
66 PROP_REQUEST,
67#endif
68 PROP_FRAME_NAME,
69};
70
71static void webkitNavigationPolicyDecisionGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
72{
73 WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(object);
74 switch (propId) {
75 case PROP_NAVIGATION_ACTION:
76 g_value_set_boxed(value, webkit_navigation_policy_decision_get_navigation_action(decision));
77 break;
78#if PLATFORM(GTK)
79 case PROP_NAVIGATION_TYPE:
80 g_value_set_enum(value, webkit_navigation_action_get_navigation_type(decision->priv->navigationAction));
81 break;
82 case PROP_MOUSE_BUTTON:
83 g_value_set_enum(value, webkit_navigation_action_get_mouse_button(decision->priv->navigationAction));
84 break;
85 case PROP_MODIFIERS:
86 g_value_set_uint(value, webkit_navigation_action_get_modifiers(decision->priv->navigationAction));
87 break;
88 case PROP_REQUEST:
89 g_value_set_object(value, webkit_navigation_action_get_request(decision->priv->navigationAction));
90 break;
91#endif
92 case PROP_FRAME_NAME:
93 g_value_set_string(value, webkit_navigation_policy_decision_get_frame_name(decision));
94 break;
95 default:
96 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
97 break;
98 }
99}
100
101static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyDecisionClass* decisionClass)
102{
103 GObjectClass* objectClass = G_OBJECT_CLASS(decisionClass);
104 objectClass->get_property = webkitNavigationPolicyDecisionGetProperty;
105
106 /**
107 * WebKitNavigationPolicyDecision:navigation-action:
108 *
109 * The #WebKitNavigationAction that triggered this policy decision.
110 *
111 * Since: 2.6
112 */
113 g_object_class_install_property(
114 objectClass,
115 PROP_NAVIGATION_ACTION,
116 g_param_spec_boxed(
117 "navigation-action",
118 _("Navigation action"),
119 _("The WebKitNavigationAction triggering this decision"),
120 WEBKIT_TYPE_NAVIGATION_ACTION,
121 WEBKIT_PARAM_READABLE));
122
123#if PLATFORM(GTK)
124 /**
125 * WebKitNavigationPolicyDecision:navigation-type:
126 *
127 * The type of navigation that triggered this policy decision. This is
128 * useful for enacting different policies depending on what type of user
129 * action caused the navigation.
130 *
131 * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead
132 */
133 g_object_class_install_property(objectClass,
134 PROP_NAVIGATION_TYPE,
135 g_param_spec_enum("navigation-type",
136 _("Navigation type"),
137 _("The type of navigation triggering this decision"),
138 WEBKIT_TYPE_NAVIGATION_TYPE,
139 WEBKIT_NAVIGATION_TYPE_LINK_CLICKED,
140 WEBKIT_PARAM_READABLE));
141
142 /**
143 * WebKitNavigationPolicyDecision:mouse-button:
144 *
145 * If the navigation associated with this policy decision was originally
146 * triggered by a mouse event, this property contains non-zero button number
147 * of the button triggering that event. The button numbers match those from GDK.
148 * If the navigation was not triggered by a mouse event, the value of this
149 * property will be 0.
150 *
151 * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead
152 */
153 g_object_class_install_property(objectClass,
154 PROP_MOUSE_BUTTON,
155 g_param_spec_uint("mouse-button",
156 _("Mouse button"),
157 _("The mouse button used if this decision was triggered by a mouse event"),
158 0, G_MAXUINT, 0,
159 WEBKIT_PARAM_READABLE));
160
161 /**
162 * WebKitNavigationPolicyDecision:modifiers:
163 *
164 * If the navigation associated with this policy decision was originally
165 * triggered by a mouse event, this property contains a bitmask of various
166 * #GdkModifierType values describing the modifiers used for that click.
167 * If the navigation was not triggered by a mouse event or no modifiers
168 * were active, the value of this property will be zero.
169 *
170 * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead
171 */
172 g_object_class_install_property(objectClass,
173 PROP_MODIFIERS,
174 g_param_spec_uint("modifiers",
175 _("Mouse event modifiers"),
176 _("The modifiers active if this decision was triggered by a mouse event"),
177 0, G_MAXUINT, 0,
178 WEBKIT_PARAM_READABLE));
179
180 /**
181 * WebKitNavigationPolicyDecision:request:
182 *
183 * This property contains the #WebKitURIRequest associated with this
184 * navigation.
185 *
186 * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead
187 */
188 g_object_class_install_property(objectClass,
189 PROP_REQUEST,
190 g_param_spec_object("request",
191 _("Navigation URI request"),
192 _("The URI request that is associated with this navigation"),
193 WEBKIT_TYPE_URI_REQUEST,
194 WEBKIT_PARAM_READABLE));
195#endif
196
197 /**
198 * WebKitNavigationPolicyDecision:frame-name:
199 *
200 * If this navigation request targets a new frame, this property contains
201 * the name of that frame. For example if the decision was triggered by clicking a
202 * link with a target attribute equal to "_blank", this property will contain the
203 * value of that attribute. In all other cases, this value will be %NULL.
204 */
205 g_object_class_install_property(objectClass,
206 PROP_FRAME_NAME,
207 g_param_spec_string("frame-name",
208 _("Frame name"),
209 _("The name of the new frame this navigation action targets"),
210 0,
211 WEBKIT_PARAM_READABLE));
212}
213
214/**
215 * webkit_navigation_policy_decision_get_navigation_action:
216 * @decision: a #WebKitNavigationPolicyDecision
217 *
218 * Gets the value of the #WebKitNavigationPolicyDecision:navigation-action property.
219 *
220 * Returns: (transfer none): The #WebKitNavigationAction triggering this policy decision.
221 *
222 * Since: 2.6
223 */
224WebKitNavigationAction* webkit_navigation_policy_decision_get_navigation_action(WebKitNavigationPolicyDecision* decision)
225{
226 g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), nullptr);
227 return decision->priv->navigationAction;
228}
229
230#if PLATFORM(GTK)
231/**
232 * webkit_navigation_policy_decision_get_navigation_type:
233 * @decision: a #WebKitNavigationPolicyDecision
234 *
235 * Gets the value of the #WebKitNavigationPolicyDecision:navigation-type property.
236 *
237 * Returns: The type of navigation triggering this policy decision.
238 *
239 * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead.
240 */
241WebKitNavigationType webkit_navigation_policy_decision_get_navigation_type(WebKitNavigationPolicyDecision* decision)
242{
243 g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), WEBKIT_NAVIGATION_TYPE_OTHER);
244 return webkit_navigation_action_get_navigation_type(decision->priv->navigationAction);
245}
246
247/**
248 * webkit_navigation_policy_decision_get_mouse_button:
249 * @decision: a #WebKitNavigationPolicyDecision
250 *
251 * Gets the value of the #WebKitNavigationPolicyDecision:mouse-button property.
252 *
253 * Returns: The mouse button used if this decision was triggered by a mouse event or 0 otherwise
254 *
255 * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead.
256 */
257guint webkit_navigation_policy_decision_get_mouse_button(WebKitNavigationPolicyDecision* decision)
258{
259 g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
260 return webkit_navigation_action_get_mouse_button(decision->priv->navigationAction);
261}
262
263/**
264 * webkit_navigation_policy_decision_get_modifiers:
265 * @decision: a #WebKitNavigationPolicyDecision
266 *
267 * Gets the value of the #WebKitNavigationPolicyDecision:modifiers property.
268 *
269 * Returns: The modifiers active if this decision was triggered by a mouse event
270 *
271 * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead.
272 */
273unsigned webkit_navigation_policy_decision_get_modifiers(WebKitNavigationPolicyDecision* decision)
274{
275 g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0);
276 return webkit_navigation_action_get_modifiers(decision->priv->navigationAction);
277}
278
279/**
280 * webkit_navigation_policy_decision_get_request:
281 * @decision: a #WebKitNavigationPolicyDecision
282 *
283 * Gets the value of the #WebKitNavigationPolicyDecision:request property.
284 *
285 * Returns: (transfer none): The URI request that is associated with this navigation
286 *
287 * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead.
288 */
289WebKitURIRequest* webkit_navigation_policy_decision_get_request(WebKitNavigationPolicyDecision* decision)
290{
291 g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), nullptr);
292 return webkit_navigation_action_get_request(decision->priv->navigationAction);
293}
294#endif
295
296/**
297 * webkit_navigation_policy_decision_get_frame_name:
298 * @decision: a #WebKitNavigationPolicyDecision
299 *
300 * Gets the value of the #WebKitNavigationPolicyDecision:frame-name property.
301 *
302 * Returns: The name of the new frame this navigation action targets or %NULL
303 */
304const char* webkit_navigation_policy_decision_get_frame_name(WebKitNavigationPolicyDecision* decision)
305{
306 g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), nullptr);
307 // FIXME: frame name should also be moved to WebKitNavigationAction and this method deprecated.
308 return decision->priv->frameName.data();
309}
310
311WebKitPolicyDecision* webkitNavigationPolicyDecisionCreate(Ref<API::NavigationAction>&& navigationAction, Ref<WebFramePolicyListenerProxy>&& listener)
312{
313 WebKitNavigationPolicyDecision* navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION(g_object_new(WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, nullptr));
314 // FIXME: frame name should also be moved to WebKitNavigationAction.
315 auto targetFrameName = navigationAction->targetFrameName();
316 navigationDecision->priv->navigationAction = webkitNavigationActionCreate(WTFMove(navigationAction));
317 if (targetFrameName)
318 navigationDecision->priv->frameName = targetFrameName->utf8();
319 WebKitPolicyDecision* decision = WEBKIT_POLICY_DECISION(navigationDecision);
320 webkitPolicyDecisionSetListener(decision, WTFMove(listener));
321 return decision;
322}
323