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