1/*
2 * Copyright (C) 2011 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "AccessibilityTextMarker.h"
29#include "AccessibilityTextMarkerRange.h"
30#include "JSWrappable.h"
31
32#include <JavaScriptCore/JSObjectRef.h>
33#include <JavaScriptCore/JSRetainPtr.h>
34#include <wtf/Platform.h>
35#include <wtf/Vector.h>
36
37#if PLATFORM(COCOA)
38#ifdef __OBJC__
39typedef id PlatformUIElement;
40#else
41typedef struct objc_object* PlatformUIElement;
42#endif
43#elif HAVE(ACCESSIBILITY) && PLATFORM(GTK)
44#include "AccessibilityNotificationHandlerAtk.h"
45#include <atk/atk.h>
46#include <wtf/glib/GRefPtr.h>
47typedef GRefPtr<AtkObject> PlatformUIElement;
48#else
49typedef void* PlatformUIElement;
50#endif
51
52#if PLATFORM(COCOA)
53#ifdef __OBJC__
54typedef id NotificationHandler;
55#else
56typedef struct objc_object* NotificationHandler;
57#endif
58#endif
59
60namespace WTR {
61
62class AccessibilityUIElement : public JSWrappable {
63public:
64 static Ref<AccessibilityUIElement> create(PlatformUIElement);
65 static Ref<AccessibilityUIElement> create(const AccessibilityUIElement&);
66
67 ~AccessibilityUIElement();
68
69 PlatformUIElement platformUIElement() { return m_element; }
70 virtual JSClassRef wrapperClass();
71
72 static JSObjectRef makeJSAccessibilityUIElement(JSContextRef, const AccessibilityUIElement&);
73
74 bool isEqual(AccessibilityUIElement* otherElement);
75
76 RefPtr<AccessibilityUIElement> elementAtPoint(int x, int y);
77 RefPtr<AccessibilityUIElement> childAtIndex(unsigned);
78 unsigned indexOfChild(AccessibilityUIElement*);
79 int childrenCount();
80 RefPtr<AccessibilityUIElement> titleUIElement();
81 RefPtr<AccessibilityUIElement> parentElement();
82
83 void takeFocus();
84 void takeSelection();
85 void addSelection();
86 void removeSelection();
87
88 // Methods - platform-independent implementations
89 JSRetainPtr<JSStringRef> allAttributes();
90 JSRetainPtr<JSStringRef> attributesOfLinkedUIElements();
91 RefPtr<AccessibilityUIElement> linkedUIElementAtIndex(unsigned);
92
93 JSRetainPtr<JSStringRef> attributesOfDocumentLinks();
94 JSRetainPtr<JSStringRef> attributesOfChildren();
95 JSRetainPtr<JSStringRef> parameterizedAttributeNames();
96 void increment();
97 void decrement();
98 void showMenu();
99 void press();
100 bool dismiss();
101#if PLATFORM(MAC)
102 void syncPress();
103 void asyncIncrement();
104 void asyncDecrement();
105#else
106 void syncPress() { press(); }
107 void asyncIncrement() { }
108 void asyncDecrement() { };
109#endif
110
111 // Attributes - platform-independent implementations
112 JSRetainPtr<JSStringRef> stringDescriptionOfAttributeValue(JSStringRef attribute);
113 JSRetainPtr<JSStringRef> stringAttributeValue(JSStringRef attribute);
114 double numberAttributeValue(JSStringRef attribute);
115 JSValueRef uiElementArrayAttributeValue(JSStringRef attribute) const;
116 RefPtr<AccessibilityUIElement> uiElementAttributeValue(JSStringRef attribute) const;
117 bool boolAttributeValue(JSStringRef attribute);
118 void setBoolAttributeValue(JSStringRef attribute, bool value);
119 bool isAttributeSupported(JSStringRef attribute);
120 bool isAttributeSettable(JSStringRef attribute);
121 bool isPressActionSupported();
122 bool isIncrementActionSupported();
123 bool isDecrementActionSupported();
124 void setValue(JSStringRef);
125 JSRetainPtr<JSStringRef> role();
126 JSRetainPtr<JSStringRef> subrole();
127 JSRetainPtr<JSStringRef> roleDescription();
128 JSRetainPtr<JSStringRef> computedRoleString();
129 JSRetainPtr<JSStringRef> title();
130 JSRetainPtr<JSStringRef> description();
131 JSRetainPtr<JSStringRef> language();
132 JSRetainPtr<JSStringRef> stringValue();
133 JSRetainPtr<JSStringRef> accessibilityValue() const;
134 JSRetainPtr<JSStringRef> helpText() const;
135 JSRetainPtr<JSStringRef> orientation() const;
136 double x();
137 double y();
138 double width();
139 double height();
140 double intValue() const;
141 double minValue();
142 double maxValue();
143 JSRetainPtr<JSStringRef> valueDescription();
144 int insertionPointLineNumber();
145 JSRetainPtr<JSStringRef> selectedTextRange();
146 bool isEnabled();
147 bool isRequired() const;
148
149 bool isFocused() const;
150 bool isFocusable() const;
151 bool isSelected() const;
152 bool isSelectedOptionActive() const;
153 bool isSelectable() const;
154 bool isMultiSelectable() const;
155 void setSelectedChild(AccessibilityUIElement*) const;
156 void setSelectedChildAtIndex(unsigned) const;
157 void removeSelectionAtIndex(unsigned) const;
158 void clearSelectedChildren() const;
159 unsigned selectedChildrenCount() const;
160 RefPtr<AccessibilityUIElement> selectedChildAtIndex(unsigned) const;
161
162 bool isValid() const;
163 bool isExpanded() const;
164 bool isChecked() const;
165 bool isIndeterminate() const;
166 bool isVisible() const;
167 bool isOffScreen() const;
168 bool isCollapsed() const;
169 bool isIgnored() const;
170 bool isSingleLine() const;
171 bool isMultiLine() const;
172 bool hasPopup() const;
173 int hierarchicalLevel() const;
174 double clickPointX();
175 double clickPointY();
176 JSRetainPtr<JSStringRef> documentEncoding();
177 JSRetainPtr<JSStringRef> documentURI();
178 JSRetainPtr<JSStringRef> url();
179 JSRetainPtr<JSStringRef> classList() const;
180
181 // CSS3-speech properties.
182 JSRetainPtr<JSStringRef> speakAs();
183
184 // Table-specific attributes
185 JSRetainPtr<JSStringRef> attributesOfColumnHeaders();
186 JSRetainPtr<JSStringRef> attributesOfRowHeaders();
187 JSRetainPtr<JSStringRef> attributesOfColumns();
188 JSRetainPtr<JSStringRef> attributesOfRows();
189 JSRetainPtr<JSStringRef> attributesOfVisibleCells();
190 JSRetainPtr<JSStringRef> attributesOfHeader();
191 int indexInTable();
192 JSRetainPtr<JSStringRef> rowIndexRange();
193 JSRetainPtr<JSStringRef> columnIndexRange();
194 int rowCount();
195 int columnCount();
196 JSValueRef rowHeaders() const;
197 JSValueRef columnHeaders() const;
198
199 // Tree/Outline specific attributes
200 RefPtr<AccessibilityUIElement> selectedRowAtIndex(unsigned);
201 RefPtr<AccessibilityUIElement> disclosedByRow();
202 RefPtr<AccessibilityUIElement> disclosedRowAtIndex(unsigned);
203 RefPtr<AccessibilityUIElement> rowAtIndex(unsigned);
204
205 // ARIA specific
206 RefPtr<AccessibilityUIElement> ariaOwnsElementAtIndex(unsigned);
207 RefPtr<AccessibilityUIElement> ariaFlowToElementAtIndex(unsigned);
208 RefPtr<AccessibilityUIElement> ariaControlsElementAtIndex(unsigned);
209#if PLATFORM(MAC) || PLATFORM(GTK)
210 RefPtr<AccessibilityUIElement> ariaDetailsElementAtIndex(unsigned);
211 RefPtr<AccessibilityUIElement> ariaErrorMessageElementAtIndex(unsigned);
212#else
213 RefPtr<AccessibilityUIElement> ariaDetailsElementAtIndex(unsigned) { return nullptr; }
214 RefPtr<AccessibilityUIElement> ariaErrorMessageElementAtIndex(unsigned) { return nullptr; }
215#endif
216
217#if PLATFORM(GTK)
218 RefPtr<AccessibilityUIElement> ariaLabelledByElementAtIndex(unsigned);
219 RefPtr<AccessibilityUIElement> ariaDescribedByElementAtIndex(unsigned);
220 RefPtr<AccessibilityUIElement> ariaOwnsReferencingElementAtIndex(unsigned);
221 RefPtr<AccessibilityUIElement> ariaFlowToReferencingElementAtIndex(unsigned);
222 RefPtr<AccessibilityUIElement> ariaControlsReferencingElementAtIndex(unsigned);
223 RefPtr<AccessibilityUIElement> ariaLabelledByReferencingElementAtIndex(unsigned);
224 RefPtr<AccessibilityUIElement> ariaDescribedByReferencingElementAtIndex(unsigned);
225 RefPtr<AccessibilityUIElement> ariaDetailsReferencingElementAtIndex(unsigned);
226 RefPtr<AccessibilityUIElement> ariaErrorMessageReferencingElementAtIndex(unsigned);
227#else
228 RefPtr<AccessibilityUIElement> ariaLabelledByElementAtIndex(unsigned) { return nullptr; }
229 RefPtr<AccessibilityUIElement> ariaDescribedByElementAtIndex(unsigned) { return nullptr; }
230 RefPtr<AccessibilityUIElement> ariaOwnsReferencingElementAtIndex(unsigned) { return nullptr; }
231 RefPtr<AccessibilityUIElement> ariaFlowToReferencingElementAtIndex(unsigned) { return nullptr; }
232 RefPtr<AccessibilityUIElement> ariaControlsReferencingElementAtIndex(unsigned) { return nullptr; }
233 RefPtr<AccessibilityUIElement> ariaLabelledByReferencingElementAtIndex(unsigned) { return nullptr; }
234 RefPtr<AccessibilityUIElement> ariaDescribedByReferencingElementAtIndex(unsigned) { return nullptr; }
235 RefPtr<AccessibilityUIElement> ariaDetailsReferencingElementAtIndex(unsigned) { return nullptr; }
236 RefPtr<AccessibilityUIElement> ariaErrorMessageReferencingElementAtIndex(unsigned) { return nullptr; }
237#endif
238
239 // ARIA Drag and Drop
240 bool ariaIsGrabbed() const;
241 // A space concatentated string of all the drop effects.
242 JSRetainPtr<JSStringRef> ariaDropEffects() const;
243
244 // Parameterized attributes
245 int lineForIndex(int);
246 JSRetainPtr<JSStringRef> rangeForLine(int);
247 JSRetainPtr<JSStringRef> rangeForPosition(int x, int y);
248 JSRetainPtr<JSStringRef> boundsForRange(unsigned location, unsigned length);
249 bool setSelectedTextRange(unsigned location, unsigned length);
250 JSRetainPtr<JSStringRef> stringForRange(unsigned location, unsigned length);
251 JSRetainPtr<JSStringRef> attributedStringForRange(unsigned location, unsigned length);
252 JSRetainPtr<JSStringRef> attributedStringForElement();
253
254 bool attributedStringRangeIsMisspelled(unsigned location, unsigned length);
255 unsigned uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
256 RefPtr<AccessibilityUIElement> uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
257 JSRetainPtr<JSStringRef> selectTextWithCriteria(JSContextRef, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity);
258 JSValueRef searchTextWithCriteria(JSContextRef, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction);
259
260 // Text-specific
261 JSRetainPtr<JSStringRef> characterAtOffset(int offset);
262 JSRetainPtr<JSStringRef> wordAtOffset(int offset);
263 JSRetainPtr<JSStringRef> lineAtOffset(int offset);
264 JSRetainPtr<JSStringRef> sentenceAtOffset(int offset);
265
266 // Table-specific
267 RefPtr<AccessibilityUIElement> cellForColumnAndRow(unsigned column, unsigned row);
268
269 // Scrollarea-specific
270 RefPtr<AccessibilityUIElement> horizontalScrollbar() const;
271 RefPtr<AccessibilityUIElement> verticalScrollbar() const;
272
273 void scrollToMakeVisible();
274 void scrollToGlobalPoint(int x, int y);
275 void scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height);
276
277 // Text markers.
278 RefPtr<AccessibilityTextMarkerRange> lineTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
279 RefPtr<AccessibilityTextMarkerRange> textMarkerRangeForElement(AccessibilityUIElement*);
280 RefPtr<AccessibilityTextMarkerRange> textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker);
281 RefPtr<AccessibilityTextMarkerRange> selectedTextMarkerRange();
282 void resetSelectedTextMarkerRange();
283 bool replaceTextInRange(JSStringRef, int position, int length);
284 RefPtr<AccessibilityTextMarker> startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
285 RefPtr<AccessibilityTextMarker> endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
286 RefPtr<AccessibilityTextMarker> endTextMarkerForBounds(int x, int y, int width, int height);
287 RefPtr<AccessibilityTextMarker> startTextMarkerForBounds(int x, int y, int width, int height);
288 RefPtr<AccessibilityTextMarker> textMarkerForPoint(int x, int y);
289 RefPtr<AccessibilityTextMarker> previousTextMarker(AccessibilityTextMarker*);
290 RefPtr<AccessibilityTextMarker> nextTextMarker(AccessibilityTextMarker*);
291 RefPtr<AccessibilityUIElement> accessibilityElementForTextMarker(AccessibilityTextMarker*);
292 JSRetainPtr<JSStringRef> stringForTextMarkerRange(AccessibilityTextMarkerRange*);
293 JSRetainPtr<JSStringRef> attributedStringForTextMarkerRange(AccessibilityTextMarkerRange*);
294 JSRetainPtr<JSStringRef> attributedStringForTextMarkerRangeWithOptions(AccessibilityTextMarkerRange*, bool);
295 int textMarkerRangeLength(AccessibilityTextMarkerRange*);
296 bool attributedStringForTextMarkerRangeContainsAttribute(JSStringRef, AccessibilityTextMarkerRange*);
297 int indexForTextMarker(AccessibilityTextMarker*);
298 bool isTextMarkerValid(AccessibilityTextMarker*);
299 RefPtr<AccessibilityTextMarker> textMarkerForIndex(int);
300 RefPtr<AccessibilityTextMarker> startTextMarker();
301 RefPtr<AccessibilityTextMarker> endTextMarker();
302 bool setSelectedVisibleTextRange(AccessibilityTextMarkerRange*);
303 RefPtr<AccessibilityTextMarkerRange> leftWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
304 RefPtr<AccessibilityTextMarkerRange> rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
305 RefPtr<AccessibilityTextMarker> previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker*);
306 RefPtr<AccessibilityTextMarker> nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker*);
307 RefPtr<AccessibilityTextMarkerRange> paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
308 RefPtr<AccessibilityTextMarker> nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*);
309 RefPtr<AccessibilityTextMarker> previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*);
310 RefPtr<AccessibilityTextMarkerRange> sentenceTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
311 RefPtr<AccessibilityTextMarker> nextSentenceEndTextMarkerForTextMarker(AccessibilityTextMarker*);
312 RefPtr<AccessibilityTextMarker> previousSentenceStartTextMarkerForTextMarker(AccessibilityTextMarker*);
313 RefPtr<AccessibilityTextMarkerRange> textMarkerRangeMatchesTextNearMarkers(JSStringRef, AccessibilityTextMarker*, AccessibilityTextMarker*);
314
315 // Returns an ordered list of supported actions for an element.
316 JSRetainPtr<JSStringRef> supportedActions() const;
317 JSRetainPtr<JSStringRef> mathPostscriptsDescription() const;
318 JSRetainPtr<JSStringRef> mathPrescriptsDescription() const;
319
320 JSRetainPtr<JSStringRef> pathDescription() const;
321
322 // Notifications
323 // Function callback should take one argument, the name of the notification.
324 bool addNotificationListener(JSValueRef functionCallback);
325 // Make sure you call remove, because you can't rely on objects being deallocated in a timely fashion.
326 bool removeNotificationListener();
327
328 JSRetainPtr<JSStringRef> identifier();
329 JSRetainPtr<JSStringRef> traits();
330 int elementTextPosition();
331 int elementTextLength();
332 JSRetainPtr<JSStringRef> stringForSelection();
333 JSValueRef elementsForRange(unsigned location, unsigned length);
334 void increaseTextSelection();
335 void decreaseTextSelection();
336 RefPtr<AccessibilityUIElement> linkedElement();
337 RefPtr<AccessibilityUIElement> headerElementAtIndex(unsigned index);
338 void assistiveTechnologySimulatedFocus();
339 bool isSearchField() const;
340 bool isTextArea() const;
341
342 bool scrollPageUp();
343 bool scrollPageDown();
344 bool scrollPageLeft();
345 bool scrollPageRight();
346
347 // Fieldset
348 bool hasContainedByFieldsetTrait();
349 RefPtr<AccessibilityUIElement> fieldsetAncestorElement();
350
351private:
352 AccessibilityUIElement(PlatformUIElement);
353 AccessibilityUIElement(const AccessibilityUIElement&);
354
355 PlatformUIElement m_element;
356
357 // A retained, platform specific object used to help manage notifications for this object.
358#if HAVE(ACCESSIBILITY)
359#if PLATFORM(COCOA)
360 NotificationHandler m_notificationHandler;
361
362 void getLinkedUIElements(Vector<RefPtr<AccessibilityUIElement> >&);
363 void getDocumentLinks(Vector<RefPtr<AccessibilityUIElement> >&);
364
365 void getUIElementsWithAttribute(JSStringRef, Vector<RefPtr<AccessibilityUIElement> >&) const;
366#endif
367
368 void getChildren(Vector<RefPtr<AccessibilityUIElement> >&);
369 void getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >&, unsigned location, unsigned length);
370
371#if PLATFORM(GTK)
372 RefPtr<AccessibilityNotificationHandler> m_notificationHandler;
373#endif
374#endif
375};
376
377} // namespace WTR
378