1 /* 2 * Copyright (C) 2009 Collabora Ltd. 3 * Copyright (C) 2009 Igalia S.L. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21 #include "config.h" 22 #include "webkithittestresult.h" 23 24 #include "GOwnPtr.h" 25 #include "HitTestResult.h" 26 #include "KURL.h" 27 #include "WebKitDOMBinding.h" 28 #include "WebKitDOMNode.h" 29 #include "webkitenumtypes.h" 30 #include "webkitglobals.h" 31 #include "webkitglobalsprivate.h" 32 #include <glib/gi18n-lib.h> 33 #include <wtf/text/CString.h> 34 35 /** 36 * SECTION:webkithittestresult 37 * @short_description: The target of a mouse event 38 * 39 * This class holds context information about the coordinates 40 * specified by a GDK event. 41 */ 42 43 G_DEFINE_TYPE(WebKitHitTestResult, webkit_hit_test_result, G_TYPE_OBJECT) 44 45 struct _WebKitHitTestResultPrivate { 46 guint context; 47 char* linkURI; 48 char* imageURI; 49 char* mediaURI; 50 WebKitDOMNode* innerNode; 51 }; 52 53 enum { 54 PROP_0, 55 56 PROP_CONTEXT, 57 PROP_LINK_URI, 58 PROP_IMAGE_URI, 59 PROP_MEDIA_URI, 60 PROP_INNER_NODE 61 }; 62 63 static void webkit_hit_test_result_finalize(GObject* object) 64 { 65 WebKitHitTestResult* web_hit_test_result = WEBKIT_HIT_TEST_RESULT(object); 66 WebKitHitTestResultPrivate* priv = web_hit_test_result->priv; 67 68 g_free(priv->linkURI); 69 g_free(priv->imageURI); 70 g_free(priv->mediaURI); 71 72 G_OBJECT_CLASS(webkit_hit_test_result_parent_class)->finalize(object); 73 } 74 75 static void webkit_hit_test_result_dispose(GObject* object) 76 { 77 g_object_unref(WEBKIT_HIT_TEST_RESULT(object)->priv->innerNode); 78 79 G_OBJECT_CLASS(webkit_hit_test_result_parent_class)->dispose(object); 80 } 81 82 static void webkit_hit_test_result_get_property(GObject* object, guint propertyID, GValue* value, GParamSpec* pspec) 83 { 84 WebKitHitTestResult* web_hit_test_result = WEBKIT_HIT_TEST_RESULT(object); 85 WebKitHitTestResultPrivate* priv = web_hit_test_result->priv; 86 87 switch(propertyID) { 88 case PROP_CONTEXT: 89 g_value_set_flags(value, priv->context); 90 break; 91 case PROP_LINK_URI: 92 g_value_set_string(value, priv->linkURI); 93 break; 94 case PROP_IMAGE_URI: 95 g_value_set_string(value, priv->imageURI); 96 break; 97 case PROP_MEDIA_URI: 98 g_value_set_string(value, priv->mediaURI); 99 break; 100 case PROP_INNER_NODE: 101 g_value_set_object(value, priv->innerNode); 102 break; 103 default: 104 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, pspec); 105 } 106 } 107 108 static void webkit_hit_test_result_set_property(GObject* object, guint propertyID, const GValue* value, GParamSpec* pspec) 109 { 110 WebKitHitTestResult* web_hit_test_result = WEBKIT_HIT_TEST_RESULT(object); 111 WebKitHitTestResultPrivate* priv = web_hit_test_result->priv; 112 113 switch(propertyID) { 114 case PROP_CONTEXT: 115 priv->context = g_value_get_flags(value); 116 break; 117 case PROP_LINK_URI: 118 g_free (priv->linkURI); 119 priv->linkURI = g_value_dup_string(value); 120 break; 121 case PROP_IMAGE_URI: 122 g_free (priv->imageURI); 123 priv->imageURI = g_value_dup_string(value); 124 break; 125 case PROP_MEDIA_URI: 126 g_free (priv->mediaURI); 127 priv->mediaURI = g_value_dup_string(value); 128 break; 129 case PROP_INNER_NODE: 130 priv->innerNode = static_cast<WebKitDOMNode*>(g_value_get_object(value)); 131 break; 132 default: 133 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, pspec); 134 } 135 } 136 137 static void webkit_hit_test_result_class_init(WebKitHitTestResultClass* webHitTestResultClass) 138 { 139 GObjectClass* objectClass = G_OBJECT_CLASS(webHitTestResultClass); 140 141 objectClass->finalize = webkit_hit_test_result_finalize; 142 objectClass->dispose = webkit_hit_test_result_dispose; 143 objectClass->get_property = webkit_hit_test_result_get_property; 144 objectClass->set_property = webkit_hit_test_result_set_property; 145 146 webkitInit(); 147 148 /** 149 * WebKitHitTestResult:context: 150 * 151 * Flags indicating the kind of target that received the event. 152 * 153 * Since: 1.1.15 154 */ 155 g_object_class_install_property(objectClass, PROP_CONTEXT, 156 g_param_spec_flags("context", 157 _("Context"), 158 _("Flags indicating the kind of target that received the event."), 159 WEBKIT_TYPE_HIT_TEST_RESULT_CONTEXT, 160 WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT, 161 static_cast<GParamFlags>((WEBKIT_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)))); 162 163 /** 164 * WebKitHitTestResult:link-uri: 165 * 166 * The URI to which the target that received the event points, if any. 167 * 168 * Since: 1.1.15 169 */ 170 g_object_class_install_property(objectClass, PROP_LINK_URI, 171 g_param_spec_string("link-uri", 172 _("Link URI"), 173 _("The URI to which the target that received the event points, if any."), 174 NULL, 175 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY))); 176 177 /** 178 * WebKitHitTestResult:image-uri: 179 * 180 * The URI of the image that is part of the target that received the event, if any. 181 * 182 * Since: 1.1.15 183 */ 184 g_object_class_install_property(objectClass, PROP_IMAGE_URI, 185 g_param_spec_string("image-uri", 186 _("Image URI"), 187 _("The URI of the image that is part of the target that received the event, if any."), 188 NULL, 189 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY))); 190 191 /** 192 * WebKitHitTestResult:media-uri: 193 * 194 * The URI of the media that is part of the target that received the event, if any. 195 * 196 * Since: 1.1.15 197 */ 198 g_object_class_install_property(objectClass, PROP_MEDIA_URI, 199 g_param_spec_string("media-uri", 200 _("Media URI"), 201 _("The URI of the media that is part of the target that received the event, if any."), 202 NULL, 203 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY))); 204 205 /** 206 * WebKitHitTestResult:inner-node: 207 * 208 * The DOM node at the coordinates where the hit test 209 * happened. Keep in mind that the node might not be 210 * representative of the information given in the context 211 * property, since WebKit uses a series of heuristics to figure 212 * out that information. One common example is inner-node having 213 * the text node inside the anchor (<a>) tag; WebKit knows the 214 * whole context and will put WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK 215 * in the 'context' property, but the user might be confused by 216 * the lack of any link tag in 'inner-node'. 217 * 218 * Since: 1.3.2 219 */ 220 g_object_class_install_property(objectClass, PROP_INNER_NODE, 221 g_param_spec_object("inner-node", 222 _("Inner node"), 223 _("The inner DOM node associated with the hit test result."), 224 WEBKIT_TYPE_DOM_NODE, 225 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); 226 227 g_type_class_add_private(webHitTestResultClass, sizeof(WebKitHitTestResultPrivate)); 228 } 229 230 static void webkit_hit_test_result_init(WebKitHitTestResult* web_hit_test_result) 231 { 232 web_hit_test_result->priv = G_TYPE_INSTANCE_GET_PRIVATE(web_hit_test_result, WEBKIT_TYPE_HIT_TEST_RESULT, WebKitHitTestResultPrivate); 233 } 234 235 namespace WebKit { 236 237 WebKitHitTestResult* kit(const WebCore::HitTestResult& result) 238 { 239 guint context = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT; 240 GOwnPtr<char> linkURI(0); 241 GOwnPtr<char> imageURI(0); 242 GOwnPtr<char> mediaURI(0); 243 WebKitDOMNode* node = 0; 244 245 if (!result.absoluteLinkURL().isEmpty()) { 246 context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK; 247 linkURI.set(g_strdup(result.absoluteLinkURL().string().utf8().data())); 248 } 249 250 if (!result.absoluteImageURL().isEmpty()) { 251 context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE; 252 imageURI.set(g_strdup(result.absoluteImageURL().string().utf8().data())); 253 } 254 255 if (!result.absoluteMediaURL().isEmpty()) { 256 context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA; 257 mediaURI.set(g_strdup(result.absoluteMediaURL().string().utf8().data())); 258 } 259 260 if (result.isSelected()) 261 context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION; 262 263 if (result.isContentEditable()) 264 context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE; 265 266 if (result.innerNonSharedNode()) 267 node = kit(result.innerNonSharedNode()); 268 269 return WEBKIT_HIT_TEST_RESULT(g_object_new(WEBKIT_TYPE_HIT_TEST_RESULT, 270 "link-uri", linkURI.get(), 271 "image-uri", imageURI.get(), 272 "media-uri", mediaURI.get(), 273 "context", context, 274 "inner-node", node, 275 NULL)); 276 } 277 278 } 279