| 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 | |
| 33 | using namespace WebKit; |
| 34 | using 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 | |
| 47 | struct _WebKitNavigationPolicyDecisionPrivate { |
| 48 | ~_WebKitNavigationPolicyDecisionPrivate() |
| 49 | { |
| 50 | webkit_navigation_action_free(navigationAction); |
| 51 | } |
| 52 | |
| 53 | WebKitNavigationAction* navigationAction; |
| 54 | CString frameName; |
| 55 | }; |
| 56 | |
| 57 | WEBKIT_DEFINE_TYPE(WebKitNavigationPolicyDecision, webkit_navigation_policy_decision, WEBKIT_TYPE_POLICY_DECISION) |
| 58 | |
| 59 | enum { |
| 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 | |
| 71 | static 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 | |
| 101 | static 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 | */ |
| 224 | WebKitNavigationAction* 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 | */ |
| 241 | WebKitNavigationType 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 | */ |
| 257 | guint 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 | */ |
| 273 | unsigned 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 | */ |
| 289 | WebKitURIRequest* 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 | */ |
| 304 | const 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 | |
| 311 | WebKitPolicyDecision* 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 | |