1 /*
2 * Copyright (C) 2008 Collabora Ltd.
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
22 #include <wtf/Assertions.h>
23 #include "FrameLoaderTypes.h"
24
25 #include <glib/gi18n-lib.h>
26 #include "webkitwebnavigationaction.h"
27 #include "webkitprivate.h"
28 #include "webkitenumtypes.h"
29
30 #include <string.h>
31
32 static void webkit_web_navigation_action_set_target_frame(WebKitWebNavigationAction* navigationAction, const gchar* targetFrame);
33
34 /**
35 * SECTION:webkitwebnavigationaction
36 * @short_description: Object used to report details of navigation actions
37 *
38 * #WebKitWebNavigationAction is used in signals to provide details about
39 * what led the navigation to happen. This includes, for instance, if the user
40 * clicked a link to start that navigation, and what mouse button was used.
41 */
42
43 struct _WebKitWebNavigationActionPrivate {
44 WebKitWebNavigationReason reason;
45 gchar* originalUri;
46 gint button;
47 gint modifier_state;
48 gchar* targetFrame;
49 };
50
51 #define WEBKIT_WEB_NAVIGATION_ACTION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_NAVIGATION_ACTION, WebKitWebNavigationActionPrivate))
52
53 enum {
54 PROP_0,
55
56 PROP_REASON,
57 PROP_ORIGINAL_URI,
58 PROP_BUTTON,
59 PROP_MODIFIER_STATE,
60 PROP_TARGET_FRAME
61 };
62
G_DEFINE_TYPE(WebKitWebNavigationAction,webkit_web_navigation_action,G_TYPE_OBJECT)63 G_DEFINE_TYPE(WebKitWebNavigationAction, webkit_web_navigation_action, G_TYPE_OBJECT)
64
65
66 static void webkit_web_navigation_action_get_property(GObject* object, guint propertyId, GValue* value, GParamSpec* pspec)
67 {
68 WebKitWebNavigationAction* navigationAction = WEBKIT_WEB_NAVIGATION_ACTION(object);
69
70 switch(propertyId) {
71 case PROP_REASON:
72 g_value_set_enum(value, webkit_web_navigation_action_get_reason(navigationAction));
73 break;
74 case PROP_ORIGINAL_URI:
75 g_value_set_string(value, webkit_web_navigation_action_get_original_uri(navigationAction));
76 break;
77 case PROP_BUTTON:
78 g_value_set_int(value, webkit_web_navigation_action_get_button(navigationAction));
79 break;
80 case PROP_MODIFIER_STATE:
81 g_value_set_int(value, webkit_web_navigation_action_get_modifier_state(navigationAction));
82 break;
83 case PROP_TARGET_FRAME:
84 g_value_set_string(value, webkit_web_navigation_action_get_target_frame(navigationAction));
85 break;
86 default:
87 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
88 break;
89 }
90 }
91
webkit_web_navigation_action_set_property(GObject * object,guint propertyId,const GValue * value,GParamSpec * pspec)92 static void webkit_web_navigation_action_set_property(GObject* object, guint propertyId, const GValue* value, GParamSpec* pspec)
93 {
94 WebKitWebNavigationAction* navigationAction = WEBKIT_WEB_NAVIGATION_ACTION(object);
95 WebKitWebNavigationActionPrivate* priv = navigationAction->priv;
96
97 switch(propertyId) {
98 case PROP_REASON:
99 webkit_web_navigation_action_set_reason(navigationAction, (WebKitWebNavigationReason)g_value_get_enum(value));
100 break;
101 case PROP_ORIGINAL_URI:
102 webkit_web_navigation_action_set_original_uri(navigationAction, g_value_get_string(value));
103 break;
104 case PROP_BUTTON:
105 priv->button = g_value_get_int(value);
106 break;
107 case PROP_MODIFIER_STATE:
108 priv->modifier_state = g_value_get_int(value);
109 break;
110 case PROP_TARGET_FRAME:
111 webkit_web_navigation_action_set_target_frame(navigationAction, g_value_get_string(value));
112 break;
113 default:
114 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
115 break;
116 }
117 }
118
webkit_web_navigation_action_init(WebKitWebNavigationAction * navigationAction)119 static void webkit_web_navigation_action_init(WebKitWebNavigationAction* navigationAction)
120 {
121 navigationAction->priv = WEBKIT_WEB_NAVIGATION_ACTION_GET_PRIVATE(navigationAction);
122 }
123
webkit_web_navigation_action_finalize(GObject * obj)124 static void webkit_web_navigation_action_finalize(GObject* obj)
125 {
126 WebKitWebNavigationAction* navigationAction = WEBKIT_WEB_NAVIGATION_ACTION(obj);
127 WebKitWebNavigationActionPrivate* priv = navigationAction->priv;
128
129 g_free(priv->originalUri);
130
131 G_OBJECT_CLASS(webkit_web_navigation_action_parent_class)->finalize(obj);
132 }
133
webkit_web_navigation_action_class_init(WebKitWebNavigationActionClass * requestClass)134 static void webkit_web_navigation_action_class_init(WebKitWebNavigationActionClass* requestClass)
135 {
136 GObjectClass* objectClass = G_OBJECT_CLASS(requestClass);
137
138 COMPILE_ASSERT(static_cast<int>(WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED) == static_cast<int>(WebCore::NavigationTypeLinkClicked), navigation_type_link_clicked_enum_match);
139 COMPILE_ASSERT(static_cast<int>(WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED) == static_cast<int>(WebCore::NavigationTypeFormSubmitted), navigation_type_form_submitted_enum_match);
140 COMPILE_ASSERT(static_cast<int>(WEBKIT_WEB_NAVIGATION_REASON_BACK_FORWARD) == static_cast<int>(WebCore::NavigationTypeBackForward), navigation_type_back_forward_enum_match);
141 COMPILE_ASSERT(static_cast<int>(WEBKIT_WEB_NAVIGATION_REASON_RELOAD) == static_cast<int>(WebCore::NavigationTypeReload), navigation_type_reload_enum_match);
142 COMPILE_ASSERT(static_cast<int>(WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED) == static_cast<int>(WebCore::NavigationTypeFormResubmitted), navigation_type_form_resubmitted_enum_match);
143 COMPILE_ASSERT(static_cast<int>(WEBKIT_WEB_NAVIGATION_REASON_OTHER) == static_cast<int>(WebCore::NavigationTypeOther), navigation_type_other_enum_match);
144
145 objectClass->get_property = webkit_web_navigation_action_get_property;
146 objectClass->set_property = webkit_web_navigation_action_set_property;
147 objectClass->dispose = webkit_web_navigation_action_finalize;
148
149 /**
150 * WebKitWebNavigationAction:reason:
151 *
152 * The reason why this navigation is occuring.
153 *
154 * Since: 1.0.3
155 */
156 g_object_class_install_property(objectClass, PROP_REASON,
157 g_param_spec_enum("reason",
158 _("Reason"),
159 _("The reason why this navigation is occurring"),
160 WEBKIT_TYPE_WEB_NAVIGATION_REASON,
161 WEBKIT_WEB_NAVIGATION_REASON_OTHER,
162 (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
163
164 /**
165 * WebKitWebNavigationAction:original-uri:
166 *
167 * The URI that was requested as the target for the navigation.
168 *
169 * Since: 1.0.3
170 */
171 g_object_class_install_property(objectClass, PROP_ORIGINAL_URI,
172 g_param_spec_string("original-uri",
173 _("Original URI"),
174 _("The URI that was requested as the target for the navigation"),
175 "",
176 (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
177 /**
178 * WebKitWebNavigationAction:button:
179 *
180 * The DOM identifier for the mouse button used to click. DOM button values
181 * are 0, 1 and 2 for left, middle and right buttons. If the action was not
182 * initiated by a mouse click the value will be -1.
183 *
184 * Since: 1.0.3
185 */
186 g_object_class_install_property(objectClass, PROP_BUTTON,
187 g_param_spec_int("button",
188 _("Button"),
189 _("The button used to click"),
190 -1,
191 G_MAXINT,
192 -1,
193 (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
194
195 /**
196 * WebKitWebNavigationAction:modifier-state:
197 *
198 * The state of the modifier keys when the action was requested.
199 *
200 * Since: 1.0.3
201 */
202 g_object_class_install_property(objectClass, PROP_MODIFIER_STATE,
203 g_param_spec_int("modifier-state",
204 _("Modifier state"),
205 _("A bitmask representing the state of the modifier keys"),
206 0,
207 G_MAXINT,
208 0,
209 (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
210
211 /**
212 * WebKitWebNavigationAction:target-frame:
213 *
214 * The target frame for the navigation.
215 *
216 * Since: 1.1.13
217 */
218 g_object_class_install_property(objectClass, PROP_TARGET_FRAME,
219 g_param_spec_string("target-frame",
220 _("Target frame"),
221 _("The target frame for the navigation"),
222 NULL,
223 (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
224
225
226
227 g_type_class_add_private(requestClass, sizeof(WebKitWebNavigationActionPrivate));
228 }
229
230 /**
231 * webkit_web_navigation_action_get_reason:
232 * @navigationAction: a #WebKitWebNavigationAction
233 *
234 * Returns the reason why WebKit is requesting a navigation.
235 *
236 * Return value: a #WebKitWebNavigationReason
237 *
238 * Since: 1.0.3
239 */
webkit_web_navigation_action_get_reason(WebKitWebNavigationAction * navigationAction)240 WebKitWebNavigationReason webkit_web_navigation_action_get_reason(WebKitWebNavigationAction* navigationAction)
241 {
242 g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), WEBKIT_WEB_NAVIGATION_REASON_OTHER);
243
244 return navigationAction->priv->reason;
245 }
246
247 /**
248 * webkit_web_navigation_action_set_reason:
249 * @navigationAction: a #WebKitWebNavigationAction
250 * @reason: a #WebKitWebNavigationReason
251 *
252 * Sets the reason why WebKit is requesting a navigation.
253 *
254 * Since: 1.0.3
255 */
webkit_web_navigation_action_set_reason(WebKitWebNavigationAction * navigationAction,WebKitWebNavigationReason reason)256 void webkit_web_navigation_action_set_reason(WebKitWebNavigationAction* navigationAction, WebKitWebNavigationReason reason)
257 {
258 g_return_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction));
259
260 if (navigationAction->priv->reason == reason)
261 return;
262
263 navigationAction->priv->reason = reason;
264 g_object_notify(G_OBJECT(navigationAction), "reason");
265 }
266
267 /**
268 * webkit_web_navigation_action_get_original_uri:
269 * @navigationAction: a #WebKitWebNavigationAction
270 *
271 * Returns the URI that was originally requested. This may differ from the
272 * navigation target, for instance because of a redirect.
273 *
274 * Return value: the originally requested URI
275 *
276 * Since: 1.0.3
277 */
webkit_web_navigation_action_get_original_uri(WebKitWebNavigationAction * navigationAction)278 const gchar* webkit_web_navigation_action_get_original_uri(WebKitWebNavigationAction* navigationAction)
279 {
280 g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), NULL);
281
282 return navigationAction->priv->originalUri;
283 }
284
285 /**
286 * webkit_web_navigation_action_set_original_uri:
287 * @navigationAction: a #WebKitWebNavigationAction
288 * @originalUri: a URI
289 *
290 * Sets the URI that was originally requested. This may differ from the
291 * navigation target, for instance because of a redirect.
292 *
293 * Since: 1.0.3
294 */
webkit_web_navigation_action_set_original_uri(WebKitWebNavigationAction * navigationAction,const gchar * originalUri)295 void webkit_web_navigation_action_set_original_uri(WebKitWebNavigationAction* navigationAction, const gchar* originalUri)
296 {
297 g_return_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction));
298 g_return_if_fail(originalUri);
299
300 if (navigationAction->priv->originalUri &&
301 (!strcmp(navigationAction->priv->originalUri, originalUri)))
302 return;
303
304 g_free(navigationAction->priv->originalUri);
305 navigationAction->priv->originalUri = g_strdup(originalUri);
306 g_object_notify(G_OBJECT(navigationAction), "original-uri");
307 }
308
309 /**
310 * webkit_web_navigation_action_get_button:
311 * @navigationAction: a #WebKitWebNavigationAction
312 *
313 * Returns the DOM identifier for the mouse button used to click.
314 * DOM button values are 0, 1 and 2 for left, middle and right buttons.
315 * If the action was not initiated by a mouse click, returns -1.
316 *
317 * Return value: the mouse button used to click
318 *
319 * Since: 1.0.3
320 */
webkit_web_navigation_action_get_button(WebKitWebNavigationAction * navigationAction)321 gint webkit_web_navigation_action_get_button(WebKitWebNavigationAction* navigationAction)
322 {
323 g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), -1);
324
325 return navigationAction->priv->button;
326 }
327
328 /**
329 * webkit_web_navigation_action_get_modifier_state:
330 * @navigationAction: a #WebKitWebNavigationAction
331 *
332 * Returns a bitmask with the the state of the modifier keys.
333 *
334 * Return value: a bitmask with the state of the modifier keys
335 *
336 * Since: 1.0.3
337 */
webkit_web_navigation_action_get_modifier_state(WebKitWebNavigationAction * navigationAction)338 gint webkit_web_navigation_action_get_modifier_state(WebKitWebNavigationAction* navigationAction)
339 {
340 g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), 0);
341
342 return navigationAction->priv->modifier_state;
343 }
344
345 /**
346 * webkit_web_navigation_action_get_target_frame:
347 * @navigationAction: a #WebKitWebNavigationAction
348 *
349 * Returns the target frame of the action.
350 *
351 * Return value: the target frame of the action or NULL
352 * if there is no target.
353 *
354 * Since: 1.1.13
355 */
webkit_web_navigation_action_get_target_frame(WebKitWebNavigationAction * navigationAction)356 G_CONST_RETURN gchar* webkit_web_navigation_action_get_target_frame(WebKitWebNavigationAction* navigationAction)
357 {
358 g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), NULL);
359
360 return navigationAction->priv->targetFrame;
361 }
362
webkit_web_navigation_action_set_target_frame(WebKitWebNavigationAction * navigationAction,const gchar * targetFrame)363 static void webkit_web_navigation_action_set_target_frame(WebKitWebNavigationAction* navigationAction, const gchar* targetFrame)
364 {
365 if (!g_strcmp0(navigationAction->priv->targetFrame, targetFrame))
366 return;
367
368 g_free(navigationAction->priv->targetFrame);
369 navigationAction->priv->targetFrame = g_strdup(targetFrame);
370 g_object_notify(G_OBJECT(navigationAction), "target-frame");
371 }
372