62247e7da65b55a97923f0b6456941d5dede9132
[WebKit-https.git] / Source / WebCore / accessibility / mac / WebAccessibilityObjectWrapperMac.mm
1 /*
2  * Copyright (C) 2008, 2009, 2010, 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import "config.h"
30 #import "WebAccessibilityObjectWrapperMac.h"
31
32 #if ENABLE(ACCESSIBILITY) && PLATFORM(MAC)
33
34 #import "AXObjectCache.h"
35 #import "AccessibilityARIAGridRow.h"
36 #import "AccessibilityLabel.h"
37 #import "AccessibilityList.h"
38 #import "AccessibilityListBox.h"
39 #import "AccessibilityProgressIndicator.h"
40 #import "AccessibilityRenderObject.h"
41 #import "AccessibilityScrollView.h"
42 #import "AccessibilitySpinButton.h"
43 #import "AccessibilityTable.h"
44 #import "AccessibilityTableCell.h"
45 #import "AccessibilityTableColumn.h"
46 #import "AccessibilityTableRow.h"
47 #import "Chrome.h"
48 #import "ChromeClient.h"
49 #import "ColorMac.h"
50 #import "ContextMenuController.h"
51 #import "Editing.h"
52 #import "Editor.h"
53 #import "Font.h"
54 #import "FontCascade.h"
55 #import "Frame.h"
56 #import "FrameLoaderClient.h"
57 #import "FrameSelection.h"
58 #import "HTMLAnchorElement.h"
59 #import "HTMLAreaElement.h"
60 #import "HTMLFrameOwnerElement.h"
61 #import "HTMLImageElement.h"
62 #import "HTMLInputElement.h"
63 #import "HTMLNames.h"
64 #import "LocalizedStrings.h"
65 #import "Page.h"
66 #import "PluginDocument.h"
67 #import "PluginViewBase.h"
68 #import "RenderInline.h"
69 #import "RenderTextControl.h"
70 #import "RenderView.h"
71 #import "RenderWidget.h"
72 #import "ScrollView.h"
73 #import "TextCheckerClient.h"
74 #import "TextCheckingHelper.h"
75 #import "TextDecorationPainter.h"
76 #import "TextIterator.h"
77 #import "VisibleUnits.h"
78 #import "WebCoreFrameView.h"
79 #import <pal/spi/mac/HIServicesSPI.h>
80 #import <pal/spi/mac/NSAccessibilitySPI.h>
81 #import <wtf/ObjCRuntimeExtras.h>
82 #if ENABLE(TREE_DEBUGGING) || ENABLE(METER_ELEMENT)
83 #import <wtf/text/StringBuilder.h>
84 #endif
85
86 using namespace WebCore;
87 using namespace HTMLNames;
88
89 // Cell Tables
90 #ifndef NSAccessibilitySelectedCellsAttribute
91 #define NSAccessibilitySelectedCellsAttribute @"AXSelectedCells"
92 #endif
93
94 #ifndef NSAccessibilityVisibleCellsAttribute
95 #define NSAccessibilityVisibleCellsAttribute @"AXVisibleCells"
96 #endif
97
98 #ifndef NSAccessibilityRowIndexRangeAttribute
99 #define NSAccessibilityRowIndexRangeAttribute @"AXRowIndexRange"
100 #endif
101
102 #ifndef NSAccessibilityColumnIndexRangeAttribute
103 #define NSAccessibilityColumnIndexRangeAttribute @"AXColumnIndexRange"
104 #endif
105
106 #ifndef NSAccessibilityCellForColumnAndRowParameterizedAttribute
107 #define NSAccessibilityCellForColumnAndRowParameterizedAttribute @"AXCellForColumnAndRow"
108 #endif
109
110 #ifndef NSAccessibilityCellRole
111 #define NSAccessibilityCellRole @"AXCell"
112 #endif
113
114 // Lists
115 #ifndef NSAccessibilityContentListSubrole
116 #define NSAccessibilityContentListSubrole @"AXContentList"
117 #endif
118
119 #ifndef NSAccessibilityDefinitionListSubrole
120 #define NSAccessibilityDefinitionListSubrole @"AXDefinitionList"
121 #endif
122
123 #ifndef NSAccessibilityDescriptionListSubrole
124 #define NSAccessibilityDescriptionListSubrole @"AXDescriptionList"
125 #endif
126
127 #ifndef NSAccessibilityContentSeparatorSubrole
128 #define NSAccessibilityContentSeparatorSubrole @"AXContentSeparator"
129 #endif
130
131 #ifndef NSAccessibilityRubyBaseSubRole
132 #define NSAccessibilityRubyBaseSubrole @"AXRubyBase"
133 #endif
134
135 #ifndef NSAccessibilityRubyBlockSubrole
136 #define NSAccessibilityRubyBlockSubrole @"AXRubyBlock"
137 #endif
138
139 #ifndef NSAccessibilityRubyInlineSubrole
140 #define NSAccessibilityRubyInlineSubrole @"AXRubyInline"
141 #endif
142
143 #ifndef NSAccessibilityRubyRunSubrole
144 #define NSAccessibilityRubyRunSubrole @"AXRubyRun"
145 #endif
146
147 #ifndef NSAccessibilityRubyTextSubrole
148 #define NSAccessibilityRubyTextSubrole @"AXRubyText"
149 #endif
150
151 // Miscellaneous
152 #ifndef NSAccessibilityBlockQuoteLevelAttribute
153 #define NSAccessibilityBlockQuoteLevelAttribute @"AXBlockQuoteLevel"
154 #endif
155
156 #ifndef NSAccessibilityChildrenInNavigationOrderAttribute
157 #define NSAccessibilityChildrenInNavigationOrderAttribute @"AXChildrenInNavigationOrder"
158 #endif
159
160 #ifndef NSAccessibilityAccessKeyAttribute
161 #define NSAccessibilityAccessKeyAttribute @"AXAccessKey"
162 #endif
163
164 #ifndef NSAccessibilityValueAutofilledAttribute
165 #define NSAccessibilityValueAutofilledAttribute @"AXValueAutofilled"
166 #endif
167
168 #ifndef NSAccessibilityValueAutofillAvailableAttribute
169 #define NSAccessibilityValueAutofillAvailableAttribute @"AXValueAutofillAvailable"
170 #endif
171
172 #ifndef NSAccessibilityValueAutofillTypeAttribute
173 #define NSAccessibilityValueAutofillTypeAttribute @"AXValueAutofillType"
174 #endif
175
176 #ifndef NSAccessibilityLanguageAttribute
177 #define NSAccessibilityLanguageAttribute @"AXLanguage"
178 #endif
179
180 #ifndef NSAccessibilityRequiredAttribute
181 #define NSAccessibilityRequiredAttribute @"AXRequired"
182 #endif
183
184 #ifndef NSAccessibilityInvalidAttribute
185 #define NSAccessibilityInvalidAttribute @"AXInvalid"
186 #endif
187
188 #ifndef NSAccessibilityOwnsAttribute
189 #define NSAccessibilityOwnsAttribute @"AXOwns"
190 #endif
191
192 #ifndef NSAccessibilityGrabbedAttribute
193 #define NSAccessibilityGrabbedAttribute @"AXGrabbed"
194 #endif
195
196 #ifndef NSAccessibilityDatetimeValueAttribute
197 #define NSAccessibilityDatetimeValueAttribute @"AXDateTimeValue"
198 #endif
199
200 #ifndef NSAccessibilityInlineTextAttribute
201 #define NSAccessibilityInlineTextAttribute @"AXInlineText"
202 #endif
203
204 #ifndef NSAccessibilityDropEffectsAttribute
205 #define NSAccessibilityDropEffectsAttribute @"AXDropEffects"
206 #endif
207
208 #ifndef NSAccessibilityARIALiveAttribute
209 #define NSAccessibilityARIALiveAttribute @"AXARIALive"
210 #endif
211
212 #ifndef NSAccessibilityARIAAtomicAttribute
213 #define NSAccessibilityARIAAtomicAttribute @"AXARIAAtomic"
214 #endif
215
216 #ifndef NSAccessibilityARIARelevantAttribute
217 #define NSAccessibilityARIARelevantAttribute @"AXARIARelevant"
218 #endif
219
220 #ifndef NSAccessibilityElementBusyAttribute
221 #define NSAccessibilityElementBusyAttribute @"AXElementBusy"
222 #endif
223
224 #ifndef NSAccessibilityARIAPosInSetAttribute
225 #define NSAccessibilityARIAPosInSetAttribute @"AXARIAPosInSet"
226 #endif
227
228 #ifndef NSAccessibilityARIASetSizeAttribute
229 #define NSAccessibilityARIASetSizeAttribute @"AXARIASetSize"
230 #endif
231
232 #ifndef NSAccessibilityLoadingProgressAttribute
233 #define NSAccessibilityLoadingProgressAttribute @"AXLoadingProgress"
234 #endif
235
236 #ifndef NSAccessibilityHasPopupAttribute
237 #define NSAccessibilityHasPopupAttribute @"AXHasPopup"
238 #endif
239
240 #ifndef NSAccessibilityPopupValueAttribute
241 #define NSAccessibilityPopupValueAttribute @"AXPopupValue"
242 #endif
243
244 #ifndef NSAccessibilityPlaceholderValueAttribute
245 #define NSAccessibilityPlaceholderValueAttribute @"AXPlaceholderValue"
246 #endif
247
248 #define NSAccessibilityTextMarkerIsValidParameterizedAttribute @"AXTextMarkerIsValid"
249 #define NSAccessibilityIndexForTextMarkerParameterizedAttribute @"AXIndexForTextMarker"
250 #define NSAccessibilityTextMarkerForIndexParameterizedAttribute @"AXTextMarkerForIndex"
251
252 #ifndef NSAccessibilityScrollToVisibleAction
253 #define NSAccessibilityScrollToVisibleAction @"AXScrollToVisible"
254 #endif
255
256 #ifndef NSAccessibilityPathAttribute
257 #define NSAccessibilityPathAttribute @"AXPath"
258 #endif
259
260 #ifndef NSAccessibilityExpandedTextValueAttribute
261 #define NSAccessibilityExpandedTextValueAttribute @"AXExpandedTextValue"
262 #endif
263
264 #ifndef NSAccessibilityIsMultiSelectableAttribute
265 #define NSAccessibilityIsMultiSelectableAttribute @"AXIsMultiSelectable"
266 #endif
267
268 #ifndef NSAccessibilityDocumentURIAttribute
269 #define NSAccessibilityDocumentURIAttribute @"AXDocumentURI"
270 #endif
271
272 #ifndef NSAccessibilityDocumentEncodingAttribute
273 #define NSAccessibilityDocumentEncodingAttribute @"AXDocumentEncoding"
274 #endif
275
276 #ifndef NSAccessibilityAriaControlsAttribute
277 #define NSAccessibilityAriaControlsAttribute @"AXARIAControls"
278 #endif
279
280 #define NSAccessibilityDOMIdentifierAttribute @"AXDOMIdentifier"
281 #define NSAccessibilityDOMClassListAttribute @"AXDOMClassList"
282
283 #ifndef NSAccessibilityARIACurrentAttribute
284 #define NSAccessibilityARIACurrentAttribute @"AXARIACurrent"
285 #endif
286
287 // Table/grid attributes
288 #ifndef NSAccessibilityARIAColumnIndexAttribute
289 #define NSAccessibilityARIAColumnIndexAttribute @"AXARIAColumnIndex"
290 #endif
291
292 #ifndef NSAccessibilityARIARowIndexAttribute
293 #define NSAccessibilityARIARowIndexAttribute @"AXARIARowIndex"
294 #endif
295
296 #ifndef NSAccessibilityARIAColumnCountAttribute
297 #define NSAccessibilityARIAColumnCountAttribute @"AXARIAColumnCount"
298 #endif
299
300 #ifndef NSAccessibilityARIARowCountAttribute
301 #define NSAccessibilityARIARowCountAttribute @"AXARIARowCount"
302 #endif
303
304
305 #ifndef NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute
306 #define NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute @"AXUIElementCountForSearchPredicate"
307 #endif
308
309 #ifndef NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute
310 #define NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute @"AXUIElementsForSearchPredicate"
311 #endif
312
313 // Text markers
314 #ifndef NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute
315 #define NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute @"AXEndTextMarkerForBounds"
316 #endif
317
318 #ifndef NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute
319 #define NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute @"AXStartTextMarkerForBounds"
320 #endif
321
322 #ifndef NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute
323 #define NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute @"AXLineTextMarkerRangeForTextMarker"
324 #endif
325
326 #ifndef NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute
327 #define NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute @"AXMisspellingTextMarkerRange"
328 #endif
329
330 // Text selection
331 #ifndef NSAccessibilitySelectTextActivity
332 #define NSAccessibilitySelectTextActivity @"AXSelectTextActivity"
333 #endif
334
335 #ifndef NSAccessibilitySelectTextActivityFindAndReplace
336 #define NSAccessibilitySelectTextActivityFindAndReplace @"AXSelectTextActivityFindAndReplace"
337 #endif
338
339 #ifndef NSAccessibilitySelectTextActivityFindAndSelect
340 #define NSAccessibilitySelectTextActivityFindAndSelect @"AXSelectTextActivityFindAndSelect"
341 #endif
342
343 #ifndef kAXSelectTextActivityFindAndCapitalize
344 #define kAXSelectTextActivityFindAndCapitalize @"AXSelectTextActivityFindAndCapitalize"
345 #endif
346
347 #ifndef kAXSelectTextActivityFindAndLowercase
348 #define kAXSelectTextActivityFindAndLowercase @"AXSelectTextActivityFindAndLowercase"
349 #endif
350
351 #ifndef kAXSelectTextActivityFindAndUppercase
352 #define kAXSelectTextActivityFindAndUppercase @"AXSelectTextActivityFindAndUppercase"
353 #endif
354
355 #ifndef NSAccessibilitySelectTextAmbiguityResolution
356 #define NSAccessibilitySelectTextAmbiguityResolution @"AXSelectTextAmbiguityResolution"
357 #endif
358
359 #ifndef NSAccessibilitySelectTextAmbiguityResolutionClosestAfterSelection
360 #define NSAccessibilitySelectTextAmbiguityResolutionClosestAfterSelection @"AXSelectTextAmbiguityResolutionClosestAfterSelection"
361 #endif
362
363 #ifndef NSAccessibilitySelectTextAmbiguityResolutionClosestBeforeSelection
364 #define NSAccessibilitySelectTextAmbiguityResolutionClosestBeforeSelection @"AXSelectTextAmbiguityResolutionClosestBeforeSelection"
365 #endif
366
367 #ifndef NSAccessibilitySelectTextAmbiguityResolutionClosestToSelection
368 #define NSAccessibilitySelectTextAmbiguityResolutionClosestToSelection @"AXSelectTextAmbiguityResolutionClosestToSelection"
369 #endif
370
371 #ifndef NSAccessibilitySelectTextReplacementString
372 #define NSAccessibilitySelectTextReplacementString @"AXSelectTextReplacementString"
373 #endif
374
375 #ifndef NSAccessibilitySelectTextSearchStrings
376 #define NSAccessibilitySelectTextSearchStrings @"AXSelectTextSearchStrings"
377 #endif
378
379 #ifndef NSAccessibilitySelectTextWithCriteriaParameterizedAttribute
380 #define NSAccessibilitySelectTextWithCriteriaParameterizedAttribute @"AXSelectTextWithCriteria"
381 #endif
382
383 // Text search
384
385 #ifndef NSAccessibilitySearchTextWithCriteriaParameterizedAttribute
386 /* Performs a text search with the given parameters.
387  Returns an NSArray of text marker ranges of the search hits.
388  */
389 #define NSAccessibilitySearchTextWithCriteriaParameterizedAttribute @"AXSearchTextWithCriteria"
390 #endif
391
392 #ifndef NSAccessibilitySearchTextSearchStrings
393 // NSArray of strings to search for.
394 #define NSAccessibilitySearchTextSearchStrings @"AXSearchTextSearchStrings"
395 #endif
396
397 #ifndef NSAccessibilitySearchTextStartFrom
398 // NSString specifying the start point of the search: selection, begin or end.
399 #define NSAccessibilitySearchTextStartFrom @"AXSearchTextStartFrom"
400 #endif
401
402 #ifndef NSAccessibilitySearchTextStartFromBegin
403 // Value for SearchTextStartFrom.
404 #define NSAccessibilitySearchTextStartFromBegin @"AXSearchTextStartFromBegin"
405 #endif
406
407 #ifndef NSAccessibilitySearchTextStartFromSelection
408 // Value for SearchTextStartFrom.
409 #define NSAccessibilitySearchTextStartFromSelection @"AXSearchTextStartFromSelection"
410 #endif
411
412 #ifndef NSAccessibilitySearchTextStartFromEnd
413 // Value for SearchTextStartFrom.
414 #define NSAccessibilitySearchTextStartFromEnd @"AXSearchTextStartFromEnd"
415 #endif
416
417 #ifndef NSAccessibilitySearchTextDirection
418 // NSString specifying the direction of the search: forward, backward, closest, all.
419 #define NSAccessibilitySearchTextDirection @"AXSearchTextDirection"
420 #endif
421
422 #ifndef NSAccessibilitySearchTextDirectionForward
423 // Value for SearchTextDirection.
424 #define NSAccessibilitySearchTextDirectionForward @"AXSearchTextDirectionForward"
425 #endif
426
427 #ifndef NSAccessibilitySearchTextDirectionBackward
428 // Value for SearchTextDirection.
429 #define NSAccessibilitySearchTextDirectionBackward @"AXSearchTextDirectionBackward"
430 #endif
431
432 #ifndef NSAccessibilitySearchTextDirectionClosest
433 // Value for SearchTextDirection.
434 #define NSAccessibilitySearchTextDirectionClosest @"AXSearchTextDirectionClosest"
435 #endif
436
437 #ifndef NSAccessibilitySearchTextDirectionAll
438 // Value for SearchTextDirection.
439 #define NSAccessibilitySearchTextDirectionAll @"AXSearchTextDirectionAll"
440 #endif
441
442 // Text operations
443
444 #ifndef NSAccessibilityTextOperationParameterizedAttribute
445 // Performs an operation on the given text.
446 #define NSAccessibilityTextOperationParameterizedAttribute @"AXTextOperation"
447 #endif
448
449 #ifndef NSAccessibilityTextOperationMarkerRanges
450 // Text on which to perform operation.
451 #define NSAccessibilityTextOperationMarkerRanges @"AXTextOperationMarkerRanges"
452 #endif
453
454 #ifndef NSAccessibilityTextOperationType
455 // The type of operation to be performed: select, replace, capitalize....
456 #define NSAccessibilityTextOperationType @"AXTextOperationType"
457 #endif
458
459 #ifndef NSAccessibilityTextOperationSelect
460 // Value for TextOperationType.
461 #define NSAccessibilityTextOperationSelect @"TextOperationSelect"
462 #endif
463
464 #ifndef NSAccessibilityTextOperationReplace
465 // Value for TextOperationType.
466 #define NSAccessibilityTextOperationReplace @"TextOperationReplace"
467 #endif
468
469 #ifndef NSAccessibilityTextOperationCapitalize
470 // Value for TextOperationType.
471 #define NSAccessibilityTextOperationCapitalize @"Capitalize"
472 #endif
473
474 #ifndef NSAccessibilityTextOperationLowercase
475 // Value for TextOperationType.
476 #define NSAccessibilityTextOperationLowercase @"Lowercase"
477 #endif
478
479 #ifndef NSAccessibilityTextOperationUppercase
480 // Value for TextOperationType.
481 #define NSAccessibilityTextOperationUppercase @"Uppercase"
482 #endif
483
484 #ifndef NSAccessibilityTextOperationReplacementString
485 // Replacement text for operation replace.
486 #define NSAccessibilityTextOperationReplacementString @"AXTextOperationReplacementString"
487 #endif
488
489 // Math attributes
490 #define NSAccessibilityMathRootRadicandAttribute @"AXMathRootRadicand"
491 #define NSAccessibilityMathRootIndexAttribute @"AXMathRootIndex"
492 #define NSAccessibilityMathFractionDenominatorAttribute @"AXMathFractionDenominator"
493 #define NSAccessibilityMathFractionNumeratorAttribute @"AXMathFractionNumerator"
494 #define NSAccessibilityMathBaseAttribute @"AXMathBase"
495 #define NSAccessibilityMathSubscriptAttribute @"AXMathSubscript"
496 #define NSAccessibilityMathSuperscriptAttribute @"AXMathSuperscript"
497 #define NSAccessibilityMathUnderAttribute @"AXMathUnder"
498 #define NSAccessibilityMathOverAttribute @"AXMathOver"
499 #define NSAccessibilityMathFencedOpenAttribute @"AXMathFencedOpen"
500 #define NSAccessibilityMathFencedCloseAttribute @"AXMathFencedClose"
501 #define NSAccessibilityMathLineThicknessAttribute @"AXMathLineThickness"
502 #define NSAccessibilityMathPrescriptsAttribute @"AXMathPrescripts"
503 #define NSAccessibilityMathPostscriptsAttribute @"AXMathPostscripts"
504
505 #ifndef NSAccessibilityPreventKeyboardDOMEventDispatchAttribute
506 #define NSAccessibilityPreventKeyboardDOMEventDispatchAttribute @"AXPreventKeyboardDOMEventDispatch"
507 #endif
508
509 #ifndef NSAccessibilityCaretBrowsingEnabledAttribute
510 #define NSAccessibilityCaretBrowsingEnabledAttribute @"AXCaretBrowsingEnabled"
511 #endif
512
513 #ifndef NSAccessibilityWebSessionIDAttribute
514 #define NSAccessibilityWebSessionIDAttribute @"AXWebSessionID"
515 #endif
516
517 #ifndef NSAccessibilitFocusableAncestorAttribute
518 #define NSAccessibilityFocusableAncestorAttribute @"AXFocusableAncestor"
519 #endif
520
521 #ifndef NSAccessibilityEditableAncestorAttribute
522 #define NSAccessibilityEditableAncestorAttribute @"AXEditableAncestor"
523 #endif
524
525 #ifndef NSAccessibilityHighestEditableAncestorAttribute
526 #define NSAccessibilityHighestEditableAncestorAttribute @"AXHighestEditableAncestor"
527 #endif
528
529 #ifndef NSAccessibilityLinkRelationshipTypeAttribute
530 #define NSAccessibilityLinkRelationshipTypeAttribute @"AXLinkRelationshipType"
531 #endif
532
533 #ifndef NSAccessibilityRelativeFrameAttribute
534 #define NSAccessibilityRelativeFrameAttribute @"AXRelativeFrame"
535 #endif
536
537 #define _axBackingObject self.axBackingObject
538
539 extern "C" AXUIElementRef NSAccessibilityCreateAXUIElementRef(id element);
540
541 @implementation WebAccessibilityObjectWrapper
542
543 - (void)unregisterUniqueIdForUIElement
544 {
545     NSAccessibilityUnregisterUniqueIdForUIElement(self);
546 }
547
548 - (void)detach
549 {
550     // Send unregisterUniqueIdForUIElement unconditionally because if it is
551     // ever accidentally not done (via other bugs in our AX implementation) you
552     // end up with a crash like <rdar://problem/4273149>.  It is safe and not
553     // expensive to send even if the object is not registered.
554     [self unregisterUniqueIdForUIElement];
555     [super detach];
556 }
557
558 - (id)attachmentView
559 {
560     ASSERT(m_object->isAttachment());
561     Widget* widget = m_object->widgetForAttachmentView();
562     if (!widget)
563         return nil;
564     return NSAccessibilityUnignoredDescendant(widget->platformWidget());
565 }
566
567 #pragma mark SystemInterface wrappers
568
569 static inline BOOL AXObjectIsTextMarker(id object)
570 {
571     return object && CFGetTypeID((__bridge CFTypeRef)object) == AXTextMarkerGetTypeID();
572 }
573
574 static inline BOOL AXObjectIsTextMarkerRange(id object)
575 {
576     return object && CFGetTypeID((__bridge CFTypeRef)object) == AXTextMarkerRangeGetTypeID();
577 }
578
579 static id AXTextMarkerRange(id startMarker, id endMarker)
580 {
581     ASSERT(startMarker != nil);
582     ASSERT(endMarker != nil);
583     ASSERT(CFGetTypeID((__bridge CFTypeRef)startMarker) == AXTextMarkerGetTypeID());
584     ASSERT(CFGetTypeID((__bridge CFTypeRef)endMarker) == AXTextMarkerGetTypeID());
585     return CFBridgingRelease(AXTextMarkerRangeCreate(kCFAllocatorDefault, (AXTextMarkerRef)startMarker, (AXTextMarkerRef)endMarker));
586 }
587
588 static id AXTextMarkerRangeStart(id range)
589 {
590     ASSERT(range != nil);
591     ASSERT(CFGetTypeID((__bridge CFTypeRef)range) == AXTextMarkerRangeGetTypeID());
592     return CFBridgingRelease(AXTextMarkerRangeCopyStartMarker((AXTextMarkerRangeRef)range));
593 }
594
595 static id AXTextMarkerRangeEnd(id range)
596 {
597     ASSERT(range != nil);
598     ASSERT(CFGetTypeID((__bridge CFTypeRef)range) == AXTextMarkerRangeGetTypeID());
599     return CFBridgingRelease(AXTextMarkerRangeCopyEndMarker((AXTextMarkerRangeRef)range));
600 }
601
602 #pragma mark Other helpers
603
604 - (IntRect)screenToContents:(const IntRect&)rect
605 {
606     Document* document = m_object->document();
607     if (!document)
608         return IntRect();
609     
610     FrameView* frameView = document->view();
611     if (!frameView)
612         return IntRect();
613     
614     IntPoint startPoint = frameView->screenToContents(rect.minXMaxYCorner());
615     IntPoint endPoint = frameView->screenToContents(rect.maxXMinYCorner());
616     return IntRect(startPoint.x(), startPoint.y(), endPoint.x() - startPoint.x(), endPoint.y() - startPoint.y());
617 }
618
619 #pragma mark Select text helpers
620
621 // To be deprecated.
622 static std::pair<AccessibilitySearchTextCriteria, AccessibilityTextOperation> accessibilityTextCriteriaForParameterizedAttribute(const NSDictionary *parameterizedAttribute)
623 {
624     AccessibilitySearchTextCriteria criteria;
625     AccessibilityTextOperation operation;
626
627     NSString *activityParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextActivity];
628     NSString *ambiguityResolutionParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextAmbiguityResolution];
629     NSString *replacementStringParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextReplacementString];
630     NSArray *searchStringsParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextSearchStrings];
631
632     if ([activityParameter isKindOfClass:[NSString class]]) {
633         if ([activityParameter isEqualToString:NSAccessibilitySelectTextActivityFindAndReplace])
634             operation.type = AccessibilityTextOperationType::Replace;
635         else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndCapitalize])
636             operation.type = AccessibilityTextOperationType::Capitalize;
637         else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndLowercase])
638             operation.type = AccessibilityTextOperationType::Lowercase;
639         else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndUppercase])
640             operation.type = AccessibilityTextOperationType::Uppercase;
641     }
642
643     criteria.direction = AccessibilitySearchTextDirection::Closest;
644     if ([ambiguityResolutionParameter isKindOfClass:[NSString class]]) {
645         if ([ambiguityResolutionParameter isEqualToString:NSAccessibilitySelectTextAmbiguityResolutionClosestAfterSelection])
646             criteria.direction = AccessibilitySearchTextDirection::Forward;
647         else if ([ambiguityResolutionParameter isEqualToString:NSAccessibilitySelectTextAmbiguityResolutionClosestBeforeSelection])
648             criteria.direction = AccessibilitySearchTextDirection::Backward;
649     }
650
651     if ([replacementStringParameter isKindOfClass:[NSString class]])
652         operation.replacementText = replacementStringParameter;
653
654     if ([searchStringsParameter isKindOfClass:[NSArray class]]) {
655         size_t searchStringsCount = static_cast<size_t>([searchStringsParameter count]);
656         criteria.searchStrings.reserveInitialCapacity(searchStringsCount);
657         for (NSString *searchString in searchStringsParameter) {
658             if ([searchString isKindOfClass:[NSString class]])
659                 criteria.searchStrings.uncheckedAppend(searchString);
660         }
661     }
662
663     return std::make_pair(criteria, operation);
664 }
665
666 static AccessibilitySearchTextCriteria accessibilitySearchTextCriteriaForParameterizedAttribute(const NSDictionary *params)
667 {
668     AccessibilitySearchTextCriteria criteria;
669
670     NSArray *searchStrings = [params objectForKey:NSAccessibilitySearchTextSearchStrings];
671     NSString *start = [params objectForKey:NSAccessibilitySearchTextStartFrom];
672     NSString *direction = [params objectForKey:NSAccessibilitySearchTextDirection];
673
674     if ([searchStrings isKindOfClass:[NSArray class]]) {
675         size_t searchStringsCount = static_cast<size_t>([searchStrings count]);
676         criteria.searchStrings.reserveInitialCapacity(searchStringsCount);
677         for (NSString *searchString in searchStrings) {
678             if ([searchString isKindOfClass:[NSString class]])
679                 criteria.searchStrings.uncheckedAppend(searchString);
680         }
681     }
682
683     if ([start isKindOfClass:[NSString class]]) {
684         if ([start isEqualToString:NSAccessibilitySearchTextStartFromBegin])
685             criteria.start = AccessibilitySearchTextStartFrom::Begin;
686         else if ([start isEqualToString:NSAccessibilitySearchTextStartFromEnd])
687             criteria.start = AccessibilitySearchTextStartFrom::End;
688     }
689
690     if ([direction isKindOfClass:[NSString class]]) {
691         if ([direction isEqualToString:NSAccessibilitySearchTextDirectionBackward])
692             criteria.direction = AccessibilitySearchTextDirection::Backward;
693         else if ([direction isEqualToString:NSAccessibilitySearchTextDirectionClosest])
694             criteria.direction = AccessibilitySearchTextDirection::Closest;
695         else if ([direction isEqualToString:NSAccessibilitySearchTextDirectionAll])
696             criteria.direction = AccessibilitySearchTextDirection::All;
697     }
698
699     return criteria;
700 }
701
702 static AccessibilityTextOperation accessibilityTextOperationForParameterizedAttribute(WebAccessibilityObjectWrapper *obj, const NSDictionary *parameterizedAttribute)
703 {
704     AccessibilityTextOperation operation;
705
706     NSArray *markerRanges = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationMarkerRanges];
707     NSString *operationType = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationType];
708     NSString *replacementString = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationReplacementString];
709
710     if ([markerRanges isKindOfClass:[NSArray class]]) {
711         size_t count = static_cast<size_t>(markerRanges.count);
712         operation.textRanges.reserveInitialCapacity(count);
713         for (id markerRange : markerRanges)
714             operation.textRanges.append([obj rangeForTextMarkerRange:markerRange]);
715     }
716
717     if ([operationType isKindOfClass:[NSString class]]) {
718         if ([operationType isEqualToString:NSAccessibilityTextOperationReplace])
719             operation.type = AccessibilityTextOperationType::Replace;
720         else if ([operationType isEqualToString:NSAccessibilityTextOperationCapitalize])
721             operation.type = AccessibilityTextOperationType::Capitalize;
722         else if ([operationType isEqualToString:NSAccessibilityTextOperationLowercase])
723             operation.type = AccessibilityTextOperationType::Lowercase;
724         else if ([operationType isEqualToString:NSAccessibilityTextOperationUppercase])
725             operation.type = AccessibilityTextOperationType::Uppercase;
726     }
727
728     if ([replacementString isKindOfClass:[NSString class]])
729         operation.replacementText = replacementString;
730
731     return operation;
732 }
733
734 static std::pair<RefPtr<Range>, AccessibilitySearchDirection> accessibilityMisspellingSearchCriteriaForParameterizedAttribute(WebAccessibilityObjectWrapper *object, const NSDictionary *params)
735 {
736     std::pair<RefPtr<Range>, AccessibilitySearchDirection> criteria;
737
738     criteria.first = [object rangeForTextMarkerRange:[params objectForKey:@"AXStartTextMarkerRange"]];
739
740     NSNumber *forward = [params objectForKey:NSAccessibilitySearchTextDirection];
741     if ([forward isKindOfClass:[NSNumber class]])
742         criteria.second = [forward boolValue] ? AccessibilitySearchDirection::Next : AccessibilitySearchDirection::Previous;
743     else
744         criteria.second = AccessibilitySearchDirection::Next;
745
746     return criteria;
747 }
748
749 #pragma mark Text Marker helpers
750
751 static BOOL getBytesFromAXTextMarker(CFTypeRef textMarker, void* bytes, size_t length)
752 {
753     if (!textMarker)
754         return NO;
755
756     AXTextMarkerRef ref = (AXTextMarkerRef)textMarker;
757     ASSERT(CFGetTypeID(ref) == AXTextMarkerGetTypeID());
758     if (CFGetTypeID(ref) != AXTextMarkerGetTypeID())
759         return NO;
760
761     CFIndex expectedLength = length;
762     if (AXTextMarkerGetLength(ref) != expectedLength)
763         return NO;
764
765     memcpy(bytes, AXTextMarkerGetBytePtr(ref), length);
766     return YES;
767 }
768
769 static bool isTextMarkerIgnored(id textMarker)
770 {
771     if (!textMarker)
772         return false;
773     
774     TextMarkerData textMarkerData;
775     if (!getBytesFromAXTextMarker((__bridge CFTypeRef)textMarker, &textMarkerData, sizeof(textMarkerData)))
776         return false;
777     
778     return textMarkerData.ignored;
779 }
780
781 - (AccessibilityObject*)accessibilityObjectForTextMarker:(id)textMarker
782 {
783     return accessibilityObjectForTextMarker(m_object->axObjectCache(), textMarker);
784 }
785
786 static AccessibilityObject* accessibilityObjectForTextMarker(AXObjectCache* cache, id textMarker)
787 {
788     if (!textMarker || !cache || isTextMarkerIgnored(textMarker))
789         return nullptr;
790     
791     TextMarkerData textMarkerData;
792     if (!getBytesFromAXTextMarker((__bridge CFTypeRef)textMarker, &textMarkerData, sizeof(textMarkerData)))
793         return nullptr;
794     return cache->accessibilityObjectForTextMarkerData(textMarkerData);
795 }
796
797 - (id)textMarkerRangeFromRange:(const RefPtr<Range>)range
798 {
799     return textMarkerRangeFromRange(m_object->axObjectCache(), range);
800 }
801
802 static id textMarkerRangeFromRange(AXObjectCache* cache, const RefPtr<Range> range)
803 {
804     id startTextMarker = startOrEndTextmarkerForRange(cache, range, true);
805     id endTextMarker = startOrEndTextmarkerForRange(cache, range, false);
806     return textMarkerRangeFromMarkers(startTextMarker, endTextMarker);
807 }
808
809 - (id)startOrEndTextMarkerForRange:(const RefPtr<Range>)range isStart:(BOOL)isStart
810 {
811     return startOrEndTextmarkerForRange(m_object->axObjectCache(), range, isStart);
812 }
813
814 static id startOrEndTextmarkerForRange(AXObjectCache* cache, RefPtr<Range> range, bool isStart)
815 {
816     if (!cache)
817         return nil;
818     
819     TextMarkerData textMarkerData;
820     cache->startOrEndTextMarkerDataForRange(textMarkerData, range, isStart);
821     if (!textMarkerData.axID)
822         return nil;
823     
824     return CFBridgingRelease(AXTextMarkerCreate(kCFAllocatorDefault, (const UInt8*)&textMarkerData, sizeof(textMarkerData)));
825 }
826
827 static id nextTextMarkerForCharacterOffset(AXObjectCache* cache, CharacterOffset& characterOffset)
828 {
829     if (!cache)
830         return nil;
831     
832     TextMarkerData textMarkerData;
833     cache->textMarkerDataForNextCharacterOffset(textMarkerData, characterOffset);
834     if (!textMarkerData.axID)
835         return nil;
836     return CFBridgingRelease(AXTextMarkerCreate(kCFAllocatorDefault, (const UInt8*)&textMarkerData, sizeof(textMarkerData)));
837 }
838
839 static id previousTextMarkerForCharacterOffset(AXObjectCache* cache, CharacterOffset& characterOffset)
840 {
841     if (!cache)
842         return nil;
843     
844     TextMarkerData textMarkerData;
845     cache->textMarkerDataForPreviousCharacterOffset(textMarkerData, characterOffset);
846     if (!textMarkerData.axID)
847         return nil;
848     return CFBridgingRelease(AXTextMarkerCreate(kCFAllocatorDefault, (const UInt8*)&textMarkerData, sizeof(textMarkerData)));
849 }
850
851 - (id)nextTextMarkerForCharacterOffset:(CharacterOffset&)characterOffset
852 {
853     return nextTextMarkerForCharacterOffset(m_object->axObjectCache(), characterOffset);
854 }
855
856 - (id)previousTextMarkerForCharacterOffset:(CharacterOffset&)characterOffset
857 {
858     return previousTextMarkerForCharacterOffset(m_object->axObjectCache(), characterOffset);
859 }
860
861 - (id)textMarkerForCharacterOffset:(CharacterOffset&)characterOffset
862 {
863     return textMarkerForCharacterOffset(m_object->axObjectCache(), characterOffset);
864 }
865
866 static id textMarkerForCharacterOffset(AXObjectCache* cache, const CharacterOffset& characterOffset)
867 {
868     if (!cache)
869         return nil;
870     
871     TextMarkerData textMarkerData;
872     cache->textMarkerDataForCharacterOffset(textMarkerData, characterOffset);
873     if (!textMarkerData.axID && !textMarkerData.ignored)
874         return nil;
875     
876     return CFBridgingRelease(AXTextMarkerCreate(kCFAllocatorDefault, (const UInt8*)&textMarkerData, sizeof(textMarkerData)));
877 }
878
879 - (RefPtr<Range>)rangeForTextMarkerRange:(id)textMarkerRange
880 {
881     if (!textMarkerRange)
882         return nullptr;
883     
884     id startTextMarker = AXTextMarkerRangeStart(textMarkerRange);
885     id endTextMarker = AXTextMarkerRangeEnd(textMarkerRange);
886     
887     if (!startTextMarker || !endTextMarker)
888         return nullptr;
889     
890     AXObjectCache* cache = m_object->axObjectCache();
891     if (!cache)
892         return nullptr;
893     
894     CharacterOffset startCharacterOffset = [self characterOffsetForTextMarker:startTextMarker];
895     CharacterOffset endCharacterOffset = [self characterOffsetForTextMarker:endTextMarker];
896     return cache->rangeForUnorderedCharacterOffsets(startCharacterOffset, endCharacterOffset);
897 }
898
899 static CharacterOffset characterOffsetForTextMarker(AXObjectCache* cache, CFTypeRef textMarker)
900 {
901     if (!cache || !textMarker)
902         return CharacterOffset();
903     
904     TextMarkerData textMarkerData;
905     if (!getBytesFromAXTextMarker(textMarker, &textMarkerData, sizeof(textMarkerData)))
906         return CharacterOffset();
907     
908     return cache->characterOffsetForTextMarkerData(textMarkerData);
909 }
910
911 - (CharacterOffset)characterOffsetForTextMarker:(id)textMarker
912 {
913     return characterOffsetForTextMarker(m_object->axObjectCache(), (__bridge CFTypeRef)textMarker);
914 }
915
916 static id textMarkerForVisiblePosition(AXObjectCache* cache, const VisiblePosition& visiblePos)
917 {
918     ASSERT(cache);
919     if (!cache)
920         return nil;
921     
922     auto textMarkerData = cache->textMarkerDataForVisiblePosition(visiblePos);
923     if (!textMarkerData)
924         return nil;
925
926     return CFBridgingRelease(AXTextMarkerCreate(kCFAllocatorDefault, (const UInt8*)&textMarkerData.value(), sizeof(textMarkerData.value())));
927 }
928
929 - (id)textMarkerForVisiblePosition:(const VisiblePosition &)visiblePos
930 {
931     return textMarkerForVisiblePosition(m_object->axObjectCache(), visiblePos);
932 }
933
934 - (id)textMarkerForFirstPositionInTextControl:(HTMLTextFormControlElement &)textControl
935 {
936     auto *cache = m_object->axObjectCache();
937     if (!cache)
938         return nil;
939
940     auto textMarkerData = cache->textMarkerDataForFirstPositionInTextControl(textControl);
941     if (!textMarkerData)
942         return nil;
943
944     return CFBridgingRelease(AXTextMarkerCreate(kCFAllocatorDefault, (const UInt8*)&textMarkerData.value(), sizeof(textMarkerData.value())));
945 }
946
947 static VisiblePosition visiblePositionForTextMarker(AXObjectCache* cache, CFTypeRef textMarker)
948 {
949     ASSERT(cache);
950     
951     if (!textMarker)
952         return VisiblePosition();
953     TextMarkerData textMarkerData;
954     if (!getBytesFromAXTextMarker(textMarker, &textMarkerData, sizeof(textMarkerData)))
955         return VisiblePosition();
956     
957     return cache->visiblePositionForTextMarkerData(textMarkerData);
958 }
959
960 - (VisiblePosition)visiblePositionForTextMarker:(id)textMarker
961 {
962     return visiblePositionForTextMarker(m_object->axObjectCache(), (__bridge CFTypeRef)textMarker);
963 }
964
965 static VisiblePosition visiblePositionForStartOfTextMarkerRange(AXObjectCache* cache, id textMarkerRange)
966 {
967     return visiblePositionForTextMarker(cache, (__bridge CFTypeRef)AXTextMarkerRangeStart(textMarkerRange));
968 }
969
970 static VisiblePosition visiblePositionForEndOfTextMarkerRange(AXObjectCache* cache, id textMarkerRange)
971 {
972     return visiblePositionForTextMarker(cache, (__bridge CFTypeRef)AXTextMarkerRangeEnd(textMarkerRange));
973 }
974
975 static id textMarkerRangeFromMarkers(id textMarker1, id textMarker2)
976 {
977     if (!textMarker1 || !textMarker2)
978         return nil;
979     
980     return AXTextMarkerRange(textMarker1, textMarker2);
981 }
982
983 // When modifying attributed strings, the range can come from a source which may provide faulty information (e.g. the spell checker).
984 // To protect against such cases the range should be validated before adding or removing attributes.
985 static BOOL AXAttributedStringRangeIsValid(NSAttributedString *attrString, NSRange range)
986 {
987     return (range.location < [attrString length] && NSMaxRange(range) <= [attrString length]);
988 }
989
990 static void AXAttributeStringSetFont(NSMutableAttributedString *attrString, NSString *attribute, CTFontRef font, NSRange range)
991 {
992     if (!AXAttributedStringRangeIsValid(attrString, range))
993         return;
994
995     if (font) {
996         NSDictionary *dictionary = @{
997             NSAccessibilityFontNameKey: (__bridge NSString *)adoptCF(CTFontCopyPostScriptName(font)).get(),
998             NSAccessibilityFontFamilyKey: (__bridge NSString *)adoptCF(CTFontCopyFamilyName(font)).get(),
999             NSAccessibilityVisibleNameKey: (__bridge NSString *)adoptCF(CTFontCopyDisplayName(font)).get(),
1000             NSAccessibilityFontSizeKey: @(CTFontGetSize(font)),
1001         };
1002         [attrString addAttribute:attribute value:dictionary range:range];
1003     } else
1004         [attrString removeAttribute:attribute range:range];
1005     
1006 }
1007
1008 static void AXAttributeStringSetColor(NSMutableAttributedString* attrString, NSString* attribute, NSColor* color, NSRange range)
1009 {
1010     if (!AXAttributedStringRangeIsValid(attrString, range))
1011         return;
1012
1013     if (color) {
1014         CGColorRef cgColor = color.CGColor;
1015         id existingColor = [attrString attribute:attribute atIndex:range.location effectiveRange:nil];
1016         if (!existingColor || !CGColorEqualToColor((__bridge CGColorRef)existingColor, cgColor))
1017             [attrString addAttribute:attribute value:(__bridge id)cgColor range:range];
1018     } else
1019         [attrString removeAttribute:attribute range:range];
1020 }
1021
1022 static void AXAttributeStringSetNumber(NSMutableAttributedString* attrString, NSString* attribute, NSNumber* number, NSRange range)
1023 {
1024     if (!AXAttributedStringRangeIsValid(attrString, range))
1025         return;
1026     
1027     if (number)
1028         [attrString addAttribute:attribute value:number range:range];
1029     else
1030         [attrString removeAttribute:attribute range:range];
1031 }
1032
1033 static void AXAttributeStringSetStyle(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
1034 {
1035     const RenderStyle& style = renderer->style();
1036     
1037     // set basic font info
1038     AXAttributeStringSetFont(attrString, NSAccessibilityFontTextAttribute, style.fontCascade().primaryFont().getCTFont(), range);
1039     
1040     // set basic colors
1041     AXAttributeStringSetColor(attrString, NSAccessibilityForegroundColorTextAttribute, nsColor(style.visitedDependentColor(CSSPropertyColor)), range);
1042     AXAttributeStringSetColor(attrString, NSAccessibilityBackgroundColorTextAttribute, nsColor(style.visitedDependentColor(CSSPropertyBackgroundColor)), range);
1043     
1044     // set super/sub scripting
1045     VerticalAlign alignment = style.verticalAlign();
1046     if (alignment == VerticalAlign::Sub)
1047         AXAttributeStringSetNumber(attrString, NSAccessibilitySuperscriptTextAttribute, [NSNumber numberWithInt:(-1)], range);
1048     else if (alignment == VerticalAlign::Super)
1049         AXAttributeStringSetNumber(attrString, NSAccessibilitySuperscriptTextAttribute, [NSNumber numberWithInt:1], range);
1050     else
1051         [attrString removeAttribute:NSAccessibilitySuperscriptTextAttribute range:range];
1052     
1053     // set shadow
1054     if (style.textShadow())
1055         AXAttributeStringSetNumber(attrString, NSAccessibilityShadowTextAttribute, @YES, range);
1056     else
1057         [attrString removeAttribute:NSAccessibilityShadowTextAttribute range:range];
1058     
1059     // set underline and strikethrough
1060     auto decor = style.textDecorationsInEffect();
1061     if (!(decor & TextDecoration::Underline)) {
1062         [attrString removeAttribute:NSAccessibilityUnderlineTextAttribute range:range];
1063         [attrString removeAttribute:NSAccessibilityUnderlineColorTextAttribute range:range];
1064     }
1065     
1066     if (!(decor & TextDecoration::LineThrough)) {
1067         [attrString removeAttribute:NSAccessibilityStrikethroughTextAttribute range:range];
1068         [attrString removeAttribute:NSAccessibilityStrikethroughColorTextAttribute range:range];
1069     }
1070
1071     if (decor & TextDecoration::Underline || decor & TextDecoration::LineThrough) {
1072         // FIXME: Should the underline style be reported here?
1073         auto decorationStyles = TextDecorationPainter::stylesForRenderer(*renderer, decor);
1074
1075         if (decor & TextDecoration::Underline) {
1076             AXAttributeStringSetNumber(attrString, NSAccessibilityUnderlineTextAttribute, @YES, range);
1077             AXAttributeStringSetColor(attrString, NSAccessibilityUnderlineColorTextAttribute, nsColor(decorationStyles.underlineColor), range);
1078         }
1079         
1080         if (decor & TextDecoration::LineThrough) {
1081             AXAttributeStringSetNumber(attrString, NSAccessibilityStrikethroughTextAttribute, @YES, range);
1082             AXAttributeStringSetColor(attrString, NSAccessibilityStrikethroughColorTextAttribute, nsColor(decorationStyles.linethroughColor), range);
1083         }
1084     }
1085     
1086     // Indicate background highlighting.
1087     for (Node* node = renderer->node(); node; node = node->parentNode()) {
1088         if (node->hasTagName(markTag))
1089             AXAttributeStringSetNumber(attrString, @"AXHighlight", @YES, range);
1090     }
1091 }
1092
1093 static void AXAttributeStringSetBlockquoteLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
1094 {
1095     if (!AXAttributedStringRangeIsValid(attrString, range))
1096         return;
1097     
1098     AccessibilityObject* obj = renderer->document().axObjectCache()->getOrCreate(renderer);
1099     int quoteLevel = obj->blockquoteLevel();
1100     
1101     if (quoteLevel)
1102         [attrString addAttribute:NSAccessibilityBlockQuoteLevelAttribute value:[NSNumber numberWithInt:quoteLevel] range:range];
1103     else
1104         [attrString removeAttribute:NSAccessibilityBlockQuoteLevelAttribute range:range];
1105 }
1106
1107 static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString, Node* node, StringView text, NSRange range)
1108 {
1109     ASSERT(node);
1110     
1111     // If this node is not inside editable content, do not run the spell checker on the text.
1112     if (!node->document().axObjectCache()->rootAXEditableElement(node))
1113         return;
1114
1115     if (unifiedTextCheckerEnabled(node->document().frame())) {
1116         // Check the spelling directly since document->markersForNode() does not store the misspelled marking when the cursor is in a word.
1117         TextCheckerClient* checker = node->document().frame()->editor().textChecker();
1118         
1119         // checkTextOfParagraph is the only spelling/grammar checker implemented in WK1 and WK2
1120         Vector<TextCheckingResult> results;
1121         checkTextOfParagraph(*checker, text, TextCheckingType::Spelling, results, node->document().frame()->selection().selection());
1122         
1123         size_t size = results.size();
1124         for (unsigned i = 0; i < size; i++) {
1125             const TextCheckingResult& result = results[i];
1126             AXAttributeStringSetNumber(attrString, NSAccessibilityMisspelledTextAttribute, @YES, NSMakeRange(result.location + range.location, result.length));
1127 #if PLATFORM(MAC)
1128             AXAttributeStringSetNumber(attrString, NSAccessibilityMarkedMisspelledTextAttribute, @YES, NSMakeRange(result.location + range.location, result.length));
1129 #endif
1130         }
1131         return;
1132     }
1133
1134     for (unsigned currentPosition = 0; currentPosition < text.length(); ) {
1135         int misspellingLocation = -1;
1136         int misspellingLength = 0;
1137         node->document().frame()->editor().textChecker()->checkSpellingOfString(text.substring(currentPosition), &misspellingLocation, &misspellingLength);
1138         if (misspellingLocation == -1 || !misspellingLength)
1139             break;
1140         
1141         NSRange spellRange = NSMakeRange(range.location + currentPosition + misspellingLocation, misspellingLength);
1142         AXAttributeStringSetNumber(attrString, NSAccessibilityMisspelledTextAttribute, @YES, spellRange);
1143 #if PLATFORM(MAC)
1144         AXAttributeStringSetNumber(attrString, NSAccessibilityMarkedMisspelledTextAttribute, @YES, spellRange);
1145 #endif
1146
1147         currentPosition += misspellingLocation + misspellingLength;
1148     }
1149 }
1150
1151 static void AXAttributeStringSetExpandedTextValue(NSMutableAttributedString *attrString, RenderObject* renderer, NSRange range)
1152 {
1153     if (!renderer || !AXAttributedStringRangeIsValid(attrString, range))
1154         return;
1155     AccessibilityObject* axObject = renderer->document().axObjectCache()->getOrCreate(renderer);
1156     if (axObject->supportsExpandedTextValue())
1157         [attrString addAttribute:NSAccessibilityExpandedTextValueAttribute value:axObject->expandedTextValue() range:range];
1158     else
1159         [attrString removeAttribute:NSAccessibilityExpandedTextValueAttribute range:range];
1160 }
1161
1162 static void AXAttributeStringSetHeadingLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
1163 {
1164     if (!renderer)
1165         return;
1166     
1167     if (!AXAttributedStringRangeIsValid(attrString, range))
1168         return;
1169     
1170     // Sometimes there are objects between the text and the heading.
1171     // In those cases the parent hierarchy should be queried to see if there is a heading level.
1172     int parentHeadingLevel = 0;
1173     AccessibilityObject* parentObject = renderer->document().axObjectCache()->getOrCreate(renderer->parent());
1174     for (; parentObject; parentObject = parentObject->parentObject()) {
1175         parentHeadingLevel = parentObject->headingLevel();
1176         if (parentHeadingLevel)
1177             break;
1178     }
1179     
1180     if (parentHeadingLevel)
1181         [attrString addAttribute:@"AXHeadingLevel" value:[NSNumber numberWithInt:parentHeadingLevel] range:range];
1182     else
1183         [attrString removeAttribute:@"AXHeadingLevel" range:range];
1184 }
1185
1186 static void AXAttributeStringSetElement(NSMutableAttributedString* attrString, NSString* attribute, AccessibilityObject* object, NSRange range)
1187 {
1188     if (!AXAttributedStringRangeIsValid(attrString, range))
1189         return;
1190     
1191     if (is<AccessibilityRenderObject>(object)) {
1192         // make a serializable AX object
1193         
1194         RenderObject* renderer = downcast<AccessibilityRenderObject>(*object).renderer();
1195         if (!renderer)
1196             return;
1197         
1198         AXObjectCache* cache = renderer->document().axObjectCache();
1199         if (!cache)
1200             return;
1201         
1202         id objectWrapper = object->wrapper();
1203         if ([attribute isEqualToString:NSAccessibilityAttachmentTextAttribute] && object->isAttachment() && [objectWrapper attachmentView])
1204             objectWrapper = [objectWrapper attachmentView];
1205         
1206         AXUIElementRef axElement = NSAccessibilityCreateAXUIElementRef(objectWrapper);
1207         if (axElement) {
1208             [attrString addAttribute:attribute value:(__bridge id)axElement range:range];
1209             CFRelease(axElement);
1210         }
1211     } else
1212         [attrString removeAttribute:attribute range:range];
1213 }
1214
1215 static void AXAttributedStringAppendText(NSMutableAttributedString* attrString, Node* node, StringView text, bool spellCheck)
1216 {
1217     // skip invisible text
1218     RenderObject* renderer = node->renderer();
1219     if (!renderer)
1220         return;
1221     
1222     // easier to calculate the range before appending the string
1223     NSRange attrStringRange = NSMakeRange([attrString length], text.length());
1224     
1225     // append the string from this node
1226     [[attrString mutableString] appendString:text.createNSStringWithoutCopying().get()];
1227     
1228     // add new attributes and remove irrelevant inherited ones
1229     // NOTE: color attributes are handled specially because -[NSMutableAttributedString addAttribute: value: range:] does not merge
1230     // identical colors.  Workaround is to not replace an existing color attribute if it matches what we are adding.  This also means
1231     // we cannot just pre-remove all inherited attributes on the appended string, so we have to remove the irrelevant ones individually.
1232     
1233     // remove inherited attachment from prior AXAttributedStringAppendReplaced
1234     [attrString removeAttribute:NSAccessibilityAttachmentTextAttribute range:attrStringRange];
1235     if (spellCheck) {
1236 #if PLATFORM(MAC)
1237         [attrString removeAttribute:NSAccessibilityMarkedMisspelledTextAttribute range:attrStringRange];
1238 #endif
1239         [attrString removeAttribute:NSAccessibilityMisspelledTextAttribute range:attrStringRange];
1240     }
1241     
1242     // set new attributes
1243     AXAttributeStringSetStyle(attrString, renderer, attrStringRange);
1244     AXAttributeStringSetHeadingLevel(attrString, renderer, attrStringRange);
1245     AXAttributeStringSetBlockquoteLevel(attrString, renderer, attrStringRange);
1246     AXAttributeStringSetExpandedTextValue(attrString, renderer, attrStringRange);
1247     AXAttributeStringSetElement(attrString, NSAccessibilityLinkTextAttribute, AccessibilityObject::anchorElementForNode(node), attrStringRange);
1248     
1249     // do spelling last because it tends to break up the range
1250     if (spellCheck)
1251         AXAttributeStringSetSpelling(attrString, node, text, attrStringRange);
1252 }
1253
1254 static NSString* nsStringForReplacedNode(Node* replacedNode)
1255 {
1256     // we should always be given a rendered node and a replaced node, but be safe
1257     // replaced nodes are either attachments (widgets) or images
1258     if (!replacedNode || !isRendererReplacedElement(replacedNode->renderer()) || replacedNode->isTextNode()) {
1259         ASSERT_NOT_REACHED();
1260         return nil;
1261     }
1262     
1263     // create an AX object, but skip it if it is not supposed to be seen
1264     RefPtr<AccessibilityObject> obj = replacedNode->renderer()->document().axObjectCache()->getOrCreate(replacedNode->renderer());
1265     if (obj->accessibilityIsIgnored())
1266         return nil;
1267     
1268     // use the attachmentCharacter to represent the replaced node
1269     const UniChar attachmentChar = NSAttachmentCharacter;
1270     return [NSString stringWithCharacters:&attachmentChar length:1];
1271 }
1272
1273 - (NSAttributedString*)doAXAttributedStringForTextMarkerRange:(id)textMarkerRange spellCheck:(BOOL)spellCheck
1274 {
1275     if (!m_object)
1276         return nil;
1277     
1278     RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
1279     NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] init];
1280     TextIterator it(range.get());
1281     while (!it.atEnd()) {
1282         // locate the node and starting offset for this range
1283         Node& node = it.range()->startContainer();
1284         ASSERT(&node == &it.range()->endContainer());
1285         int offset = it.range()->startOffset();
1286         
1287         // non-zero length means textual node, zero length means replaced node (AKA "attachments" in AX)
1288         if (it.text().length()) {
1289             // Add the text of the list marker item if necessary.
1290             String listMarkerText = m_object->listMarkerTextForNodeAndPosition(&node, VisiblePosition(it.range()->startPosition()));
1291             if (!listMarkerText.isEmpty())
1292                 AXAttributedStringAppendText(attrString, &node, listMarkerText, spellCheck);
1293             AXAttributedStringAppendText(attrString, &node, it.text(), spellCheck);
1294         } else {
1295             Node* replacedNode = node.traverseToChildAt(offset);
1296             NSString *attachmentString = nsStringForReplacedNode(replacedNode);
1297             if (attachmentString) {
1298                 NSRange attrStringRange = NSMakeRange([attrString length], [attachmentString length]);
1299                 
1300                 // append the placeholder string
1301                 [[attrString mutableString] appendString:attachmentString];
1302                 
1303                 // remove all inherited attributes
1304                 [attrString setAttributes:nil range:attrStringRange];
1305                 
1306                 // add the attachment attribute
1307                 AccessibilityObject* obj = replacedNode->renderer()->document().axObjectCache()->getOrCreate(replacedNode->renderer());
1308                 AXAttributeStringSetElement(attrString, NSAccessibilityAttachmentTextAttribute, obj, attrStringRange);
1309             }
1310         }
1311         it.advance();
1312     }
1313
1314     return [attrString autorelease];
1315 }
1316
1317 static id textMarkerRangeFromVisiblePositions(AXObjectCache* cache, const VisiblePosition& startPosition, const VisiblePosition& endPosition)
1318 {
1319     if (!cache)
1320         return nil;
1321     
1322     id startTextMarker = textMarkerForVisiblePosition(cache, startPosition);
1323     id endTextMarker = textMarkerForVisiblePosition(cache, endPosition);
1324     return textMarkerRangeFromMarkers(startTextMarker, endTextMarker);
1325 }
1326
1327 - (id)textMarkerRangeFromVisiblePositions:(const VisiblePosition&)startPosition endPosition:(const VisiblePosition&)endPosition
1328 {
1329     return textMarkerRangeFromVisiblePositions(m_object->axObjectCache(), startPosition, endPosition);
1330 }
1331
1332 ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
1333 - (NSArray*)accessibilityActionNames
1334 ALLOW_DEPRECATED_IMPLEMENTATIONS_END
1335 {
1336     if (![self updateObjectBackingStore])
1337         return nil;
1338     
1339     // All elements should get ShowMenu and ScrollToVisible.
1340     // But certain earlier VoiceOver versions do not support scroll to visible, and it confuses them to see it in the list.
1341     static NSArray *defaultElementActions = [[NSArray alloc] initWithObjects:NSAccessibilityShowMenuAction, NSAccessibilityScrollToVisibleAction, nil];
1342
1343     // Action elements allow Press.
1344     // The order is important to VoiceOver, which expects the 'default' action to be the first action. In this case the default action should be press.
1345     static NSArray *actionElementActions = [[NSArray alloc] initWithObjects:NSAccessibilityPressAction, NSAccessibilityShowMenuAction, NSAccessibilityScrollToVisibleAction, nil];
1346
1347     // Menu elements allow Press and Cancel.
1348     static NSArray *menuElementActions = [[actionElementActions arrayByAddingObject:NSAccessibilityCancelAction] retain];
1349
1350     // Slider elements allow Increment/Decrement.
1351     static NSArray *sliderActions = [[defaultElementActions arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:NSAccessibilityIncrementAction, NSAccessibilityDecrementAction, nil]] retain];
1352     
1353     NSArray *actions;
1354     if (m_object->supportsPressAction())
1355         actions = actionElementActions;
1356     else if (m_object->isMenuRelated())
1357         actions = menuElementActions;
1358     else if (m_object->isSlider())
1359         actions = sliderActions;
1360     else if (m_object->isAttachment())
1361         actions = [[self attachmentView] accessibilityActionNames];
1362     else
1363         actions = defaultElementActions;
1364     
1365     return actions;
1366 }
1367
1368 - (NSArray*)additionalAccessibilityAttributeNames
1369 {
1370     if (!m_object)
1371         return nil;
1372     
1373     NSMutableArray *additional = [NSMutableArray array];
1374     if (m_object->supportsARIAOwns())
1375         [additional addObject:NSAccessibilityOwnsAttribute];
1376     
1377     if (m_object->isToggleButton())
1378         [additional addObject:NSAccessibilityValueAttribute];
1379     
1380     if (m_object->supportsExpanded() || m_object->isSummary())
1381         [additional addObject:NSAccessibilityExpandedAttribute];
1382     
1383     if (m_object->isScrollbar()
1384         || m_object->isRadioGroup()
1385         || m_object->isSplitter()
1386         || m_object->isToolbar())
1387         [additional addObject:NSAccessibilityOrientationAttribute];
1388     
1389     if (m_object->supportsARIADragging())
1390         [additional addObject:NSAccessibilityGrabbedAttribute];
1391     
1392     if (m_object->supportsARIADropping())
1393         [additional addObject:NSAccessibilityDropEffectsAttribute];
1394     
1395     if (is<AccessibilityTable>(*m_object) && downcast<AccessibilityTable>(*m_object).isExposableThroughAccessibility() && downcast<AccessibilityTable>(*m_object).supportsSelectedRows())
1396         [additional addObject:NSAccessibilitySelectedRowsAttribute];
1397     
1398     if (m_object->supportsLiveRegion()) {
1399         [additional addObject:NSAccessibilityARIALiveAttribute];
1400         [additional addObject:NSAccessibilityARIARelevantAttribute];
1401     }
1402     
1403     if (m_object->supportsSetSize())
1404         [additional addObject:NSAccessibilityARIASetSizeAttribute];
1405     if (m_object->supportsPosInSet())
1406         [additional addObject:NSAccessibilityARIAPosInSetAttribute];
1407     
1408     AccessibilitySortDirection sortDirection = m_object->sortDirection();
1409     if (sortDirection != AccessibilitySortDirection::None && sortDirection != AccessibilitySortDirection::Invalid)
1410         [additional addObject:NSAccessibilitySortDirectionAttribute];
1411     
1412     // If an object is a child of a live region, then add these
1413     if (m_object->isInsideLiveRegion())
1414         [additional addObject:NSAccessibilityARIAAtomicAttribute];
1415     // All objects should expose the ARIA busy attribute (ARIA 1.1 with ISSUE-538).
1416     [additional addObject:NSAccessibilityElementBusyAttribute];
1417     
1418     // Popup buttons on the Mac expose the value attribute.
1419     if (m_object->isPopUpButton()) {
1420         [additional addObject:NSAccessibilityValueAttribute];
1421     }
1422
1423     if (m_object->supportsDatetimeAttribute())
1424         [additional addObject:NSAccessibilityDatetimeValueAttribute];
1425     
1426     if (m_object->supportsRequiredAttribute()) {
1427         [additional addObject:NSAccessibilityRequiredAttribute];
1428     }
1429     
1430     if (m_object->hasPopup())
1431         [additional addObject:NSAccessibilityHasPopupAttribute];
1432     
1433     if (m_object->isMathRoot()) {
1434         // The index of a square root is always known, so there's no object associated with it.
1435         if (!m_object->isMathSquareRoot())
1436             [additional addObject:NSAccessibilityMathRootIndexAttribute];
1437         [additional addObject:NSAccessibilityMathRootRadicandAttribute];
1438     } else if (m_object->isMathFraction()) {
1439         [additional addObject:NSAccessibilityMathFractionNumeratorAttribute];
1440         [additional addObject:NSAccessibilityMathFractionDenominatorAttribute];
1441         [additional addObject:NSAccessibilityMathLineThicknessAttribute];
1442     } else if (m_object->isMathSubscriptSuperscript()) {
1443         [additional addObject:NSAccessibilityMathBaseAttribute];
1444         [additional addObject:NSAccessibilityMathSubscriptAttribute];
1445         [additional addObject:NSAccessibilityMathSuperscriptAttribute];
1446     } else if (m_object->isMathUnderOver()) {
1447         [additional addObject:NSAccessibilityMathBaseAttribute];
1448         [additional addObject:NSAccessibilityMathUnderAttribute];
1449         [additional addObject:NSAccessibilityMathOverAttribute];
1450     } else if (m_object->isMathFenced()) {
1451         [additional addObject:NSAccessibilityMathFencedOpenAttribute];
1452         [additional addObject:NSAccessibilityMathFencedCloseAttribute];
1453     } else if (m_object->isMathMultiscript()) {
1454         [additional addObject:NSAccessibilityMathBaseAttribute];
1455         [additional addObject:NSAccessibilityMathPrescriptsAttribute];
1456         [additional addObject:NSAccessibilityMathPostscriptsAttribute];
1457     }
1458     
1459     if (m_object->supportsPath())
1460         [additional addObject:NSAccessibilityPathAttribute];
1461     
1462     if (m_object->supportsExpandedTextValue())
1463         [additional addObject:NSAccessibilityExpandedTextValueAttribute];
1464     
1465     return additional;
1466 }
1467
1468 ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
1469 - (NSArray*)accessibilityAttributeNames
1470 ALLOW_DEPRECATED_IMPLEMENTATIONS_END
1471 {
1472     if (![self updateObjectBackingStore])
1473         return nil;
1474     
1475     if (m_object->isAttachment())
1476         return [[self attachmentView] accessibilityAttributeNames];
1477     
1478     static NSArray* attributes = nil;
1479     static NSArray* anchorAttrs = nil;
1480     static NSArray* webAreaAttrs = nil;
1481     static NSArray* textAttrs = nil;
1482     static NSArray* listAttrs = nil;
1483     static NSArray* listBoxAttrs = nil;
1484     static NSArray* rangeAttrs = nil;
1485     static NSArray* commonMenuAttrs = nil;
1486     static NSArray* menuAttrs = nil;
1487     static NSArray* menuBarAttrs = nil;
1488     static NSArray* menuItemAttrs = nil;
1489     static NSArray* menuButtonAttrs = nil;
1490     static NSArray* controlAttrs = nil;
1491     static NSArray* tableAttrs = nil;
1492     static NSArray* tableRowAttrs = nil;
1493     static NSArray* tableColAttrs = nil;
1494     static NSArray* tableCellAttrs = nil;
1495     static NSArray* groupAttrs = nil;
1496     static NSArray* inputImageAttrs = nil;
1497     static NSArray* passwordFieldAttrs = nil;
1498     static NSArray* tabListAttrs = nil;
1499     static NSArray* comboBoxAttrs = nil;
1500     static NSArray* outlineAttrs = nil;
1501     static NSArray* outlineRowAttrs = nil;
1502     static NSArray* buttonAttrs = nil;
1503     static NSArray* scrollViewAttrs = nil;
1504     static NSArray* incrementorAttrs = nil;
1505     NSMutableArray* tempArray;
1506     if (attributes == nil) {
1507         attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute,
1508             NSAccessibilitySubroleAttribute,
1509             NSAccessibilityRoleDescriptionAttribute,
1510             NSAccessibilityChildrenAttribute,
1511             NSAccessibilityHelpAttribute,
1512             NSAccessibilityParentAttribute,
1513             NSAccessibilityPositionAttribute,
1514             NSAccessibilitySizeAttribute,
1515             NSAccessibilityTitleAttribute,
1516             NSAccessibilityDescriptionAttribute,
1517             NSAccessibilityValueAttribute,
1518             NSAccessibilityFocusedAttribute,
1519             NSAccessibilityEnabledAttribute,
1520             NSAccessibilityWindowAttribute,
1521             @"AXSelectedTextMarkerRange",
1522             @"AXStartTextMarker",
1523             @"AXEndTextMarker",
1524             @"AXVisited",
1525             NSAccessibilityLinkedUIElementsAttribute,
1526             NSAccessibilitySelectedAttribute,
1527             NSAccessibilityBlockQuoteLevelAttribute,
1528             NSAccessibilityTopLevelUIElementAttribute,
1529             NSAccessibilityLanguageAttribute,
1530             NSAccessibilityDOMIdentifierAttribute,
1531             NSAccessibilityDOMClassListAttribute,
1532             NSAccessibilityFocusableAncestorAttribute,
1533             NSAccessibilityEditableAncestorAttribute,
1534             NSAccessibilityHighestEditableAncestorAttribute,
1535             NSAccessibilityRelativeFrameAttribute,
1536             nil];
1537     }
1538     if (commonMenuAttrs == nil) {
1539         commonMenuAttrs = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute,
1540                            NSAccessibilityRoleDescriptionAttribute,
1541                            NSAccessibilityChildrenAttribute,
1542                            NSAccessibilityParentAttribute,
1543                            NSAccessibilityEnabledAttribute,
1544                            NSAccessibilityPositionAttribute,
1545                            NSAccessibilitySizeAttribute,
1546                            nil];
1547     }
1548     if (anchorAttrs == nil) {
1549         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1550         [tempArray addObject:NSAccessibilityURLAttribute];
1551         [tempArray addObject:NSAccessibilityAccessKeyAttribute];
1552         [tempArray addObject:NSAccessibilityLinkRelationshipTypeAttribute];
1553         anchorAttrs = [[NSArray alloc] initWithArray:tempArray];
1554         [tempArray release];
1555     }
1556     if (webAreaAttrs == nil) {
1557         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1558         // WebAreas should not expose AXSubrole.
1559         [tempArray removeObject:NSAccessibilitySubroleAttribute];
1560         // WebAreas should not expose ancestor attributes
1561         [tempArray removeObject:NSAccessibilityFocusableAncestorAttribute];
1562         [tempArray removeObject:NSAccessibilityEditableAncestorAttribute];
1563         [tempArray removeObject:NSAccessibilityHighestEditableAncestorAttribute];
1564         [tempArray addObject:@"AXLinkUIElements"];
1565         [tempArray addObject:@"AXLoaded"];
1566         [tempArray addObject:@"AXLayoutCount"];
1567         [tempArray addObject:NSAccessibilityLoadingProgressAttribute];
1568         [tempArray addObject:NSAccessibilityURLAttribute];
1569         [tempArray addObject:NSAccessibilityCaretBrowsingEnabledAttribute];
1570         [tempArray addObject:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute];
1571         [tempArray addObject:NSAccessibilityWebSessionIDAttribute];
1572         webAreaAttrs = [[NSArray alloc] initWithArray:tempArray];
1573         [tempArray release];
1574     }
1575     if (textAttrs == nil) {
1576         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1577         [tempArray addObject:NSAccessibilityNumberOfCharactersAttribute];
1578         [tempArray addObject:NSAccessibilitySelectedTextAttribute];
1579         [tempArray addObject:NSAccessibilitySelectedTextRangeAttribute];
1580         [tempArray addObject:NSAccessibilityVisibleCharacterRangeAttribute];
1581         [tempArray addObject:NSAccessibilityInsertionPointLineNumberAttribute];
1582         [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
1583         [tempArray addObject:NSAccessibilityAccessKeyAttribute];
1584         [tempArray addObject:NSAccessibilityRequiredAttribute];
1585         [tempArray addObject:NSAccessibilityInvalidAttribute];
1586         [tempArray addObject:NSAccessibilityPlaceholderValueAttribute];
1587         [tempArray addObject:NSAccessibilityValueAutofilledAttribute];
1588         textAttrs = [[NSArray alloc] initWithArray:tempArray];
1589         [tempArray release];
1590     }
1591     if (listAttrs == nil) {
1592         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1593         [tempArray addObject:NSAccessibilitySelectedChildrenAttribute];
1594         [tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
1595         [tempArray addObject:NSAccessibilityOrientationAttribute];
1596         [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
1597         listAttrs = [[NSArray alloc] initWithArray:tempArray];
1598         [tempArray release];
1599     }
1600     if (listBoxAttrs == nil) {
1601         tempArray = [[NSMutableArray alloc] initWithArray:listAttrs];
1602         [tempArray addObject:NSAccessibilityAccessKeyAttribute];
1603         [tempArray addObject:NSAccessibilityRequiredAttribute];
1604         [tempArray addObject:NSAccessibilityInvalidAttribute];
1605         [tempArray addObject:NSAccessibilityOrientationAttribute];
1606         listBoxAttrs = [[NSArray alloc] initWithArray:tempArray];
1607         [tempArray release];
1608     }
1609     if (rangeAttrs == nil) {
1610         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1611         [tempArray addObject:NSAccessibilityMinValueAttribute];
1612         [tempArray addObject:NSAccessibilityMaxValueAttribute];
1613         [tempArray addObject:NSAccessibilityOrientationAttribute];
1614         [tempArray addObject:NSAccessibilityValueDescriptionAttribute];
1615         [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
1616         rangeAttrs = [[NSArray alloc] initWithArray:tempArray];
1617         [tempArray release];
1618     }
1619     if (menuBarAttrs == nil) {
1620         tempArray = [[NSMutableArray alloc] initWithArray:commonMenuAttrs];
1621         [tempArray addObject:NSAccessibilitySelectedChildrenAttribute];
1622         [tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
1623         [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
1624         [tempArray addObject:NSAccessibilityOrientationAttribute];
1625         menuBarAttrs = [[NSArray alloc] initWithArray:tempArray];
1626         [tempArray release];
1627     }
1628     if (menuAttrs == nil) {
1629         tempArray = [[NSMutableArray alloc] initWithArray:commonMenuAttrs];
1630         [tempArray addObject:NSAccessibilitySelectedChildrenAttribute];
1631         [tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
1632         [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
1633         [tempArray addObject:NSAccessibilityOrientationAttribute];
1634         menuAttrs = [[NSArray alloc] initWithArray:tempArray];
1635         [tempArray release];
1636     }
1637     if (menuItemAttrs == nil) {
1638         tempArray = [[NSMutableArray alloc] initWithArray:commonMenuAttrs];
1639         [tempArray addObject:NSAccessibilityTitleAttribute];
1640         [tempArray addObject:NSAccessibilityDescriptionAttribute];
1641         [tempArray addObject:NSAccessibilityHelpAttribute];
1642         [tempArray addObject:NSAccessibilitySelectedAttribute];
1643         [tempArray addObject:NSAccessibilityValueAttribute];
1644         [tempArray addObject:(NSString*)kAXMenuItemCmdCharAttribute];
1645         [tempArray addObject:(NSString*)kAXMenuItemCmdVirtualKeyAttribute];
1646         [tempArray addObject:(NSString*)kAXMenuItemCmdGlyphAttribute];
1647         [tempArray addObject:(NSString*)kAXMenuItemCmdModifiersAttribute];
1648         [tempArray addObject:(NSString*)kAXMenuItemMarkCharAttribute];
1649         [tempArray addObject:(NSString*)kAXMenuItemPrimaryUIElementAttribute];
1650         [tempArray addObject:NSAccessibilityServesAsTitleForUIElementsAttribute];
1651         [tempArray addObject:NSAccessibilityFocusedAttribute];
1652         menuItemAttrs = [[NSArray alloc] initWithArray:tempArray];
1653         [tempArray release];
1654     }
1655     if (menuButtonAttrs == nil) {
1656         menuButtonAttrs = [[NSArray alloc] initWithObjects:NSAccessibilityRoleAttribute,
1657                            NSAccessibilityRoleDescriptionAttribute,
1658                            NSAccessibilityParentAttribute,
1659                            NSAccessibilityPositionAttribute,
1660                            NSAccessibilitySizeAttribute,
1661                            NSAccessibilityWindowAttribute,
1662                            NSAccessibilityEnabledAttribute,
1663                            NSAccessibilityFocusedAttribute,
1664                            NSAccessibilityTitleAttribute,
1665                            NSAccessibilityChildrenAttribute, nil];
1666     }
1667     if (controlAttrs == nil) {
1668         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1669         [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
1670         [tempArray addObject:NSAccessibilityAccessKeyAttribute];
1671         [tempArray addObject:NSAccessibilityRequiredAttribute];
1672         [tempArray addObject:NSAccessibilityInvalidAttribute];
1673         controlAttrs = [[NSArray alloc] initWithArray:tempArray];
1674         [tempArray release];
1675     }
1676     if (incrementorAttrs == nil) {
1677         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1678         [tempArray addObject:NSAccessibilityIncrementButtonAttribute];
1679         [tempArray addObject:NSAccessibilityDecrementButtonAttribute];
1680         [tempArray addObject:NSAccessibilityValueDescriptionAttribute];
1681         [tempArray addObject:NSAccessibilityMinValueAttribute];
1682         [tempArray addObject:NSAccessibilityMaxValueAttribute];
1683         incrementorAttrs = [[NSArray alloc] initWithArray:tempArray];
1684         [tempArray release];
1685     }
1686     if (buttonAttrs == nil) {
1687         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1688         // Buttons should not expose AXValue.
1689         [tempArray removeObject:NSAccessibilityValueAttribute];
1690         [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
1691         [tempArray addObject:NSAccessibilityAccessKeyAttribute];
1692         buttonAttrs = [[NSArray alloc] initWithArray:tempArray];
1693         [tempArray release];
1694     }
1695     if (comboBoxAttrs == nil) {
1696         tempArray = [[NSMutableArray alloc] initWithArray:controlAttrs];
1697         [tempArray addObject:NSAccessibilityExpandedAttribute];
1698         [tempArray addObject:NSAccessibilityOrientationAttribute];
1699         comboBoxAttrs = [[NSArray alloc] initWithArray:tempArray];
1700         [tempArray release];
1701     }
1702     if (tableAttrs == nil) {
1703         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1704         [tempArray addObject:NSAccessibilityRowsAttribute];
1705         [tempArray addObject:NSAccessibilityVisibleRowsAttribute];
1706         [tempArray addObject:NSAccessibilityColumnsAttribute];
1707         [tempArray addObject:NSAccessibilityVisibleColumnsAttribute];
1708         [tempArray addObject:NSAccessibilityVisibleCellsAttribute];
1709         [tempArray addObject:NSAccessibilityColumnHeaderUIElementsAttribute];
1710         [tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
1711         [tempArray addObject:NSAccessibilityHeaderAttribute];
1712         [tempArray addObject:NSAccessibilityColumnCountAttribute];
1713         [tempArray addObject:NSAccessibilityRowCountAttribute];
1714         [tempArray addObject:NSAccessibilityARIAColumnCountAttribute];
1715         [tempArray addObject:NSAccessibilityARIARowCountAttribute];
1716         tableAttrs = [[NSArray alloc] initWithArray:tempArray];
1717         [tempArray release];
1718     }
1719     if (tableRowAttrs == nil) {
1720         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1721         [tempArray addObject:NSAccessibilityIndexAttribute];
1722         tableRowAttrs = [[NSArray alloc] initWithArray:tempArray];
1723         [tempArray release];
1724     }
1725     if (tableColAttrs == nil) {
1726         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1727         [tempArray addObject:NSAccessibilityIndexAttribute];
1728         [tempArray addObject:NSAccessibilityHeaderAttribute];
1729         [tempArray addObject:NSAccessibilityRowsAttribute];
1730         [tempArray addObject:NSAccessibilityVisibleRowsAttribute];
1731         tableColAttrs = [[NSArray alloc] initWithArray:tempArray];
1732         [tempArray release];
1733     }
1734     if (tableCellAttrs == nil) {
1735         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1736         [tempArray addObject:NSAccessibilityRowIndexRangeAttribute];
1737         [tempArray addObject:NSAccessibilityColumnIndexRangeAttribute];
1738         [tempArray addObject:NSAccessibilityColumnHeaderUIElementsAttribute];
1739         [tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
1740         [tempArray addObject:NSAccessibilityARIAColumnIndexAttribute];
1741         [tempArray addObject:NSAccessibilityARIARowIndexAttribute];
1742         tableCellAttrs = [[NSArray alloc] initWithArray:tempArray];
1743         [tempArray release];
1744     }
1745     if (groupAttrs == nil) {
1746         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1747         [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
1748         groupAttrs = [[NSArray alloc] initWithArray:tempArray];
1749         [tempArray release];
1750     }
1751     if (inputImageAttrs == nil) {
1752         tempArray = [[NSMutableArray alloc] initWithArray:buttonAttrs];
1753         [tempArray addObject:NSAccessibilityURLAttribute];
1754         inputImageAttrs = [[NSArray alloc] initWithArray:tempArray];
1755         [tempArray release];
1756     }
1757     if (passwordFieldAttrs == nil) {
1758         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1759         [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
1760         [tempArray addObject:NSAccessibilityRequiredAttribute];
1761         [tempArray addObject:NSAccessibilityInvalidAttribute];
1762         [tempArray addObject:NSAccessibilityPlaceholderValueAttribute];
1763         [tempArray addObject:NSAccessibilityValueAutofilledAttribute];
1764         passwordFieldAttrs = [[NSArray alloc] initWithArray:tempArray];
1765         [tempArray release];
1766     }
1767     if (tabListAttrs == nil) {
1768         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1769         [tempArray addObject:NSAccessibilityTabsAttribute];
1770         [tempArray addObject:NSAccessibilityContentsAttribute];
1771         [tempArray addObject:NSAccessibilityOrientationAttribute];
1772         tabListAttrs = [[NSArray alloc] initWithArray:tempArray];
1773         [tempArray release];
1774     }
1775     if (outlineAttrs == nil) {
1776         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1777         [tempArray addObject:NSAccessibilitySelectedRowsAttribute];
1778         [tempArray addObject:NSAccessibilityRowsAttribute];
1779         [tempArray addObject:NSAccessibilityColumnsAttribute];
1780         [tempArray addObject:NSAccessibilityOrientationAttribute];
1781         outlineAttrs = [[NSArray alloc] initWithArray:tempArray];
1782         [tempArray release];
1783     }
1784     if (outlineRowAttrs == nil) {
1785         tempArray = [[NSMutableArray alloc] initWithArray:tableRowAttrs];
1786         [tempArray addObject:NSAccessibilityDisclosingAttribute];
1787         [tempArray addObject:NSAccessibilityDisclosedByRowAttribute];
1788         [tempArray addObject:NSAccessibilityDisclosureLevelAttribute];
1789         [tempArray addObject:NSAccessibilityDisclosedRowsAttribute];
1790         outlineRowAttrs = [[NSArray alloc] initWithArray:tempArray];
1791         [tempArray release];
1792     }
1793     if (scrollViewAttrs == nil) {
1794         tempArray = [[NSMutableArray alloc] initWithArray:attributes];
1795         [tempArray addObject:NSAccessibilityContentsAttribute];
1796         [tempArray addObject:NSAccessibilityHorizontalScrollBarAttribute];
1797         [tempArray addObject:NSAccessibilityVerticalScrollBarAttribute];
1798         scrollViewAttrs = [[NSArray alloc] initWithArray:tempArray];
1799         [tempArray release];
1800     }
1801     
1802     NSArray *objectAttributes = attributes;
1803     
1804     if (m_object->isPasswordField())
1805         objectAttributes = passwordFieldAttrs;
1806     
1807     else if (m_object->isWebArea())
1808         objectAttributes = webAreaAttrs;
1809     
1810     else if (m_object->isTextControl())
1811         objectAttributes = textAttrs;
1812     
1813     else if (_axBackingObject->isLink() || _axBackingObject->isImage())
1814         objectAttributes = anchorAttrs;
1815     
1816     else if (is<AccessibilityTable>(*m_object) && downcast<AccessibilityTable>(*m_object).isExposableThroughAccessibility())
1817         objectAttributes = tableAttrs;
1818     else if (m_object->isTableColumn())
1819         objectAttributes = tableColAttrs;
1820     else if (m_object->isTableCell())
1821         objectAttributes = tableCellAttrs;
1822     else if (m_object->isTableRow()) {
1823         // An ARIA table row can be collapsed and expanded, so it needs the extra attributes.
1824         if (m_object->isARIATreeGridRow())
1825             objectAttributes = outlineRowAttrs;
1826         else
1827             objectAttributes = tableRowAttrs;
1828     }
1829     
1830     else if (m_object->isTree())
1831         objectAttributes = outlineAttrs;
1832     else if (m_object->isTreeItem())
1833         objectAttributes = outlineRowAttrs;
1834     
1835     else if (m_object->isListBox())
1836         objectAttributes = listBoxAttrs;
1837     else if (m_object->isList())
1838         objectAttributes = listAttrs;
1839     
1840     else if (m_object->isComboBox())
1841         objectAttributes = comboBoxAttrs;
1842     
1843     else if (m_object->isProgressIndicator() || m_object->isSlider())
1844         objectAttributes = rangeAttrs;
1845     
1846     // These are processed in order because an input image is a button, and a button is a control.
1847     else if (m_object->isInputImage())
1848         objectAttributes = inputImageAttrs;
1849     else if (m_object->isButton())
1850         objectAttributes = buttonAttrs;
1851     else if (m_object->isControl())
1852         objectAttributes = controlAttrs;
1853     
1854     else if (m_object->isGroup() || m_object->isListItem())
1855         objectAttributes = groupAttrs;
1856     else if (m_object->isTabList())
1857         objectAttributes = tabListAttrs;
1858     else if (m_object->isScrollView())
1859         objectAttributes = scrollViewAttrs;
1860     else if (m_object->isSpinButton())
1861         objectAttributes = incrementorAttrs;
1862     
1863     else if (m_object->isMenu())
1864         objectAttributes = menuAttrs;
1865     else if (m_object->isMenuBar())
1866         objectAttributes = menuBarAttrs;
1867     else if (m_object->isMenuButton())
1868         objectAttributes = menuButtonAttrs;
1869     else if (m_object->isMenuItem())
1870         objectAttributes = menuItemAttrs;
1871     
1872     NSArray *additionalAttributes = [self additionalAccessibilityAttributeNames];
1873     if ([additionalAttributes count])
1874         objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:additionalAttributes];
1875     
1876     // Only expose AXARIACurrent attribute when the element is set to be current item.
1877     if (m_object->currentState() != AccessibilityCurrentState::False)
1878         objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:@[ NSAccessibilityARIACurrentAttribute ]];
1879     
1880     // AppKit needs to know the screen height in order to do the coordinate conversion.
1881     objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:@[ NSAccessibilityPrimaryScreenHeightAttribute ]];
1882     
1883     return objectAttributes;
1884 }
1885
1886 - (VisiblePositionRange)visiblePositionRangeForTextMarkerRange:(id)textMarkerRange
1887 {
1888     if (!textMarkerRange)
1889         return VisiblePositionRange();
1890     AXObjectCache* cache = m_object->axObjectCache();
1891     return VisiblePositionRange(visiblePositionForStartOfTextMarkerRange(cache, textMarkerRange), visiblePositionForEndOfTextMarkerRange(cache, textMarkerRange));
1892 }
1893
1894 - (NSArray*)renderWidgetChildren
1895 {
1896     Widget* widget = m_object->widget();
1897     if (!widget)
1898         return nil;
1899     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
1900     return [(widget->platformWidget()) accessibilityAttributeValue: NSAccessibilityChildrenAttribute];
1901     ALLOW_DEPRECATED_DECLARATIONS_END
1902 }
1903
1904 - (id)remoteAccessibilityParentObject
1905 {
1906     if (!m_object)
1907         return nil;
1908     
1909     Document* document = m_object->document();
1910     if (!document)
1911         return nil;
1912     
1913     Frame* frame = document->frame();
1914     if (!frame)
1915         return nil;
1916     
1917     return frame->loader().client().accessibilityRemoteObject();
1918 }
1919
1920 static void convertToVector(NSArray* array, AccessibilityObject::AccessibilityChildrenVector& vector)
1921 {
1922     unsigned length = [array count];
1923     vector.reserveInitialCapacity(length);
1924     for (unsigned i = 0; i < length; ++i) {
1925         AccessibilityObject* obj = [[array objectAtIndex:i] accessibilityObject];
1926         if (obj)
1927             vector.append(obj);
1928     }
1929 }
1930
1931 static NSMutableArray *convertStringsToNSArray(const Vector<String>& vector)
1932 {
1933     NSMutableArray *array = [NSMutableArray arrayWithCapacity:vector.size()];
1934     for (const auto& string : vector)
1935         [array addObject:string];
1936     return array;
1937 }
1938
1939 - (id)textMarkerRangeForSelection
1940 {
1941     VisibleSelection selection = m_object->selection();
1942     if (selection.isNone())
1943         return nil;
1944     return [self textMarkerRangeFromVisiblePositions:selection.visibleStart() endPosition:selection.visibleEnd()];
1945 }
1946
1947 - (id)associatedPluginParent
1948 {
1949     if (!m_object || !m_object->hasAttribute(x_apple_pdf_annotationAttr))
1950         return nil;
1951     
1952     if (!m_object->document()->isPluginDocument())
1953         return nil;
1954         
1955     Widget* pluginWidget = static_cast<PluginDocument*>(m_object->document())->pluginWidget();
1956     if (!pluginWidget || !pluginWidget->isPluginViewBase())
1957         return nil;
1958
1959     return static_cast<PluginViewBase*>(pluginWidget)->accessibilityAssociatedPluginParentForElement(m_object->element());
1960 }
1961
1962 static void WebTransformCGPathToNSBezierPath(void* info, const CGPathElement *element)
1963 {
1964     NSBezierPath *bezierPath = (__bridge NSBezierPath *)info;
1965     switch (element->type) {
1966     case kCGPathElementMoveToPoint:
1967         [bezierPath moveToPoint:NSPointFromCGPoint(element->points[0])];
1968         break;
1969     case kCGPathElementAddLineToPoint:
1970         [bezierPath lineToPoint:NSPointFromCGPoint(element->points[0])];
1971         break;
1972     case kCGPathElementAddCurveToPoint:
1973         [bezierPath curveToPoint:NSPointFromCGPoint(element->points[0]) controlPoint1:NSPointFromCGPoint(element->points[1]) controlPoint2:NSPointFromCGPoint(element->points[2])];
1974         break;
1975     case kCGPathElementCloseSubpath:
1976         [bezierPath closePath];
1977         break;
1978     default:
1979         break;
1980     }
1981 }
1982
1983 - (NSBezierPath *)bezierPathFromPath:(CGPathRef)path
1984 {
1985     NSBezierPath *bezierPath = [NSBezierPath bezierPath];
1986     CGPathApply(path, (__bridge void*)bezierPath, WebTransformCGPathToNSBezierPath);
1987     return bezierPath;
1988 }
1989
1990 - (NSBezierPath *)path
1991 {
1992     Path path = m_object->elementPath();
1993     if (path.isEmpty())
1994         return NULL;
1995     
1996     CGPathRef transformedPath = [self convertPathToScreenSpace:path];
1997     return [self bezierPathFromPath:transformedPath];
1998 }
1999
2000 - (NSNumber *)primaryScreenHeight
2001 {
2002     FloatRect screenRect = screenRectForPrimaryScreen();
2003     return [NSNumber numberWithFloat:screenRect.height()];
2004 }
2005
2006 - (size_t)childrenVectorSize
2007 {
2008 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
2009     if (_AXUIElementRequestServicedBySecondaryAXThread())
2010         return self.isolatedTreeNode->children().size();
2011 #endif
2012     
2013     return m_object->children().size();
2014 }
2015
2016 - (NSArray<WebAccessibilityObjectWrapper *> *)childrenVectorArray
2017 {
2018 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
2019     if (_AXUIElementRequestServicedBySecondaryAXThread()) {
2020         auto treeNode = self.isolatedTreeNode;
2021         auto nodeChildren = treeNode->children();
2022         Vector<RefPtr<AXIsolatedTreeNode>> children;
2023         children.reserveInitialCapacity(nodeChildren.size());
2024         auto tree = treeNode->tree();
2025         for (auto childID : nodeChildren)
2026             children.uncheckedAppend(tree->nodeForID(child));
2027         return convertToNSArray(children);
2028     }
2029 #endif
2030     return convertToNSArray(m_object->children());
2031 }
2032
2033 - (NSValue *)position
2034 {
2035 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
2036     if (_AXUIElementRequestServicedBySecondaryAXThread())
2037         return [NSValue valueWithPoint:(NSPoint)_axBackingObject->relativeFrame().location()];
2038 #endif
2039         
2040     auto rect = snappedIntRect(m_object->elementRect());
2041     
2042     // The Cocoa accessibility API wants the lower-left corner.
2043     auto floatPoint = FloatPoint(rect.x(), rect.maxY());
2044
2045     auto floatRect = FloatRect(floatPoint, FloatSize());
2046     CGPoint cgPoint = [self convertRectToSpace:floatRect space:AccessibilityConversionSpace::Screen].origin;
2047     return [NSValue valueWithPoint:NSPointFromCGPoint(cgPoint)];
2048 }
2049
2050 using AccessibilityRoleMap = HashMap<int, CFStringRef>;
2051
2052 static AccessibilityRoleMap createAccessibilityRoleMap()
2053 {
2054     struct RoleEntry {
2055         AccessibilityRole value;
2056         __unsafe_unretained NSString *string;
2057     };
2058     static const RoleEntry roles[] = {
2059         { AccessibilityRole::Unknown, NSAccessibilityUnknownRole },
2060         { AccessibilityRole::Button, NSAccessibilityButtonRole },
2061         { AccessibilityRole::RadioButton, NSAccessibilityRadioButtonRole },
2062         { AccessibilityRole::CheckBox, NSAccessibilityCheckBoxRole },
2063         { AccessibilityRole::Slider, NSAccessibilitySliderRole },
2064         { AccessibilityRole::TabGroup, NSAccessibilityTabGroupRole },
2065         { AccessibilityRole::TextField, NSAccessibilityTextFieldRole },
2066         { AccessibilityRole::StaticText, NSAccessibilityStaticTextRole },
2067         { AccessibilityRole::TextArea, NSAccessibilityTextAreaRole },
2068         { AccessibilityRole::ScrollArea, NSAccessibilityScrollAreaRole },
2069         { AccessibilityRole::PopUpButton, NSAccessibilityPopUpButtonRole },
2070         { AccessibilityRole::MenuButton, NSAccessibilityMenuButtonRole },
2071         { AccessibilityRole::Table, NSAccessibilityTableRole },
2072         { AccessibilityRole::Application, NSAccessibilityApplicationRole },
2073         { AccessibilityRole::Group, NSAccessibilityGroupRole },
2074         { AccessibilityRole::TextGroup, NSAccessibilityGroupRole },
2075         { AccessibilityRole::RadioGroup, NSAccessibilityRadioGroupRole },
2076         { AccessibilityRole::List, NSAccessibilityListRole },
2077         { AccessibilityRole::Directory, NSAccessibilityListRole },
2078         { AccessibilityRole::ScrollBar, NSAccessibilityScrollBarRole },
2079         { AccessibilityRole::ValueIndicator, NSAccessibilityValueIndicatorRole },
2080         { AccessibilityRole::Image, NSAccessibilityImageRole },
2081         { AccessibilityRole::MenuBar, NSAccessibilityMenuBarRole },
2082         { AccessibilityRole::Menu, NSAccessibilityMenuRole },
2083         { AccessibilityRole::MenuItem, NSAccessibilityMenuItemRole },
2084         { AccessibilityRole::MenuItemCheckbox, NSAccessibilityMenuItemRole },
2085         { AccessibilityRole::MenuItemRadio, NSAccessibilityMenuItemRole },
2086         { AccessibilityRole::Column, NSAccessibilityColumnRole },
2087         { AccessibilityRole::Row, NSAccessibilityRowRole },
2088         { AccessibilityRole::Toolbar, NSAccessibilityToolbarRole },
2089         { AccessibilityRole::BusyIndicator, NSAccessibilityBusyIndicatorRole },
2090         { AccessibilityRole::ProgressIndicator, NSAccessibilityProgressIndicatorRole },
2091         { AccessibilityRole::Meter, NSAccessibilityLevelIndicatorRole },
2092         { AccessibilityRole::Window, NSAccessibilityWindowRole },
2093         { AccessibilityRole::Drawer, NSAccessibilityDrawerRole },
2094         { AccessibilityRole::SystemWide, NSAccessibilitySystemWideRole },
2095         { AccessibilityRole::Outline, NSAccessibilityOutlineRole },
2096         { AccessibilityRole::Incrementor, NSAccessibilityIncrementorRole },
2097         { AccessibilityRole::Browser, NSAccessibilityBrowserRole },
2098         { AccessibilityRole::ComboBox, NSAccessibilityComboBoxRole },
2099         { AccessibilityRole::SplitGroup, NSAccessibilitySplitGroupRole },
2100         { AccessibilityRole::Splitter, NSAccessibilitySplitterRole },
2101         { AccessibilityRole::ColorWell, NSAccessibilityColorWellRole },
2102         { AccessibilityRole::GrowArea, NSAccessibilityGrowAreaRole },
2103         { AccessibilityRole::Sheet, NSAccessibilitySheetRole },
2104         { AccessibilityRole::HelpTag, NSAccessibilityHelpTagRole },
2105         { AccessibilityRole::Matte, NSAccessibilityMatteRole },
2106         { AccessibilityRole::Ruler, NSAccessibilityRulerRole },
2107         { AccessibilityRole::RulerMarker, NSAccessibilityRulerMarkerRole },
2108         { AccessibilityRole::Link, NSAccessibilityLinkRole },
2109         { AccessibilityRole::DisclosureTriangle, NSAccessibilityDisclosureTriangleRole },
2110         { AccessibilityRole::Grid, NSAccessibilityTableRole },
2111         { AccessibilityRole::TreeGrid, NSAccessibilityTableRole },
2112         { AccessibilityRole::WebCoreLink, NSAccessibilityLinkRole },
2113         { AccessibilityRole::ImageMapLink, NSAccessibilityLinkRole },
2114         { AccessibilityRole::ImageMap, @"AXImageMap" },
2115         { AccessibilityRole::ListMarker, @"AXListMarker" },
2116         { AccessibilityRole::WebArea, @"AXWebArea" },
2117         { AccessibilityRole::Heading, @"AXHeading" },
2118         { AccessibilityRole::ListBox, NSAccessibilityListRole },
2119         { AccessibilityRole::ListBoxOption, NSAccessibilityStaticTextRole },
2120         { AccessibilityRole::Cell, NSAccessibilityCellRole },
2121         { AccessibilityRole::GridCell, NSAccessibilityCellRole },
2122         { AccessibilityRole::TableHeaderContainer, NSAccessibilityGroupRole },
2123         { AccessibilityRole::ColumnHeader, NSAccessibilityCellRole },
2124         { AccessibilityRole::RowHeader, NSAccessibilityCellRole },
2125         { AccessibilityRole::Definition, NSAccessibilityGroupRole },
2126         { AccessibilityRole::DescriptionListDetail, NSAccessibilityGroupRole },
2127         { AccessibilityRole::DescriptionListTerm, NSAccessibilityGroupRole },
2128         { AccessibilityRole::Term, NSAccessibilityGroupRole },
2129         { AccessibilityRole::DescriptionList, NSAccessibilityListRole },
2130         { AccessibilityRole::SliderThumb, NSAccessibilityValueIndicatorRole },
2131         { AccessibilityRole::WebApplication, NSAccessibilityGroupRole },
2132         { AccessibilityRole::LandmarkBanner, NSAccessibilityGroupRole },
2133         { AccessibilityRole::LandmarkComplementary, NSAccessibilityGroupRole },
2134         { AccessibilityRole::LandmarkDocRegion, NSAccessibilityGroupRole },
2135         { AccessibilityRole::LandmarkContentInfo, NSAccessibilityGroupRole },
2136         { AccessibilityRole::LandmarkMain, NSAccessibilityGroupRole },
2137         { AccessibilityRole::LandmarkNavigation, NSAccessibilityGroupRole },
2138         { AccessibilityRole::LandmarkRegion, NSAccessibilityGroupRole },
2139         { AccessibilityRole::LandmarkSearch, NSAccessibilityGroupRole },
2140         { AccessibilityRole::ApplicationAlert, NSAccessibilityGroupRole },
2141         { AccessibilityRole::ApplicationAlertDialog, NSAccessibilityGroupRole },
2142         { AccessibilityRole::ApplicationDialog, NSAccessibilityGroupRole },
2143         { AccessibilityRole::ApplicationGroup, NSAccessibilityGroupRole },
2144         { AccessibilityRole::ApplicationTextGroup, NSAccessibilityGroupRole },
2145         { AccessibilityRole::ApplicationLog, NSAccessibilityGroupRole },
2146         { AccessibilityRole::ApplicationMarquee, NSAccessibilityGroupRole },
2147         { AccessibilityRole::ApplicationStatus, NSAccessibilityGroupRole },
2148         { AccessibilityRole::ApplicationTimer, NSAccessibilityGroupRole },
2149         { AccessibilityRole::Document, NSAccessibilityGroupRole },
2150         { AccessibilityRole::DocumentArticle, NSAccessibilityGroupRole },
2151         { AccessibilityRole::DocumentMath, NSAccessibilityGroupRole },
2152         { AccessibilityRole::DocumentNote, NSAccessibilityGroupRole },
2153         { AccessibilityRole::UserInterfaceTooltip, NSAccessibilityGroupRole },
2154         { AccessibilityRole::Tab, NSAccessibilityRadioButtonRole },
2155         { AccessibilityRole::TabList, NSAccessibilityTabGroupRole },
2156         { AccessibilityRole::TabPanel, NSAccessibilityGroupRole },
2157         { AccessibilityRole::Tree, NSAccessibilityOutlineRole },
2158         { AccessibilityRole::TreeItem, NSAccessibilityRowRole },
2159         { AccessibilityRole::ListItem, NSAccessibilityGroupRole },
2160         { AccessibilityRole::Paragraph, NSAccessibilityGroupRole },
2161         { AccessibilityRole::Label, NSAccessibilityGroupRole },
2162         { AccessibilityRole::Div, NSAccessibilityGroupRole },
2163         { AccessibilityRole::Form, NSAccessibilityGroupRole },
2164         { AccessibilityRole::SpinButton, NSAccessibilityIncrementorRole },
2165         { AccessibilityRole::Footer, NSAccessibilityGroupRole },
2166         { AccessibilityRole::ToggleButton, NSAccessibilityCheckBoxRole },
2167         { AccessibilityRole::Canvas, NSAccessibilityImageRole },
2168         { AccessibilityRole::SVGRoot, NSAccessibilityGroupRole },
2169         { AccessibilityRole::Legend, NSAccessibilityGroupRole },
2170         { AccessibilityRole::MathElement, NSAccessibilityGroupRole },
2171         { AccessibilityRole::Audio, NSAccessibilityGroupRole },
2172         { AccessibilityRole::Video, NSAccessibilityGroupRole },
2173         { AccessibilityRole::HorizontalRule, NSAccessibilitySplitterRole },
2174         { AccessibilityRole::Blockquote, NSAccessibilityGroupRole },
2175         { AccessibilityRole::Switch, NSAccessibilityCheckBoxRole },
2176         { AccessibilityRole::SearchField, NSAccessibilityTextFieldRole },
2177         { AccessibilityRole::Pre, NSAccessibilityGroupRole },
2178         { AccessibilityRole::RubyBase, NSAccessibilityGroupRole },
2179         { AccessibilityRole::RubyBlock, NSAccessibilityGroupRole },
2180         { AccessibilityRole::RubyInline, NSAccessibilityGroupRole },
2181         { AccessibilityRole::RubyRun, NSAccessibilityGroupRole },
2182         { AccessibilityRole::RubyText, NSAccessibilityGroupRole },
2183         { AccessibilityRole::Details, NSAccessibilityGroupRole },
2184         { AccessibilityRole::Summary, NSAccessibilityButtonRole },
2185         { AccessibilityRole::SVGTextPath, NSAccessibilityGroupRole },
2186         { AccessibilityRole::SVGText, NSAccessibilityGroupRole },
2187         { AccessibilityRole::SVGTSpan, NSAccessibilityGroupRole },
2188         { AccessibilityRole::Inline, NSAccessibilityGroupRole },
2189         { AccessibilityRole::Mark, NSAccessibilityGroupRole },
2190         { AccessibilityRole::Time, NSAccessibilityGroupRole },
2191         { AccessibilityRole::Feed, NSAccessibilityGroupRole },
2192         { AccessibilityRole::Figure, NSAccessibilityGroupRole },
2193         { AccessibilityRole::Footnote, NSAccessibilityGroupRole },
2194         { AccessibilityRole::GraphicsDocument, NSAccessibilityGroupRole },
2195         { AccessibilityRole::GraphicsObject, NSAccessibilityGroupRole },
2196         { AccessibilityRole::GraphicsSymbol, NSAccessibilityImageRole },
2197         { AccessibilityRole::Caption, NSAccessibilityGroupRole },
2198         { AccessibilityRole::Deletion, NSAccessibilityGroupRole },
2199         { AccessibilityRole::Insertion, NSAccessibilityGroupRole },
2200         { AccessibilityRole::Subscript, NSAccessibilityGroupRole },
2201         { AccessibilityRole::Superscript, NSAccessibilityGroupRole },
2202     };
2203     AccessibilityRoleMap roleMap;
2204     for (auto& role : roles)
2205         roleMap.add(static_cast<int>(role.value), (__bridge CFStringRef)role.string);
2206     return roleMap;
2207 }
2208
2209 static NSString *roleValueToNSString(AccessibilityRole value)
2210 {
2211     static NeverDestroyed<AccessibilityRoleMap> roleMap = createAccessibilityRoleMap();
2212     return (__bridge NSString *)roleMap.get().get(static_cast<int>(value));
2213 }
2214
2215 - (NSString*)role
2216 {
2217     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
2218     if (_axBackingObject->isAttachment())
2219         return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityRoleAttribute];
2220     ALLOW_DEPRECATED_DECLARATIONS_END
2221     AccessibilityRole role = _axBackingObject->roleValue();
2222
2223     if (role == AccessibilityRole::Label && is<AccessibilityLabel>(*m_object) && downcast<AccessibilityLabel>(*m_object).containsOnlyStaticText())
2224         role = AccessibilityRole::StaticText;
2225
2226     // The mfenced element creates anonymous RenderMathMLOperators with no RenderText
2227     // descendants. Because these anonymous renderers are the only accessible objects
2228     // containing the operator, assign AccessibilityRole::StaticText.
2229     if (m_object->isAnonymousMathOperator())
2230         role = AccessibilityRole::StaticText;
2231
2232     if (role == AccessibilityRole::Canvas && m_object->canvasHasFallbackContent())
2233         role = AccessibilityRole::Group;
2234     NSString* string = roleValueToNSString(role);
2235     if (string != nil)
2236         return string;
2237     return NSAccessibilityUnknownRole;
2238 }
2239
2240 ALLOW_DEPRECATED_DECLARATIONS_BEGIN
2241 - (NSString*)subrole
2242 {
2243     if (m_object->isPasswordField())
2244         return NSAccessibilitySecureTextFieldSubrole;
2245     if (m_object->isSearchField())
2246         return NSAccessibilitySearchFieldSubrole;
2247     
2248     if (_axBackingObject->isAttachment()) {
2249         NSView* attachView = [self attachmentView];
2250         if ([[attachView accessibilityAttributeNames] containsObject:NSAccessibilitySubroleAttribute])
2251             return [attachView accessibilityAttributeValue:NSAccessibilitySubroleAttribute];
2252     }
2253     
2254     if (m_object->isMeter())
2255         return @"AXMeter";
2256     
2257     AccessibilityRole role = m_object->roleValue();
2258     if (role == AccessibilityRole::HorizontalRule)
2259         return NSAccessibilityContentSeparatorSubrole;
2260     if (role == AccessibilityRole::ToggleButton)
2261         return NSAccessibilityToggleSubrole;
2262     if (role == AccessibilityRole::Footer)
2263         return @"AXFooter";
2264
2265     if (is<AccessibilitySpinButtonPart>(*m_object)) {
2266         if (downcast<AccessibilitySpinButtonPart>(*m_object).isIncrementor())
2267             return NSAccessibilityIncrementArrowSubrole;
2268         
2269         return NSAccessibilityDecrementArrowSubrole;
2270     }
2271     
2272     if (_axBackingObject->isFileUploadButton())
2273         return @"AXFileUploadButton";
2274     
2275     if (m_object->isTreeItem())
2276         return NSAccessibilityOutlineRowSubrole;
2277     
2278     if (m_object->isFieldset())
2279         return @"AXFieldset";
2280     
2281     if (is<AccessibilityList>(*m_object)) {
2282         auto& listObject = downcast<AccessibilityList>(*m_object);
2283         if (listObject.isUnorderedList() || listObject.isOrderedList())
2284             return NSAccessibilityContentListSubrole;
2285         if (listObject.isDescriptionList()) {
2286             return NSAccessibilityDescriptionListSubrole;
2287         }
2288     }
2289     
2290     // ARIA content subroles.
2291     switch (role) {
2292     case AccessibilityRole::LandmarkBanner:
2293         return @"AXLandmarkBanner";
2294     case AccessibilityRole::LandmarkComplementary:
2295         return @"AXLandmarkComplementary";
2296     case AccessibilityRole::LandmarkContentInfo:
2297         return @"AXLandmarkContentInfo";
2298     case AccessibilityRole::LandmarkMain:
2299         return @"AXLandmarkMain";
2300     case AccessibilityRole::LandmarkNavigation:
2301         return @"AXLandmarkNavigation";
2302     case AccessibilityRole::LandmarkDocRegion:
2303     case AccessibilityRole::LandmarkRegion:
2304         return @"AXLandmarkRegion";
2305     case AccessibilityRole::LandmarkSearch:
2306         return @"AXLandmarkSearch";
2307     case AccessibilityRole::ApplicationAlert:
2308         return @"AXApplicationAlert";
2309     case AccessibilityRole::ApplicationAlertDialog:
2310         return @"AXApplicationAlertDialog";
2311     case AccessibilityRole::ApplicationDialog:
2312         return @"AXApplicationDialog";
2313     case AccessibilityRole::ApplicationGroup:
2314     case AccessibilityRole::ApplicationTextGroup:
2315     case AccessibilityRole::Feed:
2316     case AccessibilityRole::Footnote:
2317         return @"AXApplicationGroup";
2318     case AccessibilityRole::ApplicationLog:
2319         return @"AXApplicationLog";
2320     case AccessibilityRole::ApplicationMarquee:
2321         return @"AXApplicationMarquee";
2322     case AccessibilityRole::ApplicationStatus:
2323         return @"AXApplicationStatus";
2324     case AccessibilityRole::ApplicationTimer:
2325         return @"AXApplicationTimer";
2326     case AccessibilityRole::Document:
2327     case AccessibilityRole::GraphicsDocument:
2328         return @"AXDocument";
2329     case AccessibilityRole::DocumentArticle:
2330         return @"AXDocumentArticle";
2331     case AccessibilityRole::DocumentMath:
2332         return @"AXDocumentMath";
2333     case AccessibilityRole::DocumentNote:
2334         return @"AXDocumentNote";
2335     case AccessibilityRole::UserInterfaceTooltip:
2336         return @"AXUserInterfaceTooltip";
2337     case AccessibilityRole::TabPanel:
2338         return @"AXTabPanel";
2339     case AccessibilityRole::Definition:
2340         return @"AXDefinition";
2341     case AccessibilityRole::DescriptionListTerm:
2342     case AccessibilityRole::Term:
2343         return @"AXTerm";
2344     case AccessibilityRole::DescriptionListDetail:
2345         return @"AXDescription";
2346     case AccessibilityRole::WebApplication:
2347         return @"AXWebApplication";
2348         // Default doesn't return anything, so roles defined below can be chosen.
2349     default:
2350         break;
2351     }
2352     
2353     if (role == AccessibilityRole::MathElement) {
2354         if (m_object->isMathFraction())
2355             return @"AXMathFraction";
2356         if (m_object->isMathFenced())
2357             return @"AXMathFenced";
2358         if (m_object->isMathSubscriptSuperscript())
2359             return @"AXMathSubscriptSuperscript";
2360         if (m_object->isMathRow())
2361             return @"AXMathRow";
2362         if (m_object->isMathUnderOver())
2363             return @"AXMathUnderOver";
2364         if (m_object->isMathSquareRoot())
2365             return @"AXMathSquareRoot";
2366         if (m_object->isMathRoot())
2367             return @"AXMathRoot";
2368         if (m_object->isMathText())
2369             return @"AXMathText";
2370         if (m_object->isMathNumber())
2371             return @"AXMathNumber";
2372         if (m_object->isMathIdentifier())
2373             return @"AXMathIdentifier";
2374         if (m_object->isMathTable())
2375             return @"AXMathTable";
2376         if (m_object->isMathTableRow())
2377             return @"AXMathTableRow";
2378         if (m_object->isMathTableCell())
2379             return @"AXMathTableCell";
2380         if (m_object->isMathFenceOperator())
2381             return @"AXMathFenceOperator";
2382         if (m_object->isMathSeparatorOperator())
2383             return @"AXMathSeparatorOperator";
2384         if (m_object->isMathOperator())
2385             return @"AXMathOperator";
2386         if (m_object->isMathMultiscript())
2387             return @"AXMathMultiscript";
2388     }
2389     
2390     if (role == AccessibilityRole::Video)
2391         return @"AXVideo";
2392     if (role == AccessibilityRole::Audio)
2393         return @"AXAudio";
2394     if (role == AccessibilityRole::Details)
2395         return @"AXDetails";
2396     if (role == AccessibilityRole::Summary)
2397         return @"AXSummary";
2398     if (role == AccessibilityRole::Time)
2399         return @"AXTimeGroup";
2400
2401     if (m_object->isMediaTimeline())
2402         return NSAccessibilityTimelineSubrole;
2403
2404     if (m_object->isSwitch())
2405         return NSAccessibilitySwitchSubrole;
2406
2407     if (role == AccessibilityRole::Insertion)
2408         return @"AXInsertStyleGroup";
2409     if (role == AccessibilityRole::Deletion)
2410         return @"AXDeleteStyleGroup";
2411     if (role == AccessibilityRole::Superscript)
2412         return @"AXSuperscriptStyleGroup";
2413     if (role == AccessibilityRole::Subscript)
2414         return @"AXSubscriptStyleGroup";
2415
2416     if (m_object->isStyleFormatGroup()) {
2417         if (Node* node = m_object->node()) {
2418             if (node->hasTagName(kbdTag))
2419                 return @"AXKeyboardInputStyleGroup";
2420             if (node->hasTagName(codeTag))
2421                 return @"AXCodeStyleGroup";
2422             if (node->hasTagName(preTag))
2423                 return @"AXPreformattedStyleGroup";
2424             if (node->hasTagName(sampTag))
2425                 return @"AXSampleStyleGroup";
2426             if (node->hasTagName(varTag))
2427                 return @"AXVariableStyleGroup";
2428             if (node->hasTagName(citeTag))
2429                 return @"AXCiteStyleGroup";
2430         }
2431     }
2432     
2433     // Ruby subroles
2434     switch (role) {
2435     case AccessibilityRole::RubyBase:
2436         return NSAccessibilityRubyBaseSubrole;
2437     case AccessibilityRole::RubyBlock:
2438         return NSAccessibilityRubyBlockSubrole;
2439     case AccessibilityRole::RubyInline:
2440         return NSAccessibilityRubyInlineSubrole;
2441     case AccessibilityRole::RubyRun:
2442         return NSAccessibilityRubyRunSubrole;
2443     case AccessibilityRole::RubyText:
2444         return NSAccessibilityRubyTextSubrole;
2445     default:
2446         break;
2447     }
2448     
2449     return nil;
2450 }
2451 ALLOW_DEPRECATED_DECLARATIONS_END
2452
2453 - (NSString*)roleDescription
2454 {
2455     if (!m_object)
2456         return nil;
2457
2458     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
2459     // attachments have the AXImage role, but a different subrole
2460     if (_axBackingObject->isAttachment())
2461         return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute];
2462     ALLOW_DEPRECATED_DECLARATIONS_END
2463
2464     const AtomString& overrideRoleDescription = m_object->roleDescription();
2465     if (!overrideRoleDescription.isNull() && !overrideRoleDescription.isEmpty())
2466         return overrideRoleDescription;
2467     
2468     NSString* axRole = [self role];
2469     
2470     if ([axRole isEqualToString:NSAccessibilityGroupRole]) {
2471         
2472         if (m_object->isOutput())
2473             return AXOutputText();
2474         
2475         NSString *ariaLandmarkRoleDescription = [self ariaLandmarkRoleDescription];
2476         if (ariaLandmarkRoleDescription)
2477             return ariaLandmarkRoleDescription;
2478         
2479         switch (m_object->roleValue()) {
2480         case AccessibilityRole::Audio:
2481             return localizedMediaControlElementString("AudioElement");
2482         case AccessibilityRole::Definition:
2483             return AXDefinitionText();
2484         case AccessibilityRole::DescriptionListTerm:
2485         case AccessibilityRole::Term:
2486             return AXDescriptionListTermText();
2487         case AccessibilityRole::DescriptionListDetail:
2488             return AXDescriptionListDetailText();
2489         case AccessibilityRole::Details:
2490             return AXDetailsText();
2491         case AccessibilityRole::Feed:
2492             return AXFeedText();
2493         case AccessibilityRole::Figure:
2494             return AXFigureText();
2495         case AccessibilityRole::Footer:
2496             return AXFooterRoleDescriptionText();
2497         case AccessibilityRole::Mark:
2498             return AXMarkText();
2499         case AccessibilityRole::Video:
2500             return localizedMediaControlElementString("VideoElement");
2501         case AccessibilityRole::GraphicsDocument:
2502             return AXARIAContentGroupText(@"ARIADocument");
2503         default:
2504             return NSAccessibilityRoleDescription(NSAccessibilityGroupRole, [self subrole]);
2505         }
2506     }
2507     
2508     if ([axRole isEqualToString:@"AXWebArea"])
2509         return AXWebAreaText();
2510     
2511     if ([axRole isEqualToString:@"AXLink"])
2512         return AXLinkText();
2513     
2514     if ([axRole isEqualToString:@"AXListMarker"])
2515         return AXListMarkerText();
2516     
2517     if ([axRole isEqualToString:@"AXImageMap"])
2518         return AXImageMapText();
2519     
2520     if ([axRole isEqualToString:@"AXHeading"])
2521         return AXHeadingText();
2522     
2523     if ([axRole isEqualToString:NSAccessibilityTextFieldRole]) {
2524         auto* node = m_object->node();
2525         if (is<HTMLInputElement>(node)) {
2526             auto& input = downcast<HTMLInputElement>(*node);
2527             if (input.isEmailField())
2528                 return AXEmailFieldText();
2529             if (input.isTelephoneField())
2530                 return AXTelephoneFieldText();
2531             if (input.isURLField())
2532                 return AXURLFieldText();
2533             if (input.isNumberField())
2534                 return AXNumberFieldText();
2535             
2536             // These input types are not enabled on mac yet, we check the type attribute for now.
2537             auto& type = input.attributeWithoutSynchronization(typeAttr);
2538             if (equalLettersIgnoringASCIICase(type, "date"))
2539                 return AXDateFieldText();
2540             if (equalLettersIgnoringASCIICase(type, "time"))
2541                 return AXTimeFieldText();
2542             if (equalLettersIgnoringASCIICase(type, "week"))
2543                 return AXWeekFieldText();
2544             if (equalLettersIgnoringASCIICase(type, "month"))
2545                 return AXMonthFieldText();
2546             if (equalLettersIgnoringASCIICase(type, "datetime-local"))
2547                 return AXDateTimeFieldText();
2548         }
2549     }
2550     
2551     if (_axBackingObject->isFileUploadButton())
2552         return AXFileUploadButtonText();
2553     
2554     // Only returning for DL (not UL or OL) because description changed with HTML5 from 'definition list' to
2555     // superset 'description list' and does not return the same values in AX API on some OS versions. 
2556     if (is<AccessibilityList>(*m_object)) {
2557         if (downcast<AccessibilityList>(*m_object).isDescriptionList())
2558             return AXDescriptionListText();
2559     }
2560     
2561     if (m_object->roleValue() == AccessibilityRole::HorizontalRule)
2562         return AXHorizontalRuleDescriptionText();
2563     
2564     // AppKit also returns AXTab for the role description for a tab item.
2565     if (m_object->isTabItem())
2566         return NSAccessibilityRoleDescription(@"AXTab", nil);
2567     
2568     if (m_object->isSummary())
2569         return AXSummaryText();
2570     
2571     // We should try the system default role description for all other roles.
2572     // If we get the same string back, then as a last resort, return unknown.
2573     NSString* defaultRoleDescription = NSAccessibilityRoleDescription(axRole, [self subrole]);
2574     
2575     // On earlier Mac versions (Lion), using a non-standard subrole would result in a role description
2576     // being returned that looked like AXRole:AXSubrole. To make all platforms have the same role descriptions
2577     // we should fallback on a role description ignoring the subrole in these cases.
2578     if ([defaultRoleDescription isEqualToString:[NSString stringWithFormat:@"%@:%@", axRole, [self subrole]]])
2579         defaultRoleDescription = NSAccessibilityRoleDescription(axRole, nil);
2580     
2581     if (![defaultRoleDescription isEqualToString:axRole])
2582         return defaultRoleDescription;
2583     
2584     return NSAccessibilityRoleDescription(NSAccessibilityUnknownRole, nil);
2585 }
2586
2587 - (NSString *)computedRoleString
2588 {
2589     if (!m_object)
2590         return nil;
2591     return m_object->computedRoleString();
2592 }
2593
2594 - (id)scrollViewParent
2595 {
2596     if (!is<AccessibilityScrollView>(m_object))
2597         return nil;
2598     
2599     // If this scroll view provides it's parent object (because it's a sub-frame), then
2600     // we should not find the remoteAccessibilityParent.
2601     if (m_object->parentObject())
2602         return nil;
2603     
2604     ScrollView* scroll = downcast<AccessibilityScrollView>(*m_object).scrollView();
2605     if (!scroll)
2606         return nil;
2607     
2608     if (scroll->platformWidget())
2609         return NSAccessibilityUnignoredAncestor(scroll->platformWidget());
2610     
2611     return [self remoteAccessibilityParentObject];
2612 }
2613
2614 - (NSString *)valueDescriptionForMeter
2615 {
2616     if (!m_object)
2617         return nil;
2618     
2619     String valueDescription = m_object->valueDescription();
2620 #if ENABLE(METER_ELEMENT)
2621     if (!is<AccessibilityProgressIndicator>(m_object))
2622         return valueDescription;
2623     auto &meter = downcast<AccessibilityProgressIndicator>(*m_object);
2624     String gaugeRegionValue = meter.gaugeRegionValueDescription();
2625     if (!gaugeRegionValue.isEmpty()) {
2626         StringBuilder builder;
2627         builder.append(valueDescription);
2628         if (builder.length())
2629             builder.appendLiteral(", ");
2630         builder.append(gaugeRegionValue);
2631         return builder.toString();
2632     }
2633 #endif
2634     return valueDescription;
2635 }
2636
2637 // FIXME: split up this function in a better way.
2638 // suggestions: Use a hash table that maps attribute names to function calls,
2639 // or maybe pointers to member functions
2640 ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
2641 - (id)accessibilityAttributeValue:(NSString*)attributeName
2642 ALLOW_DEPRECATED_IMPLEMENTATIONS_END
2643 {
2644     if (![self updateObjectBackingStore])
2645         return nil;
2646     
2647     if (m_object->isDetachedFromParent())
2648         return nil;
2649     
2650     if ([attributeName isEqualToString: NSAccessibilityRoleAttribute])
2651         return [self role];
2652     
2653     if ([attributeName isEqualToString: NSAccessibilitySubroleAttribute])
2654         return [self subrole];
2655     
2656     if ([attributeName isEqualToString: NSAccessibilityRoleDescriptionAttribute])
2657         return [self roleDescription];
2658
2659     // AXARIARole is only used by DumpRenderTree (so far).
2660     if ([attributeName isEqualToString:@"AXARIARole"])
2661         return [self computedRoleString];
2662     
2663     if ([attributeName isEqualToString: NSAccessibilityParentAttribute]) {
2664         
2665         // This will return the parent of the AXWebArea, if this is a web area.
2666         id scrollViewParent = [self scrollViewParent];
2667         if (scrollViewParent)
2668             return scrollViewParent;
2669         
2670         // Tree item (changed to AXRows) can only report the tree (AXOutline) as its parent.
2671         if (_axBackingObject->isTreeItem()) {
2672             auto parent = _axBackingObject->parentObjectInterfaceUnignored();
2673             while (parent) {
2674                 if (parent->isTree())
2675                     return parent->wrapper();
2676                 parent = parent->parentObjectInterfaceUnignored();
2677             }
2678         }
2679         
2680         auto parent = _axBackingObject->parentObjectInterfaceUnignored();
2681         if (!parent)
2682             return nil;
2683         
2684         // In WebKit1, the scroll view is provided by the system (the attachment view), so the parent
2685         // should be reported directly as such.
2686         if (m_object->isWebArea() && parent->isAttachment())
2687             return [parent->wrapper() attachmentView];
2688         
2689         return parent->wrapper();
2690     }
2691     
2692     if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute] || [attributeName isEqualToString: NSAccessibilityChildrenInNavigationOrderAttribute]) {
2693         if (!self.childrenVectorSize) {
2694             NSArray* children = [self renderWidgetChildren];
2695             if (children != nil)
2696                 return children;
2697         }
2698         
2699         // The tree's (AXOutline) children are supposed to be its rows and columns.
2700         // The ARIA spec doesn't have columns, so we just need rows.
2701         if (m_object->isTree())
2702             return [self accessibilityAttributeValue:NSAccessibilityRowsAttribute];
2703         
2704         // A tree item should only expose its content as its children (not its rows)
2705         if (m_object->isTreeItem()) {
2706             AccessibilityObject::AccessibilityChildrenVector contentCopy;
2707             m_object->ariaTreeItemContent(contentCopy);
2708             return convertToNSArray(contentCopy);
2709         }
2710         
2711         return self.childrenVectorArray;
2712     }
2713     
2714     if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute]) {
2715         if (m_object->canHaveSelectedChildren()) {
2716             AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
2717             m_object->selectedChildren(selectedChildrenCopy);
2718             return convertToNSArray(selectedChildrenCopy);
2719         }
2720         return nil;
2721     }
2722     
2723     if ([attributeName isEqualToString: NSAccessibilityVisibleChildrenAttribute]) {
2724         if (m_object->isListBox()) {
2725             AccessibilityObject::AccessibilityChildrenVector visibleChildrenCopy;
2726             m_object->visibleChildren(visibleChildrenCopy);
2727             return convertToNSArray(visibleChildrenCopy);
2728         }
2729         else if (m_object->isList())
2730             return [self accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
2731         
2732         return nil;
2733     }
2734     
2735     
2736     if (m_object->isWebArea()) {
2737         if ([attributeName isEqualToString:@"AXLinkUIElements"]) {
2738             AccessibilityObject::AccessibilityChildrenVector links;
2739             downcast<AccessibilityRenderObject>(*m_object).getDocumentLinks(links);
2740             return convertToNSArray(links);
2741         }
2742         if ([attributeName isEqualToString:@"AXLoaded"])
2743             return [NSNumber numberWithBool:m_object->isLoaded()];
2744         if ([attributeName isEqualToString:@"AXLayoutCount"])
2745             return [NSNumber numberWithInt:m_object->layoutCount()];
2746         if ([attributeName isEqualToString:NSAccessibilityLoadingProgressAttribute])
2747             return [NSNumber numberWithDouble:m_object->estimatedLoadingProgress()];
2748         if ([attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
2749             return [NSNumber numberWithBool:m_object->preventKeyboardDOMEventDispatch()];
2750         if ([attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])
2751             return [NSNumber numberWithBool:m_object->caretBrowsingEnabled()];
2752         if ([attributeName isEqualToString:NSAccessibilityWebSessionIDAttribute]) {
2753             if (auto* document = m_object->topDocument()) {
2754                 if (auto* page = document->page())
2755                     return [NSNumber numberWithUnsignedLongLong:page->sessionID().toUInt64()];
2756             }
2757         }
2758     }
2759     
2760     if (m_object->isTextControl()) {
2761         if ([attributeName isEqualToString: NSAccessibilityNumberOfCharactersAttribute]) {
2762             int length = m_object->textLength();
2763             if (length < 0)
2764                 return nil;
2765             return [NSNumber numberWithUnsignedInt:length];
2766         }
2767         if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]) {
2768             String selectedText = m_object->selectedText();
2769             if (selectedText.isNull())
2770                 return nil;
2771             return (NSString*)selectedText;
2772         }
2773         if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) {
2774             PlainTextRange textRange = m_object->selectedTextRange();
2775             return [NSValue valueWithRange:NSMakeRange(textRange.start, textRange.length)];
2776         }
2777         // TODO: Get actual visible range. <rdar://problem/4712101>
2778         if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute])
2779             return m_object->isPasswordField() ? nil : [NSValue valueWithRange: NSMakeRange(0, m_object->textLength())];
2780         if ([attributeName isEqualToString: NSAccessibilityInsertionPointLineNumberAttribute]) {
2781             // if selectionEnd > 0, then there is selected text and this question should not be answered
2782             if (m_object->isPasswordField() || m_object->selectionEnd() > 0)
2783                 return nil;
2784             
2785             auto focusedObject = downcast<AccessibilityObject>(m_object->focusedUIElement());
2786             if (focusedObject != m_object)
2787                 return nil;
2788             
2789             VisiblePosition focusedPosition = focusedObject->visiblePositionForIndex(focusedObject->selectionStart(), true);
2790             int lineNumber = m_object->lineForPosition(focusedPosition);
2791             if (lineNumber < 0)
2792                 return nil;
2793             
2794             return [NSNumber numberWithInt:lineNumber];
2795         }
2796     }
2797     
2798     if ([attributeName isEqualToString: NSAccessibilityURLAttribute]) {
2799         URL url = m_object->url();
2800         if (url.isNull())
2801             return nil;
2802         return (NSURL*)url;
2803     }
2804
2805     // Only native spin buttons have increment and decrement buttons.
2806     if (is<AccessibilitySpinButton>(*m_object)) {
2807         if ([attributeName isEqualToString:NSAccessibilityIncrementButtonAttribute])
2808             return downcast<AccessibilitySpinButton>(*m_object).incrementButton()->wrapper();
2809         if ([attributeName isEqualToString:NSAccessibilityDecrementButtonAttribute])
2810             return downcast<AccessibilitySpinButton>(*m_object).decrementButton()->wrapper();
2811     }
2812     
2813     if ([attributeName isEqualToString: @"AXVisited"])
2814         return [NSNumber numberWithBool: m_object->isVisited()];
2815     
2816     if ([attributeName isEqualToString: NSAccessibilityTitleAttribute]) {
2817         if (_axBackingObject->isAttachment()) {
2818             if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityTitleAttribute])
2819                 return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityTitleAttribute];
2820         }
2821         
2822         // Meter elements should communicate their content via AXValueDescription.
2823         if (m_object->isMeter())
2824             return [NSString string];
2825         
2826         // Summary element should use its text node as AXTitle.
2827         if (m_object->isSummary())
2828             return m_object->textUnderElement();
2829         
2830         return [self baseAccessibilityTitle];
2831     }
2832     
2833     if ([attributeName isEqualToString: NSAccessibilityDescriptionAttribute]) {
2834         if (_axBackingObject->isAttachment()) {
2835             if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityDescriptionAttribute])
2836                 return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityDescriptionAttribute];
2837         }
2838         return [self baseAccessibilityDescription];
2839     }
2840     
2841     if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
2842         if (_axBackingObject->isAttachment()) {
2843             if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityValueAttribute])
2844                 return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityValueAttribute];
2845         }
2846         if (m_object->supportsRangeValue())
2847             return [NSNumber numberWithFloat:m_object->valueForRange()];
2848         if (m_object->roleValue() == AccessibilityRole::SliderThumb)
2849             return [NSNumber numberWithFloat:m_object->parentObject()->valueForRange()];
2850         if (m_object->isHeading())
2851             return [NSNumber numberWithInt:m_object->headingLevel()];
2852         
2853         if (m_object->isCheckboxOrRadio() || m_object->isMenuItem() || m_object->isSwitch() || m_object->isToggleButton()) {
2854             switch (m_object->checkboxOrRadioValue()) {
2855             case AccessibilityButtonState::Off:
2856                 return [NSNumber numberWithInt:0];
2857             case AccessibilityButtonState::On:
2858                 return [NSNumber numberWithInt:1];
2859             case AccessibilityButtonState::Mixed:
2860                 return [NSNumber numberWithInt:2];
2861             }
2862         }
2863         
2864         // radio groups return the selected radio button as the AXValue
2865         if (m_object->isRadioGroup()) {
2866             AccessibilityObject* radioButton = m_object->selectedRadioButton();
2867             if (!radioButton)
2868                 return nil;
2869             return radioButton->wrapper();
2870         }
2871         
2872         if (m_object->isTabList()) {
2873             AccessibilityObject* tabItem = m_object->selectedTabItem();
2874             if (!tabItem)
2875                 return nil;
2876             return tabItem->wrapper();
2877         }
2878         
2879         if (m_object->isTabItem())
2880             return [NSNumber numberWithInt:m_object->isSelected()];
2881         
2882         if (m_object->isColorWell()) {
2883             int r, g, b;
2884             m_object->colorValue(r, g, b);
2885             return [NSString stringWithFormat:@"rgb %7.5f %7.5f %7.5f 1", r / 255., g / 255., b / 255.];
2886         }
2887         
2888         return m_object->stringValue();
2889     }
2890
2891     if ([attributeName isEqualToString:(NSString *)kAXMenuItemMarkCharAttribute]) {
2892         const unichar ch = 0x2713; // ✓ used on Mac for selected menu items.
2893         return (m_object->isChecked()) ? [NSString stringWithCharacters:&ch length:1] : nil;
2894     }
2895     
2896     if ([attributeName isEqualToString: NSAccessibilityMinValueAttribute]) {
2897         // Indeterminate progress indicator should return 0.
2898         if (m_object->ariaRoleAttribute() == AccessibilityRole::ProgressIndicator && !m_object->hasAttribute(aria_valuenowAttr))
2899             return @0;
2900         return [NSNumber numberWithFloat:m_object->minValueForRange()];
2901     }
2902     
2903     if ([attributeName isEqualToString: NSAccessibilityMaxValueAttribute]) {
2904         // Indeterminate progress indicator should return 0.
2905         if (m_object->ariaRoleAttribute() == AccessibilityRole::ProgressIndicator && !m_object->hasAttribute(aria_valuenowAttr))
2906             return @0;
2907         return [NSNumber numberWithFloat:m_object->maxValueForRange()];
2908     }
2909     
2910     if ([attributeName isEqualToString: NSAccessibilityHelpAttribute])
2911         return [self baseAccessibilityHelpText];
2912     
2913     if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute])
2914         return [NSNumber numberWithBool: m_object->isFocused()];
2915     
2916     if ([attributeName isEqualToString: NSAccessibilityEnabledAttribute])
2917         return [NSNumber numberWithBool: m_object->isEnabled()];
2918     
2919     if ([attributeName isEqualToString: NSAccessibilitySizeAttribute]) {
2920         IntSize s = snappedIntRect(m_object->elementRect()).size();
2921         return [NSValue valueWithSize: NSMakeSize(s.width(), s.height())];
2922     }
2923     
2924     if ([attributeName isEqualToString: NSAccessibilityPrimaryScreenHeightAttribute])
2925         return [self primaryScreenHeight];
2926     if ([attributeName isEqualToString: NSAccessibilityPositionAttribute])
2927         return [self position];
2928     if ([attributeName isEqualToString:NSAccessibilityPathAttribute])
2929         return [self path];
2930     
2931     if ([attributeName isEqualToString: NSAccessibilityWindowAttribute] ||
2932         [attributeName isEqualToString: NSAccessibilityTopLevelUIElementAttribute]) {
2933         
2934         id remoteParent = [self remoteAccessibilityParentObject];
2935         if (remoteParent)
2936             return [remoteParent accessibilityAttributeValue:attributeName];
2937         
2938         FrameView* fv = m_object->documentFrameView();
2939         if (fv)
2940             return [fv->platformWidget() window];
2941         return nil;
2942     }
2943     
2944     if ([attributeName isEqualToString:NSAccessibilityAccessKeyAttribute]) {
2945         AtomString accessKey = m_object->accessKey();
2946         if (accessKey.isNull())
2947             return nil;
2948         return accessKey;
2949     }
2950     
2951     if ([attributeName isEqualToString:NSAccessibilityLinkRelationshipTypeAttribute])
2952         return m_object->linkRelValue();
2953     
2954     if ([attributeName isEqualToString:NSAccessibilityTabsAttribute]) {
2955         if (m_object->isTabList()) {
2956             AccessibilityObject::AccessibilityChildrenVector tabsChildren;
2957             m_object->tabChildren(tabsChildren);
2958             return convertToNSArray(tabsChildren);
2959         }
2960     }
2961     
2962     if ([attributeName isEqualToString:NSAccessibilityContentsAttribute]) {
2963         // The contents of a tab list are all the children except the tabs.
2964         if (m_object->isTabList()) {
2965             auto children = self.childrenVectorArray;
2966             AccessibilityObject::AccessibilityChildrenVector tabs;
2967             m_object->tabChildren(tabs);
2968             auto tabsChildren = convertToNSArray(tabs);
2969
2970             NSMutableArray *contents = [NSMutableArray array];
2971             for (id childWrapper in children) {
2972                 if ([tabsChildren containsObject:childWrapper])
2973                     [contents addObject:childWrapper];
2974             }
2975             return contents;
2976         } else if (m_object->isScrollView()) {
2977             // A scrollView's contents are everything except the scroll bars.
2978             auto children = self.childrenVectorArray;
2979             NSMutableArray *contents = [NSMutableArray array];
2980
2981             for (WebAccessibilityObjectWrapper *childWrapper in children) {
2982                 if (auto backingObject = [childWrapper axBackingObject]) {
2983                     if (!backingObject->isScrollbar())
2984                         [contents addObject:childWrapper];
2985                 }
2986             }
2987             return contents;
2988         }
2989     }
2990     
2991     if (is<AccessibilityTable>(*m_object) && downcast<AccessibilityTable>(*m_object).isExposableThroughAccessibility()) {
2992         auto& table = downcast<AccessibilityTable>(*m_object);
2993         if ([attributeName isEqualToString:NSAccessibilityRowsAttribute])
2994             return convertToNSArray(table.rows());
2995         
2996         if ([attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
2997             AccessibilityObject::AccessibilityChildrenVector visibleRows;
2998             table.visibleRows(visibleRows);
2999             return convertToNSArray(visibleRows);
3000         }
3001         
3002         // TODO: distinguish between visible and non-visible columns
3003         if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute] ||
3004             [attributeName isEqualToString:NSAccessibilityVisibleColumnsAttribute]) {
3005             return convertToNSArray(table.columns());
3006         }
3007         
3008         if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
3009             AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
3010             m_object->selectedChildren(selectedChildrenCopy);
3011             return convertToNSArray(selectedChildrenCopy);
3012         }
3013         
3014         // HTML tables don't support these
3015         if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute] ||
3016             [attributeName isEqualToString:NSAccessibilitySelectedCellsAttribute])
3017             return nil;
3018         
3019         if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
3020             AccessibilityObject::AccessibilityChildrenVector columnHeaders;
3021             table.columnHeaders(columnHeaders);
3022             return convertToNSArray(columnHeaders);
3023         }
3024         
3025         if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
3026             AccessibilityObject* headerContainer = table.headerContainer();
3027             if (headerContainer)
3028                 return headerContainer->wrapper();
3029             return nil;
3030         }
3031         
3032         if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
3033             AccessibilityObject::AccessibilityChildrenVector rowHeaders;
3034             table.rowHeaders(rowHeaders);
3035             return convertToNSArray(rowHeaders);
3036         }
3037         
3038         if ([attributeName isEqualToString:NSAccessibilityVisibleCellsAttribute]) {
3039             AccessibilityObject::AccessibilityChildrenVector cells;
3040             table.cells(cells);
3041             return convertToNSArray(cells);
3042         }
3043         
3044         if ([attributeName isEqualToString:NSAccessibilityColumnCountAttribute])
3045             return @(table.columnCount());
3046         
3047         if ([attributeName isEqualToString:NSAccessibilityRowCountAttribute])
3048             return @(table.rowCount());
3049         
3050         if ([attributeName isEqualToString:NSAccessibilityARIAColumnCountAttribute])
3051             return @(table.axColumnCount());
3052         
3053         if ([attributeName isEqualToString:NSAccessibilityARIARowCountAttribute])
3054             return @(table.axRowCount());
3055     }
3056     
3057     if (is<AccessibilityTableColumn>(*m_object)) {
3058         auto& column = downcast<AccessibilityTableColumn>(*m_object);
3059         if ([attributeName isEqualToString:NSAccessibilityIndexAttribute])
3060             return [NSNumber numberWithInt:column.columnIndex()];
3061         
3062         // rows attribute for a column is the list of all the elements in that column at each row
3063         if ([attributeName isEqualToString:NSAccessibilityRowsAttribute] ||
3064             [attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
3065             return convertToNSArray(column.children());
3066         }
3067         if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
3068             AccessibilityObject* header = column.headerObject();
3069             if (!header)
3070                 return nil;
3071             return header->wrapper();
3072         }
3073     }
3074     
3075     if (is<AccessibilityTableCell>(*m_object)) {
3076         auto& cell = downcast<AccessibilityTableCell>(*m_object);
3077         if ([attributeName isEqualToString:NSAccessibilityRowIndexRangeAttribute]) {
3078             std::pair<unsigned, unsigned> rowRange;
3079             cell.rowIndexRange(rowRange);
3080             return [NSValue valueWithRange:NSMakeRange(rowRange.first, rowRange.second)];
3081         }
3082         if ([attributeName isEqualToString:NSAccessibilityColumnIndexRangeAttribute]) {
3083             std::pair<unsigned, unsigned> columnRange;
3084             cell.columnIndexRange(columnRange);
3085             return [NSValue valueWithRange:NSMakeRange(columnRange.first, columnRange.second)];
3086         }
3087         if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
3088             AccessibilityObject::AccessibilityChildrenVector columnHeaders;
3089             cell.columnHeaders(columnHeaders);
3090             return convertToNSArray(columnHeaders);
3091         }
3092         if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
3093             AccessibilityObject::AccessibilityChildrenVector rowHeaders;
3094             cell.rowHeaders(rowHeaders);
3095             return convertToNSArray(rowHeaders);
3096         }
3097         if ([attributeName isEqualToString:NSAccessibilityARIAColumnIndexAttribute])
3098             return @(cell.axColumnIndex());
3099         
3100         if ([attributeName isEqualToString:NSAccessibilityARIARowIndexAttribute])
3101             return @(cell.axRowIndex());
3102     }
3103     
3104     if (m_object->isTree()) {
3105         if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
3106             AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
3107             m_object->selectedChildren(selectedChildrenCopy);
3108             return convertToNSArray(selectedChildrenCopy);
3109         }
3110         if ([attributeName isEqualToString:NSAccessibilityRowsAttribute]) {
3111             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
3112             m_object->ariaTreeRows(rowsCopy);
3113             return convertToNSArray(rowsCopy);
3114         }
3115         
3116         // TreeRoles do not support columns, but Mac AX expects to be able to ask about columns at the least.
3117         if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute])
3118             return [NSArray array];
3119     }
3120     
3121     if ([attributeName isEqualToString:NSAccessibilityIndexAttribute]) {
3122         if (m_object->isTreeItem()) {
3123             AccessibilityObject* parent = m_object->parentObject();
3124             for (; parent && !parent->isTree(); parent = parent->parentObject())
3125             { }
3126             
3127             if (!parent)
3128                 return nil;
3129             
3130             // Find the index of this item by iterating the parents.
3131             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
3132             parent->ariaTreeRows(rowsCopy);
3133             size_t count = rowsCopy.size();
3134             for (size_t k = 0; k < count; ++k)
3135                 if (rowsCopy[k]->wrapper() == self)
3136                     return [NSNumber numberWithUnsignedInt:k];
3137             
3138             return nil;
3139         }
3140         if (is<AccessibilityTableRow>(*m_object)) {
3141             if ([attributeName isEqualToString:NSAccessibilityIndexAttribute])
3142                 return [NSNumber numberWithInt:downcast<AccessibilityTableRow>(*m_object).rowIndex()];
3143         }
3144     }
3145     
3146     // The rows that are considered inside this row.
3147     if ([attributeName isEqualToString:NSAccessibilityDisclosedRowsAttribute]) {
3148         if (m_object->isTreeItem()) {
3149             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
3150             m_object->ariaTreeItemDisclosedRows(rowsCopy);
3151             return convertToNSArray(rowsCopy);
3152         } else if (is<AccessibilityARIAGridRow>(*m_object)) {
3153             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
3154             downcast<AccessibilityARIAGridRow>(*m_object).disclosedRows(rowsCopy);
3155             return convertToNSArray(rowsCopy);
3156         }
3157     }
3158     
3159     // The row that contains this row. It should be the same as the first parent that is a treeitem.
3160     if ([attributeName isEqualToString:NSAccessibilityDisclosedByRowAttribute]) {
3161         if (m_object->isTreeItem()) {
3162             AccessibilityObject* parent = m_object->parentObject();
3163             while (parent) {
3164                 if (parent->isTreeItem())
3165                     return parent->wrapper();
3166                 // If the parent is the tree itself, then this value == nil.
3167                 if (parent->isTree())
3168                     return nil;
3169                 parent = parent->parentObject();
3170             }
3171             return nil;
3172         } else if (is<AccessibilityARIAGridRow>(*m_object)) {
3173             AccessibilityObject* row = downcast<AccessibilityARIAGridRow>(*m_object).disclosedByRow();
3174             if (!row)
3175                 return nil;
3176             return row->wrapper();
3177         }
3178     }
3179     
3180     if ([attributeName isEqualToString:NSAccessibilityDisclosureLevelAttribute]) {
3181         // Convert from 1-based level (from aria-level spec) to 0-based level (Mac)
3182         int level = m_object->hierarchicalLevel();
3183         if (level > 0)
3184             level -= 1;
3185         return [NSNumber numberWithInt:level];
3186     }
3187     if ([attributeName isEqualToString:NSAccessibilityDisclosingAttribute])
3188         return [NSNumber numberWithBool:m_object->isExpanded()];
3189     
3190     if (m_object->isList() && [attributeName isEqualToString:NSAccessibilityOrientationAttribute])
3191         return NSAccessibilityVerticalOrientationValue;
3192     
3193     if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"])
3194         return [self textMarkerRangeForSelection];
3195     
3196     if (m_object->renderer()) {
3197         if ([attributeName isEqualToString: @"AXStartTextMarker"])
3198             return [self textMarkerForVisiblePosition:startOfDocument(&m_object->renderer()->document())];
3199         if ([attributeName isEqualToString: @"AXEndTextMarker"])
3200             return [self textMarkerForVisiblePosition:endOfDocument(&m_object->renderer()->document())];
3201     }
3202     
3203     if ([attributeName isEqualToString:NSAccessibilityBlockQuoteLevelAttribute])
3204         return [NSNumber numberWithUnsignedInt:m_object->blockquoteLevel()];
3205     if ([attributeName isEqualToString:@"AXTableLevel"])
3206         return [NSNumber numberWithInt:m_object->tableLevel()];
3207     
3208     if ([attributeName isEqualToString: NSAccessibilityLinkedUIElementsAttribute]) {
3209         AccessibilityObject::AccessibilityChildrenVector linkedUIElements;
3210         m_object->linkedUIElements(linkedUIElements);
3211         return convertToNSArray(linkedUIElements);
3212     }
3213     
3214     if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute])
3215         return [NSNumber numberWithBool:m_object->isSelected()];
3216     
3217     if ([attributeName isEqualToString: NSAccessibilityARIACurrentAttribute])
3218         return m_object->currentValue();
3219     
3220     if ([attributeName isEqualToString: NSAccessibilityServesAsTitleForUIElementsAttribute] && m_object->isMenuButton()) {
3221         AccessibilityObject* uiElement = downcast<AccessibilityRenderObject>(*m_object).menuForMenuButton();
3222         if (uiElement)
3223             return [NSArray arrayWithObject:uiElement->wrapper()];
3224     }
3225     
3226     if ([attributeName isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
3227         if (!m_object->exposesTitleUIElement())
3228             return nil;
3229         
3230         AccessibilityObject* obj = m_object->titleUIElement();
3231         if (obj)
3232             return obj->wrapper();
3233         return nil;
3234     }
3235     
3236     if ([attributeName isEqualToString:NSAccessibilityValueDescriptionAttribute]) {
3237         if (m_object->isMeter())
3238             return [self valueDescriptionForMeter];
3239         return m_object->valueDescription();
3240     }
3241     
3242     if ([attributeName isEqualToString:NSAccessibilityOrientationAttribute]) {
3243         AccessibilityOrientation elementOrientation = m_object->orientation();
3244         if (elementOrientation == AccessibilityOrientation::Vertical)
3245             return NSAccessibilityVerticalOrientationValue;
3246         if (elementOrientation == AccessibilityOrientation::Horizontal)
3247             return NSAccessibilityHorizontalOrientationValue;
3248         if (elementOrientation == AccessibilityOrientation::Undefined)
3249             return NSAccessibilityUnknownOrientationValue;
3250         return nil;
3251     }
3252     
3253     if ([attributeName isEqualToString:NSAccessibilityHorizontalScrollBarAttribute]) {
3254         AccessibilityObject* scrollBar = m_object->scrollBar(AccessibilityOrientation::Horizontal);
3255         if (scrollBar)
3256             return scrollBar->wrapper();
3257         return nil;
3258     }
3259     if ([attributeName isEqualToString:NSAccessibilityVerticalScrollBarAttribute]) {
3260         AccessibilityObject* scrollBar = m_object->scrollBar(AccessibilityOrientation::Vertical);
3261         if (scrollBar)
3262             return scrollBar->wrapper();
3263         return nil;
3264     }
3265     
3266     if ([attributeName isEqualToString:NSAccessibilitySortDirectionAttribute]) {
3267         switch (m_object->sortDirection()) {
3268         case AccessibilitySortDirection::Ascending:
3269             return NSAccessibilityAscendingSortDirectionValue;
3270         case AccessibilitySortDirection::Descending:
3271             return NSAccessibilityDescendingSortDirectionValue;
3272         default:
3273             return NSAccessibilityUnknownSortDirectionValue;
3274         }
3275     }
3276     
3277     if ([attributeName isEqualToString:NSAccessibilityLanguageAttribute])
3278         return m_object->language();
3279     
3280     if ([attributeName isEqualToString:NSAccessibilityExpandedAttribute])
3281         return [NSNumber numberWithBool:m_object->isExpanded()];
3282     
3283     if ([attributeName isEqualToString:NSAccessibilityRequiredAttribute])
3284         return [NSNumber numberWithBool:m_object->isRequired()];
3285     
3286     if ([attributeName isEqualToString:NSAccessibilityInvalidAttribute])
3287         return m_object->invalidStatus();
3288     
3289     if ([attributeName isEqualToString:NSAccessibilityOwnsAttribute]) {
3290         AccessibilityObject::AccessibilityChildrenVector ariaOwns;
3291         m_object->ariaOwnsElements(ariaOwns);
3292         return convertToNSArray(ariaOwns);
3293     }
3294     
3295     if ([attributeName isEqualToString:NSAccessibilityARIAPosInSetAttribute])
3296         return [NSNumber numberWithInt:m_object->posInSet()];
3297     if ([attributeName isEqualToString:NSAccessibilityARIASetSizeAttribute])
3298         return [NSNumber numberWithInt:m_object->setSize()];
3299     
3300     if ([attributeName isEqualToString:NSAccessibilityGrabbedAttribute])
3301         return [NSNumber numberWithBool:m_object->isARIAGrabbed()];
3302     
3303     if ([attributeName isEqualToString:NSAccessibilityDropEffectsAttribute]) {
3304         Vector<String> dropEffects = m_object->determineARIADropEffects();
3305         return convertStringsToNSArray(dropEffects);
3306     }
3307     
3308     if ([attributeName isEqualToString:NSAccessibilityPlaceholderValueAttribute])
3309         return m_object->placeholderValue();
3310
3311     if ([attributeName isEqualToString:NSAccessibilityValueAutofillAvailableAttribute])
3312         return @(m_object->isValueAutofillAvailable());
3313     
3314     if ([attributeName isEqualToString:NSAccessibilityValueAutofillTypeAttribute]) {
3315         switch (m_object->valueAutofillButtonType()) {
3316         case AutoFillButtonType::None:
3317             return @"none";
3318         case AutoFillButtonType::Credentials:
3319             return @"credentials";
3320         case AutoFillButtonType::Contacts:
3321             return @"contacts";
3322         case AutoFillButtonType::StrongPassword:
3323             return @"strong password";
3324         case AutoFillButtonType::CreditCard:
3325             return @"credit card";
3326         }
3327     }
3328     
3329     if ([attributeName isEqualToString:NSAccessibilityValueAutofilledAttribute])
3330         return @(m_object->isValueAutofilled());
3331
3332     if ([attributeName isEqualToString:NSAccessibilityHasPopupAttribute])
3333         return [NSNumber numberWithBool:m_object->hasPopup()];
3334
3335     if ([attributeName isEqualToString:NSAccessibilityDatetimeValueAttribute])
3336         return m_object->datetimeAttributeValue();
3337     
3338     if ([attributeName isEqualToString:NSAccessibilityInlineTextAttribute])
3339         return @(m_object->renderer() && is<RenderInline>(m_object->renderer()));
3340     
3341     // ARIA Live region attributes.
3342     if ([attributeName isEqualToString:NSAccessibilityARIALiveAttribute])
3343         return m_object->liveRegionStatus();
3344     if ([attributeName isEqualToString:NSAccessibilityARIARelevantAttribute])
3345         return m_object->liveRegionRelevant();
3346     if ([attributeName isEqualToString:NSAccessibilityARIAAtomicAttribute])
3347         return [NSNumber numberWithBool:m_object->liveRegionAtomic()];
3348     if ([attributeName isEqualToString:NSAccessibilityElementBusyAttribute])
3349         return [NSNumber numberWithBool:m_object->isBusy()];
3350     
3351     // MathML Attributes.
3352     if (m_object->isMathElement()) {
3353         if ([attributeName isEqualToString:NSAccessibilityMathRootIndexAttribute])
3354             return (m_object->mathRootIndexObject()) ? m_object->mathRootIndexObject()->wrapper() : 0;
3355         if ([attributeName isEqualToString:NSAccessibilityMathRootRadicandAttribute])
3356             return (m_object->mathRadicandObject()) ? m_object->mathRadicandObject()->wrapper() : 0;
3357         if ([attributeName isEqualToString:NSAccessibilityMathFractionNumeratorAttribute])
3358             return (m_object->mathNumeratorObject()) ? m_object->mathNumeratorObject()->wrapper() : 0;
3359         if ([attributeName isEqualToString:NSAccessibilityMathFractionDenominatorAttribute])
3360             return (m_object->mathDenominatorObject()) ? m_object->mathDenominatorObject()->wrapper() : 0;
3361         if ([attributeName isEqualToString:NSAccessibilityMathBaseAttribute])
3362             return (m_object->mathBaseObject()) ? m_object->mathBaseObject()->wrapper() : 0;
3363         if ([attributeName isEqualToString:NSAccessibilityMathSubscriptAttribute])
3364             return (m_object->mathSubscriptObject()) ? m_object->mathSubscriptObject()->wrapper() : 0;
3365         if ([attributeName isEqualToString:NSAccessibilityMathSuperscriptAttribute])
3366             return (m_object->mathSuperscriptObject()) ? m_object->mathSuperscriptObject()->wrapper() : 0;
3367         if ([attributeName isEqualToString:NSAccessibilityMathUnderAttribute])
3368             return (m_object->mathUnderObject()) ? m_object->mathUnderObject()->wrapper() : 0;
3369         if ([attributeName isEqualToString:NSAccessibilityMathOverAttribute])
3370             return (m_object->mathOverObject()) ? m_object->mathOverObject()->wrapper() : 0;
3371         if ([attributeName isEqualToString:NSAccessibilityMathFencedOpenAttribute])
3372             return m_object->mathFencedOpenString();
3373         if ([attributeName isEqualToString:NSAccessibilityMathFencedCloseAttribute])
3374             return m_object->mathFencedCloseString();
3375         if ([attributeName isEqualToString:NSAccessibilityMathLineThicknessAttribute])
3376             return [NSNumber numberWithInteger:m_object->mathLineThickness()];
3377         if ([attributeName isEqualToString:NSAccessibilityMathPostscriptsAttribute])
3378             return [self accessibilityMathPostscriptPairs];
3379         if ([attributeName isEqualToString:NSAccessibilityMathPrescriptsAttribute])
3380             return [self accessibilityMathPrescriptPairs];
3381     }
3382     
3383     if ([attributeName isEqualToString:NSAccessibilityExpandedTextValueAttribute])
3384         return m_object->expandedTextValue();
3385     
3386     if ([attributeName isEqualToString:NSAccessibilityDOMIdentifierAttribute])
3387         return m_object->identifierAttribute();
3388     if ([attributeName isEqualToString:NSAccessibilityDOMClassListAttribute]) {
3389         Vector<String> classList;
3390         m_object->classList(classList);
3391         return convertStringsToNSArray(classList);
3392     }
3393     
3394     // This allows us to connect to a plugin that creates a shadow node for editing (like PDFs).
3395     if ([attributeName isEqualToString:@"_AXAssociatedPluginParent"])
3396         return [self associatedPluginParent];
3397     
3398     // this is used only by DumpRenderTree for testing
3399     if ([attributeName isEqualToString:@"AXClickPoint"])
3400         return [NSValue valueWithPoint:m_object->clickPoint()];
3401     
3402     // This is used by DRT to verify CSS3 speech works.
3403     if ([attributeName isEqualToString:@"AXDRTSpeechAttribute"])
3404         return [self baseAccessibilitySpeechHint];
3405     
3406     // Used by DRT to find an accessible node by its element id.
3407     if ([attributeName isEqualToString:@"AXDRTElementIdAttribute"])
3408         return m_object->getAttribute(idAttr);
3409     
3410     if ([attributeName isEqualToString:@"AXAutocompleteValue"])
3411         return m_object->autoCompleteValue();
3412
3413     if ([attributeName isEqualToString:NSAccessibilityPopupValueAttribute])
3414         return m_object->popupValue();
3415
3416     if ([attributeName isEqualToString:@"AXKeyShortcutsValue"])
3417         return m_object->keyShortcutsValue();
3418     
3419     if ([attributeName isEqualToString:@"AXARIAPressedIsPresent"])
3420         return [NSNumber numberWithBool:m_object->pressedIsPresent()];
3421     
3422     if ([attributeName isEqualToString:@"AXIsMultiline"])
3423         return [NSNumber numberWithBool:m_object->ariaIsMultiline()];
3424     
3425     if ([attributeName isEqualToString:@"AXReadOnlyValue"])
3426         return m_object->readOnlyValue();
3427
3428     if ([attributeName isEqualToString:@"AXIsActiveDescendantOfFocusedContainer"])
3429         return [NSNumber numberWithBool:m_object->isActiveDescendantOfFocusedContainer()];
3430
3431     if ([attributeName isEqualToString:@"AXDetailsElements"]) {
3432         AccessibilityObject::AccessibilityChildrenVector details;
3433         m_object->ariaDetailsElements(details);
3434         return convertToNSArray(details);
3435     }
3436
3437     if ([attributeName isEqualToString:NSAccessibilityRelativeFrameAttribute])
3438         return [NSValue valueWithRect:NSRectFromCGRect(_axBackingObject->relativeFrame())];
3439
3440     if ([attributeName isEqualToString:@"AXErrorMessageElements"]) {
3441         AccessibilityObject::AccessibilityChildrenVector errorMessages;
3442         m_object->ariaErrorMessageElements(errorMessages);
3443         return convertToNSArray(errorMessages);
3444     }
3445
3446     // Multi-selectable
3447     if ([attributeName isEqualToString:NSAccessibilityIsMultiSelectableAttribute])
3448         return [NSNumber numberWithBool:m_object->isMultiSelectable()];
3449     
3450     // Document attributes
3451     if ([attributeName isEqualToString:NSAccessibilityDocumentURIAttribute]) {
3452         if (Document* document = m_object->document())
3453             return document->documentURI();
3454         return nil;
3455     }
3456     
3457     if ([attributeName isEqualToString:NSAccessibilityDocumentEncodingAttribute]) {
3458         if (Document* document = m_object->document())
3459             return document->encoding();
3460         return nil;
3461     }
3462     
3463     // Aria controls element
3464     if ([attributeName isEqualToString:NSAccessibilityAriaControlsAttribute]) {
3465         AccessibilityObject::AccessibilityChildrenVector ariaControls;
3466         m_object->ariaControlsElements(ariaControls);
3467         return convertToNSArray(ariaControls);
3468     }
3469
3470     if ([attributeName isEqualToString:NSAccessibilityFocusableAncestorAttribute]) {
3471         AccessibilityObject* object = m_object->focusableAncestor();
3472         return object ? object->wrapper() : nil;
3473     }
3474
3475     if ([attributeName isEqualToString:NSAccessibilityEditableAncestorAttribute]) {
3476         AccessibilityObject* object = m_object->editableAncestor();
3477         return object ? object->wrapper() : nil;
3478     }
3479
3480     if ([attributeName isEqualToString:NSAccessibilityHighestEditableAncestorAttribute]) {
3481         AccessibilityObject* object = m_object->highestEditableAncestor();
3482         return object ? object->wrapper() : nil;
3483     }
3484
3485     return nil;
3486 }
3487
3488 - (NSString *)accessibilityPlatformMathSubscriptKey
3489 {
3490     return NSAccessibilityMathSubscriptAttribute;
3491 }
3492
3493 - (NSString *)accessibilityPlatformMathSuperscriptKey
3494 {
3495     return NSAccessibilityMathSuperscriptAttribute;
3496 }
3497
3498 - (id)accessibilityFocusedUIElement
3499 {
3500     if (![self updateObjectBackingStore])
3501         return nil;
3502     
3503     auto focusedObject = _axBackingObject->focusedUIElement();
3504     if (!focusedObject)
3505         return nil;
3506     
3507     return focusedObject->wrapper();
3508 }
3509
3510 - (id)accessibilityHitTest:(NSPoint)point
3511 {
3512     if (![self updateObjectBackingStore])
3513         return nil;
3514     
3515     _axBackingObject->updateChildrenIfNecessary();
3516     AccessibilityObjectInterface* axObject = _axBackingObject->accessibilityHitTest(IntPoint(point));
3517     if (axObject) {
3518         if (axObject->isAttachment() && [axObject->wrapper() attachmentView])
3519             return [axObject->wrapper() attachmentView];
3520         return NSAccessibilityUnignoredAncestor(axObject->wrapper());
3521     }
3522     return NSAccessibilityUnignoredAncestor(self);
3523 }
3524
3525 ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
3526 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName
3527 ALLOW_DEPRECATED_IMPLEMENTATIONS_END
3528 {
3529     if (![self updateObjectBackingStore])
3530         return NO;
3531     
3532     if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"])
3533         return YES;
3534     
3535     if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute])
3536         return m_object->canSetFocusAttribute();
3537     
3538     if ([attributeName isEqualToString: NSAccessibilityValueAttribute])
3539         return m_object->canSetValueAttribute();