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
127    G_OBJECT_CLASS(webkit_web_navigation_action_parent_class)->finalize(obj);
128}
129
130static void webkit_web_navigation_action_class_init(WebKitWebNavigationActionClass* requestClass)
131{
132    GObjectClass* objectClass = G_OBJECT_CLASS(requestClass);
133
134    objectClass->get_property = webkit_web_navigation_action_get_property;
135    objectClass->set_property = webkit_web_navigation_action_set_property;
136    objectClass->dispose = webkit_web_navigation_action_finalize;
137
138    /**
139     * WebKitWebNavigationAction:reason:
140     *
141     * The reason why this navigation is occuring.
142     *
143     * Since: 1.0.3
144     */
145    g_object_class_install_property(objectClass, PROP_REASON,
146                                    g_param_spec_enum("reason",
147                                                      _("Reason"),
148                                                      _("The reason why this navigation is occurring"),
149                                                      WEBKIT_TYPE_WEB_NAVIGATION_REASON,
150                                                      WEBKIT_WEB_NAVIGATION_REASON_OTHER,
151                                                      (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
152
153    /**
154     * WebKitWebNavigationAction:original-uri:
155     *
156     * The URI that was requested as the target for the navigation.
157     *
158     * Since: 1.0.3
159     */
160    g_object_class_install_property(objectClass, PROP_ORIGINAL_URI,
161                                    g_param_spec_string("original-uri",
162                                                        _("Original URI"),
163                                                        _("The URI that was requested as the target for the navigation"),
164                                                        "",
165                                                        (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
166    /**
167     * WebKitWebNavigationAction:button:
168     *
169     * The GTK+ identifier for the mouse button used to click. Notice that GTK+ button values
170     * are 1, 2 and 3 for left, middle and right buttons, so they are DOM button values +1. If the action was not
171     * initiated by a mouse click the value will be -1.
172     *
173     * Since: 1.0.3
174     */
175    g_object_class_install_property(objectClass, PROP_BUTTON,
176                                    g_param_spec_int("button",
177                                                     _("Button"),
178                                                     _("The button used to click"),
179                                                     -1,
180                                                     G_MAXINT,
181                                                     -1,
182                                                     (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
183
184    /**
185     * WebKitWebNavigationAction:modifier-state:
186     *
187     * The state of the modifier keys when the action was requested.
188     *
189     * Since: 1.0.3
190     */
191    g_object_class_install_property(objectClass, PROP_MODIFIER_STATE,
192                                    g_param_spec_int("modifier-state",
193                                                     _("Modifier state"),
194                                                     _("A bitmask representing the state of the modifier keys"),
195                                                     0,
196                                                     G_MAXINT,
197                                                     0,
198                                                     (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
199
200    /**
201     * WebKitWebNavigationAction:target-frame:
202     *
203     * The target frame for the navigation.
204     *
205     * Since: 1.1.13
206     */
207    g_object_class_install_property(objectClass, PROP_TARGET_FRAME,
208                                    g_param_spec_string("target-frame",
209                                                        _("Target frame"),
210                                                        _("The target frame for the navigation"),
211                                                        NULL,
212                                                        (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
213
214
215
216    g_type_class_add_private(requestClass, sizeof(WebKitWebNavigationActionPrivate));
217}
218
219/**
220 * webkit_web_navigation_action_get_reason:
221 * @navigationAction: a #WebKitWebNavigationAction
222 *
223 * Returns the reason why WebKit is requesting a navigation.
224 *
225 * Return value: a #WebKitWebNavigationReason
226 *
227 * Since: 1.0.3
228 */
229WebKitWebNavigationReason webkit_web_navigation_action_get_reason(WebKitWebNavigationAction* navigationAction)
230{
231    g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), WEBKIT_WEB_NAVIGATION_REASON_OTHER);
232
233    return navigationAction->priv->reason;
234}
235
236/**
237 * webkit_web_navigation_action_set_reason:
238 * @navigationAction: a #WebKitWebNavigationAction
239 * @reason: a #WebKitWebNavigationReason
240 *
241 * Sets the reason why WebKit is requesting a navigation.
242 *
243 * Since: 1.0.3
244 */
245void webkit_web_navigation_action_set_reason(WebKitWebNavigationAction* navigationAction, WebKitWebNavigationReason reason)
246{
247    g_return_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction));
248
249    if (navigationAction->priv->reason == reason)
250        return;
251
252    navigationAction->priv->reason = reason;
253    g_object_notify(G_OBJECT(navigationAction), "reason");
254}
255
256/**
257 * webkit_web_navigation_action_get_original_uri:
258 * @navigationAction: a #WebKitWebNavigationAction
259 *
260 * Returns the URI that was originally requested. This may differ from the
261 * navigation target, for instance because of a redirect.
262 *
263 * Return value: the originally requested URI
264 *
265 * Since: 1.0.3
266 */
267const gchar* webkit_web_navigation_action_get_original_uri(WebKitWebNavigationAction* navigationAction)
268{
269    g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), NULL);
270
271    return navigationAction->priv->originalUri;
272}
273
274/**
275 * webkit_web_navigation_action_set_original_uri:
276 * @navigationAction: a #WebKitWebNavigationAction
277 * @originalUri: a URI
278 *
279 * Sets the URI that was originally requested. This may differ from the
280 * navigation target, for instance because of a redirect.
281 *
282 * Since: 1.0.3
283 */
284void webkit_web_navigation_action_set_original_uri(WebKitWebNavigationAction* navigationAction, const gchar* originalUri)
285{
286    g_return_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction));
287    g_return_if_fail(originalUri);
288
289    if (navigationAction->priv->originalUri &&
290        (!strcmp(navigationAction->priv->originalUri, originalUri)))
291        return;
292
293    g_free(navigationAction->priv->originalUri);
294    navigationAction->priv->originalUri = g_strdup(originalUri);
295    g_object_notify(G_OBJECT(navigationAction), "original-uri");
296}
297
298/**
299 * webkit_web_navigation_action_get_button:
300 * @navigationAction: a #WebKitWebNavigationAction
301 *
302 * The GTK+ identifier for the mouse button used to click. Notice that GTK+ button values
303 * are 1, 2 and 3 for left, middle and right buttons, so they are DOM button values +1. If the action was not
304 * initiated by a mouse click the value will be -1.
305 *
306 * Return value: the mouse button used to click
307 *
308 * Since: 1.0.3
309 */
310gint webkit_web_navigation_action_get_button(WebKitWebNavigationAction* navigationAction)
311{
312    g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), -1);
313
314    return navigationAction->priv->button;
315}
316
317/**
318 * webkit_web_navigation_action_get_modifier_state:
319 * @navigationAction: a #WebKitWebNavigationAction
320 *
321 * Returns a bitmask with the the state of the modifier keys.
322 *
323 * Return value: a bitmask with the state of the modifier keys
324 *
325 * Since: 1.0.3
326 */
327gint webkit_web_navigation_action_get_modifier_state(WebKitWebNavigationAction* navigationAction)
328{
329    g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), 0);
330
331    return navigationAction->priv->modifier_state;
332}
333
334/**
335 * webkit_web_navigation_action_get_target_frame:
336 * @navigationAction: a #WebKitWebNavigationAction
337 *
338 * Returns the target frame of the action.
339 *
340 * Return value: the target frame of the action or NULL
341 * if there is no target.
342 *
343 * Since: 1.1.13
344 */
345G_CONST_RETURN gchar* webkit_web_navigation_action_get_target_frame(WebKitWebNavigationAction* navigationAction)
346{
347    g_return_val_if_fail(WEBKIT_IS_WEB_NAVIGATION_ACTION(navigationAction), NULL);
348
349    return navigationAction->priv->targetFrame;
350}
351
352static void webkit_web_navigation_action_set_target_frame(WebKitWebNavigationAction* navigationAction, const gchar* targetFrame)
353{
354    if (!g_strcmp0(navigationAction->priv->targetFrame, targetFrame))
355        return;
356
357    g_free(navigationAction->priv->targetFrame);
358    navigationAction->priv->targetFrame = g_strdup(targetFrame);
359    g_object_notify(G_OBJECT(navigationAction), "target-frame");
360}
361
362namespace WebKit {
363
364WebKitWebNavigationReason kit(WebCore::NavigationType type)
365{
366    return (WebKitWebNavigationReason)type;
367}
368
369WebCore::NavigationType core(WebKitWebNavigationReason type)
370{
371    return static_cast<WebCore::NavigationType>(type);
372}
373
374}
375