OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2008 Nuanti Ltd. | |
3 * Copyright (C) 2009 Jan Alonzo | |
4 * Copyright (C) 2009, 2010, 2012 Igalia S.L. | |
5 * | |
6 * Portions from Mozilla a11y, copyright as follows: | |
7 * | |
8 * The Original Code is mozilla.org code. | |
9 * | |
10 * The Initial Developer of the Original Code is | |
11 * Sun Microsystems, Inc. | |
12 * Portions created by the Initial Developer are Copyright (C) 2002 | |
13 * the Initial Developer. All Rights Reserved. | |
14 * | |
15 * This library is free software; you can redistribute it and/or | |
16 * modify it under the terms of the GNU Library General Public | |
17 * License as published by the Free Software Foundation; either | |
18 * version 2 of the License, or (at your option) any later version. | |
19 * | |
20 * This library is distributed in the hope that it will be useful, | |
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
23 * Library General Public License for more details. | |
24 * | |
25 * You should have received a copy of the GNU Library General Public License | |
26 * along with this library; see the file COPYING.LIB. If not, write to | |
27 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
28 * Boston, MA 02110-1301, USA. | |
29 */ | |
30 | |
31 #include "config.h" | |
32 #include "WebKitAccessibleUtil.h" | |
33 | |
34 #if HAVE(ACCESSIBILITY) | |
35 | |
36 #include "AccessibilityObject.h" | |
37 #include "FrameView.h" | |
38 #include "IntRect.h" | |
39 #include "Node.h" | |
40 #include "Range.h" | |
41 #include "VisibleSelection.h" | |
42 | |
43 #include <wtf/text/AtomicString.h> | |
44 #include <wtf/text/CString.h> | |
45 | |
46 using namespace WebCore; | |
47 | |
48 AtkAttributeSet* addToAtkAttributeSet(AtkAttributeSet* attributeSet, const char*
name, const char* value) | |
49 { | |
50 AtkAttribute* attribute = static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttr
ibute))); | |
51 attribute->name = g_strdup(name); | |
52 attribute->value = g_strdup(value); | |
53 attributeSet = g_slist_prepend(attributeSet, attribute); | |
54 return attributeSet; | |
55 } | |
56 | |
57 void contentsRelativeToAtkCoordinateType(AccessibilityObject* coreObject, AtkCoo
rdType coordType, IntRect rect, gint* x, gint* y, gint* width, gint* height) | |
58 { | |
59 FrameView* frameView = coreObject->documentFrameView(); | |
60 | |
61 if (frameView) { | |
62 switch (coordType) { | |
63 case ATK_XY_WINDOW: | |
64 rect = frameView->contentsToWindow(rect); | |
65 break; | |
66 case ATK_XY_SCREEN: | |
67 rect = frameView->contentsToScreen(rect); | |
68 break; | |
69 } | |
70 } | |
71 | |
72 if (x) | |
73 *x = rect.x(); | |
74 if (y) | |
75 *y = rect.y(); | |
76 if (width) | |
77 *width = rect.width(); | |
78 if (height) | |
79 *height = rect.height(); | |
80 } | |
81 | |
82 // FIXME: Different kinds of elements are putting the title tag to use | |
83 // in different AX fields. This might not be 100% correct but we will | |
84 // keep it now in order to achieve consistency with previous behavior. | |
85 static bool titleTagShouldBeUsedInDescriptionField(AccessibilityObject* coreObje
ct) | |
86 { | |
87 return (coreObject->isLink() && !coreObject->isImageMapLink()) || coreObject
->isImage(); | |
88 } | |
89 | |
90 // This should be the "visible" text that's actually on the screen if possible. | |
91 // If there's alternative text, that can override the title. | |
92 String accessibilityTitle(AccessibilityObject* coreObject) | |
93 { | |
94 Vector<AccessibilityText> textOrder; | |
95 coreObject->accessibilityText(textOrder); | |
96 | |
97 unsigned length = textOrder.size(); | |
98 for (unsigned k = 0; k < length; k++) { | |
99 const AccessibilityText& text = textOrder[k]; | |
100 | |
101 // Once we encounter visible text, or the text from our children that sh
ould be used foremost. | |
102 if (text.textSource == VisibleText || text.textSource == ChildrenText) | |
103 return text.text; | |
104 | |
105 // If there's an element that labels this object and it's not exposed, t
hen we should use | |
106 // that text as our title. | |
107 if (text.textSource == LabelByElementText && !coreObject->exposesTitleUI
Element()) | |
108 return text.text; | |
109 | |
110 // Elements of role ToolbarRole will return its title as AlternativeText
. | |
111 if (coreObject->roleValue() == ToolbarRole && text.textSource == Alterna
tiveText) | |
112 return text.text; | |
113 | |
114 // FIXME: The title tag is used in certain cases for the title. This usa
ge should | |
115 // probably be in the description field since it's not "visible". | |
116 if (text.textSource == TitleTagText && !titleTagShouldBeUsedInDescriptio
nField(coreObject)) | |
117 return text.text; | |
118 } | |
119 return String(); | |
120 } | |
121 | |
122 String accessibilityDescription(AccessibilityObject* coreObject) | |
123 { | |
124 Vector<AccessibilityText> textOrder; | |
125 coreObject->accessibilityText(textOrder); | |
126 | |
127 unsigned length = textOrder.size(); | |
128 for (unsigned k = 0; k < length; k++) { | |
129 const AccessibilityText& text = textOrder[k]; | |
130 | |
131 if (text.textSource == AlternativeText) | |
132 return text.text; | |
133 | |
134 if (text.textSource == TitleTagText && titleTagShouldBeUsedInDescription
Field(coreObject)) | |
135 return text.text; | |
136 } | |
137 | |
138 return String(); | |
139 } | |
140 | |
141 bool selectionBelongsToObject(AccessibilityObject* coreObject, VisibleSelection&
selection) | |
142 { | |
143 if (!coreObject || !coreObject->isAccessibilityRenderObject()) | |
144 return false; | |
145 | |
146 if (selection.isNone()) | |
147 return false; | |
148 | |
149 RefPtr<Range> range = selection.toNormalizedRange(); | |
150 if (!range) | |
151 return false; | |
152 | |
153 // We want to check that both the selection intersects the node | |
154 // AND that the selection is not just "touching" one of the | |
155 // boundaries for the selected node. We want to check whether the | |
156 // node is actually inside the region, at least partially. | |
157 Node* node = coreObject->node(); | |
158 Node* lastDescendant = node->lastDescendant(); | |
159 return (range->intersectsNode(node, IGNORE_EXCEPTION) | |
160 && (range->endContainer() != node || range->endOffset()) | |
161 && (range->startContainer() != lastDescendant || range->startOffset() !=
lastOffsetInNode(lastDescendant))); | |
162 } | |
163 | |
164 #endif | |
OLD | NEW |