Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp

Issue 13726025: Remove GTK AX support, we've never used it (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2010, 2011, 2012 Igalia S.L.
3 * Copyright (C) 2013 Samsung Electronics
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 "WebKitAccessibleHyperlink.h"
23
24 #if HAVE(ACCESSIBILITY)
25
26 #include "AXObjectCache.h"
27 #include "AccessibilityObject.h"
28 #include "NotImplemented.h"
29 #include "Position.h"
30 #include "Range.h"
31 #include "RenderListMarker.h"
32 #include "RenderObject.h"
33 #include "TextIterator.h"
34 #include "WebKitAccessibleUtil.h"
35 #include "WebKitAccessibleWrapperAtk.h"
36 #include "htmlediting.h"
37
38 #include <atk/atk.h>
39 #include <glib.h>
40
41 using namespace WebCore;
42
43 struct _WebKitAccessibleHyperlinkPrivate {
44 WebKitAccessible* hyperlinkImpl;
45
46 // We cache these values so we can return them as const values.
47 CString actionName;
48 CString actionKeyBinding;
49 };
50
51 #define WEBKIT_ACCESSIBLE_HYPERLINK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVAT E((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlinkPrivate))
52
53 enum {
54 PROP_0,
55
56 PROP_HYPERLINK_IMPL
57 };
58
59 static gpointer webkitAccessibleHyperlinkParentClass = 0;
60
61 static AccessibilityObject* core(WebKitAccessible* accessible)
62 {
63 if (!accessible || !WEBKIT_IS_ACCESSIBLE(accessible))
64 return 0;
65
66 return webkitAccessibleGetAccessibilityObject(accessible);
67 }
68
69 static AccessibilityObject* core(WebKitAccessibleHyperlink* link)
70 {
71 if (!link)
72 return 0;
73
74 return core(link->priv->hyperlinkImpl);
75 }
76
77 static AccessibilityObject* core(AtkHyperlink* link)
78 {
79 if (!WEBKIT_IS_ACCESSIBLE_HYPERLINK(link))
80 return 0;
81
82 return core(WEBKIT_ACCESSIBLE_HYPERLINK(link));
83 }
84
85 static AccessibilityObject* core(AtkAction* action)
86 {
87 return core(WEBKIT_ACCESSIBLE_HYPERLINK(action));
88 }
89
90
91 static gboolean webkitAccessibleHyperlinkActionDoAction(AtkAction* action, gint index)
92 {
93 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), FALSE);
94 g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImp l, FALSE);
95 g_return_val_if_fail(!index, FALSE);
96
97 if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl) )
98 return FALSE;
99
100 AccessibilityObject* coreObject = core(action);
101 if (!coreObject)
102 return FALSE;
103
104 return coreObject->performDefaultAction();
105 }
106
107 static gint webkitAccessibleHyperlinkActionGetNActions(AtkAction* action)
108 {
109 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
110 g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImp l, 0);
111
112 if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl) )
113 return 0;
114
115 return 1;
116 }
117
118 static const gchar* webkitAccessibleHyperlinkActionGetDescription(AtkAction* act ion, gint index)
119 {
120 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
121 g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImp l, 0);
122 g_return_val_if_fail(!index, 0);
123
124 // TODO: Need a way to provide/localize action descriptions.
125 notImplemented();
126 return "";
127 }
128
129 static const gchar* webkitAccessibleHyperlinkActionGetKeybinding(AtkAction* acti on, gint index)
130 {
131 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
132 g_return_val_if_fail(!index, 0);
133
134 WebKitAccessibleHyperlinkPrivate* priv = WEBKIT_ACCESSIBLE_HYPERLINK(action) ->priv;
135 g_return_val_if_fail(priv->hyperlinkImpl, 0);
136
137 if (!ATK_IS_ACTION(priv->hyperlinkImpl))
138 return 0;
139
140 AccessibilityObject* coreObject = core(action);
141 if (!coreObject)
142 return 0;
143
144 priv->actionKeyBinding = coreObject->accessKey().string().utf8();
145 return priv->actionKeyBinding.data();
146 }
147
148 static const gchar* webkitAccessibleHyperlinkActionGetName(AtkAction* action, gi nt index)
149 {
150 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
151 g_return_val_if_fail(!index, 0);
152
153 WebKitAccessibleHyperlinkPrivate* priv = WEBKIT_ACCESSIBLE_HYPERLINK(action) ->priv;
154 g_return_val_if_fail(priv->hyperlinkImpl, 0);
155
156 if (!ATK_IS_ACTION(priv->hyperlinkImpl))
157 return 0;
158
159 AccessibilityObject* coreObject = core(action);
160 if (!coreObject)
161 return 0;
162
163 priv->actionName = coreObject->actionVerb().utf8();
164 return priv->actionName.data();
165 }
166
167 static void atkActionInterfaceInit(AtkActionIface* iface)
168 {
169 iface->do_action = webkitAccessibleHyperlinkActionDoAction;
170 iface->get_n_actions = webkitAccessibleHyperlinkActionGetNActions;
171 iface->get_description = webkitAccessibleHyperlinkActionGetDescription;
172 iface->get_keybinding = webkitAccessibleHyperlinkActionGetKeybinding;
173 iface->get_name = webkitAccessibleHyperlinkActionGetName;
174 }
175
176 static gchar* webkitAccessibleHyperlinkGetURI(AtkHyperlink* link, gint index)
177 {
178 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
179 // FIXME: Do NOT support more than one instance of an AtkObject
180 // implementing AtkHyperlinkImpl in every instance of AtkHyperLink
181 g_return_val_if_fail(!index, 0);
182
183 AccessibilityObject* coreObject = core(link);
184 if (!coreObject || coreObject->url().isNull())
185 return 0;
186
187 return g_strdup(coreObject->url().string().utf8().data());
188 }
189
190 static AtkObject* webkitAccessibleHyperlinkGetObject(AtkHyperlink* link, gint in dex)
191 {
192 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
193 g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
194
195 // FIXME: Do NOT support more than one instance of an AtkObject
196 // implementing AtkHyperlinkImpl in every instance of AtkHyperLink
197 g_return_val_if_fail(!index, 0);
198
199 return ATK_OBJECT(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl);
200 }
201
202 static gint getRangeLengthForObject(AccessibilityObject* obj, Range* range)
203 {
204 // This is going to be the actual length in most of the cases
205 int baseLength = TextIterator::rangeLength(range, true);
206
207 // Check whether the current hyperlink belongs to a list item.
208 // If so, we need to consider the length of the item's marker
209 AccessibilityObject* parent = obj->parentObjectUnignored();
210 if (!parent || !parent->isAccessibilityRenderObject() || !parent->isListItem ())
211 return baseLength;
212
213 // Even if we don't expose list markers to Assistive
214 // Technologies, we need to have a way to measure their length
215 // for those cases when it's needed to take it into account
216 // separately (as in getAccessibilityObjectForOffset)
217 AccessibilityObject* markerObj = parent->firstChild();
218 if (!markerObj)
219 return baseLength;
220
221 RenderObject* renderer = markerObj->renderer();
222 if (!renderer || !renderer->isListMarker())
223 return baseLength;
224
225 RenderListMarker* marker = toRenderListMarker(renderer);
226 return baseLength + marker->text().length() + marker->suffix().length();
227 }
228
229 static gint webkitAccessibleHyperlinkGetStartIndex(AtkHyperlink* link)
230 {
231 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
232
233 AccessibilityObject* coreObject = core(link);
234 if (!coreObject)
235 return 0;
236
237 AccessibilityObject* parentUnignored = coreObject->parentObjectUnignored();
238 if (!parentUnignored)
239 return 0;
240
241 Node* node = coreObject->node();
242 if (!node)
243 return 0;
244
245 Node* parentNode = parentUnignored->node();
246 if (!parentNode)
247 return 0;
248
249 RefPtr<Range> range = Range::create(node->document(), firstPositionInOrBefor eNode(parentNode), firstPositionInOrBeforeNode(node));
250 return getRangeLengthForObject(coreObject, range.get());
251 }
252
253 static gint webkitAccessibleHyperlinkGetEndIndex(AtkHyperlink* link)
254 {
255 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
256
257 AccessibilityObject* coreObject = core(link);
258 if (!coreObject)
259 return 0;
260
261 AccessibilityObject* parentUnignored = coreObject->parentObjectUnignored();
262 if (!parentUnignored)
263 return 0;
264
265 Node* node = coreObject->node();
266 if (!node)
267 return 0;
268
269 Node* parentNode = parentUnignored->node();
270 if (!parentNode)
271 return 0;
272
273 RefPtr<Range> range = Range::create(node->document(), firstPositionInOrBefor eNode(parentNode), lastPositionInOrAfterNode(node));
274 return getRangeLengthForObject(coreObject, range.get());
275 }
276
277 static gboolean webkitAccessibleHyperlinkIsValid(AtkHyperlink* link)
278 {
279 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
280 g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, FALSE);
281
282 // Link is valid for the whole object's lifetime
283 return TRUE;
284 }
285
286 static gint webkitAccessibleHyperlinkGetNAnchors(AtkHyperlink* link)
287 {
288 // FIXME Do NOT support more than one instance of an AtkObject
289 // implementing AtkHyperlinkImpl in every instance of AtkHyperLink
290 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
291 g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
292 return 1;
293 }
294
295 static gboolean webkitAccessibleHyperlinkIsSelectedLink(AtkHyperlink*)
296 {
297 // Not implemented: this function is deprecated in ATK now
298 notImplemented();
299 return FALSE;
300 }
301
302 static void webkitAccessibleHyperlinkGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* pspec)
303 {
304 switch (propId) {
305 case PROP_HYPERLINK_IMPL:
306 g_value_set_object(value, WEBKIT_ACCESSIBLE_HYPERLINK(object)->priv->hyp erlinkImpl);
307 break;
308 default:
309 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
310 }
311 }
312
313 static void webkitAccessibleHyperlinkSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* pspec)
314 {
315 WebKitAccessibleHyperlinkPrivate* priv = WEBKIT_ACCESSIBLE_HYPERLINK(object) ->priv;
316
317 switch (propId) {
318 case PROP_HYPERLINK_IMPL:
319 // No need to check and unref previous values of
320 // priv->hyperlinkImpl as this is a CONSTRUCT ONLY property
321 priv->hyperlinkImpl = WEBKIT_ACCESSIBLE(g_value_get_object(value));
322 g_object_weak_ref(G_OBJECT(priv->hyperlinkImpl), (GWeakNotify)g_object_u nref, object);
323 break;
324 default:
325 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
326 }
327 }
328
329 static void webkitAccessibleHyperlinkFinalize(GObject* object)
330 {
331 G_OBJECT_CLASS(webkitAccessibleHyperlinkParentClass)->finalize(object);
332 }
333
334 static void webkitAccessibleHyperlinkClassInit(AtkHyperlinkClass* klass)
335 {
336 GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
337
338 webkitAccessibleHyperlinkParentClass = g_type_class_peek_parent(klass);
339
340 gobjectClass->finalize = webkitAccessibleHyperlinkFinalize;
341 gobjectClass->set_property = webkitAccessibleHyperlinkSetProperty;
342 gobjectClass->get_property = webkitAccessibleHyperlinkGetProperty;
343
344 klass->get_uri = webkitAccessibleHyperlinkGetURI;
345 klass->get_object = webkitAccessibleHyperlinkGetObject;
346 klass->get_start_index = webkitAccessibleHyperlinkGetStartIndex;
347 klass->get_end_index = webkitAccessibleHyperlinkGetEndIndex;
348 klass->is_valid = webkitAccessibleHyperlinkIsValid;
349 klass->get_n_anchors = webkitAccessibleHyperlinkGetNAnchors;
350 klass->is_selected_link = webkitAccessibleHyperlinkIsSelectedLink;
351
352 g_object_class_install_property(gobjectClass, PROP_HYPERLINK_IMPL,
353 g_param_spec_object("hyperlink-impl",
354 "Hyperlink implementation",
355 "The associated WebKitAccessible instance.",
356 WEBKIT_TYPE_ACCESSIBLE,
357 (GParamFlags)(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_S TATIC_STRINGS)));
358
359 g_type_class_add_private(gobjectClass, sizeof(WebKitAccessibleHyperlinkPriva te));
360 }
361
362 static void webkitAccessibleHyperlinkInit(AtkHyperlink* link)
363 {
364 WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv = WEBKIT_ACCESSIBLE_HYPERLINK_GET_PR IVATE(link);
365 WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl = 0;
366 }
367
368 GType webkitAccessibleHyperlinkGetType()
369 {
370 static volatile gsize typeVolatile = 0;
371
372 if (g_once_init_enter(&typeVolatile)) {
373 static const GTypeInfo tinfo = {
374 sizeof(WebKitAccessibleHyperlinkClass),
375 (GBaseInitFunc) 0,
376 (GBaseFinalizeFunc) 0,
377 (GClassInitFunc) webkitAccessibleHyperlinkClassInit,
378 (GClassFinalizeFunc) 0,
379 0, /* class data */
380 sizeof(WebKitAccessibleHyperlink), /* instance size */
381 0, /* nb preallocs */
382 (GInstanceInitFunc) webkitAccessibleHyperlinkInit,
383 0 /* value table */
384 };
385
386 static const GInterfaceInfo actionInfo = {
387 (GInterfaceInitFunc)(GInterfaceInitFunc)atkActionInterfaceInit,
388 (GInterfaceFinalizeFunc) 0, 0
389 };
390
391 GType type = g_type_register_static(ATK_TYPE_HYPERLINK, "WebKitAccessibl eHyperlink", &tinfo, GTypeFlags(0));
392 g_type_add_interface_static(type, ATK_TYPE_ACTION, &actionInfo);
393
394 g_once_init_leave(&typeVolatile, type);
395 }
396
397 return typeVolatile;
398 }
399
400 WebKitAccessibleHyperlink* webkitAccessibleHyperlinkNew(AtkHyperlinkImpl* hyperl inkImpl)
401 {
402 g_return_val_if_fail(ATK_IS_HYPERLINK_IMPL(hyperlinkImpl), 0);
403 return WEBKIT_ACCESSIBLE_HYPERLINK(g_object_new(WEBKIT_TYPE_ACCESSIBLE_HYPER LINK, "hyperlink-impl", hyperlinkImpl, 0));
404 }
405
406 WebCore::AccessibilityObject* webkitAccessibleHyperlinkGetAccessibilityObject(We bKitAccessibleHyperlink* link)
407 {
408 g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
409 return core(link);
410 }
411
412 #endif // HAVE(ACCESSIBILITY)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698