Implementation for AXIsolatedObject::nextSibling and previousSibling.
[WebKit-https.git] / Source / WebCore / accessibility / AccessibilityRenderObject.cpp
1 /*
2 * Copyright (C) 2008-2020 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 #include "config.h"
30 #include "AccessibilityRenderObject.h"
31
32 #include "AXLogger.h"
33 #include "AXObjectCache.h"
34 #include "AccessibilityImageMapLink.h"
35 #include "AccessibilityLabel.h"
36 #include "AccessibilityListBox.h"
37 #include "AccessibilitySVGRoot.h"
38 #include "AccessibilitySpinButton.h"
39 #include "AccessibilityTable.h"
40 #include "CachedImage.h"
41 #include "Editing.h"
42 #include "Editor.h"
43 #include "ElementIterator.h"
44 #include "EventHandler.h"
45 #include "FloatRect.h"
46 #include "Frame.h"
47 #include "FrameLoader.h"
48 #include "FrameSelection.h"
49 #include "GeometryUtilities.h"
50 #include "HTMLAreaElement.h"
51 #include "HTMLAudioElement.h"
52 #include "HTMLDetailsElement.h"
53 #include "HTMLFormElement.h"
54 #include "HTMLFrameElementBase.h"
55 #include "HTMLImageElement.h"
56 #include "HTMLInputElement.h"
57 #include "HTMLLabelElement.h"
58 #include "HTMLMapElement.h"
59 #include "HTMLMeterElement.h"
60 #include "HTMLNames.h"
61 #include "HTMLOptionElement.h"
62 #include "HTMLOptionsCollection.h"
63 #include "HTMLParserIdioms.h"
64 #include "HTMLSelectElement.h"
65 #include "HTMLSummaryElement.h"
66 #include "HTMLTableElement.h"
67 #include "HTMLTextAreaElement.h"
68 #include "HTMLVideoElement.h"
69 #include "HitTestRequest.h"
70 #include "HitTestResult.h"
71 #include "Image.h"
72 #include "LocalizedStrings.h"
73 #include "NodeList.h"
74 #include "Page.h"
75 #include "ProgressTracker.h"
76 #include "Range.h"
77 #include "RenderButton.h"
78 #include "RenderFileUploadControl.h"
79 #include "RenderHTMLCanvas.h"
80 #include "RenderImage.h"
81 #include "RenderInline.h"
82 #include "RenderIterator.h"
83 #include "RenderLayer.h"
84 #include "RenderLineBreak.h"
85 #include "RenderListBox.h"
86 #include "RenderListItem.h"
87 #include "RenderListMarker.h"
88 #include "RenderMathMLBlock.h"
89 #include "RenderMenuList.h"
90 #include "RenderSVGRoot.h"
91 #include "RenderSVGShape.h"
92 #include "RenderTableCell.h"
93 #include "RenderText.h"
94 #include "RenderTextControl.h"
95 #include "RenderTextControlSingleLine.h"
96 #include "RenderTextFragment.h"
97 #include "RenderTheme.h"
98 #include "RenderView.h"
99 #include "RenderWidget.h"
100 #include "RenderedPosition.h"
101 #include "SVGDocument.h"
102 #include "SVGImage.h"
103 #include "SVGSVGElement.h"
104 #include "Text.h"
105 #include "TextControlInnerElements.h"
106 #include "TextIterator.h"
107 #include "VisibleUnits.h"
108 #include <wtf/NeverDestroyed.h>
109 #include <wtf/StdLibExtras.h>
110 #include <wtf/unicode/CharacterNames.h>
111
112 namespace WebCore {
113
114 using namespace HTMLNames;
115
116 AccessibilityRenderObject::AccessibilityRenderObject(RenderObject* renderer)
117     : AccessibilityNodeObject(renderer->node())
118     , m_renderer(makeWeakPtr(renderer))
119 {
120 #ifndef NDEBUG
121     m_renderer->setHasAXObject(true);
122 #endif
123 }
124
125 AccessibilityRenderObject::~AccessibilityRenderObject()
126 {
127     ASSERT(isDetached());
128 }
129
130 void AccessibilityRenderObject::init()
131 {
132     AccessibilityNodeObject::init();
133 }
134
135 Ref<AccessibilityRenderObject> AccessibilityRenderObject::create(RenderObject* renderer)
136 {
137     return adoptRef(*new AccessibilityRenderObject(renderer));
138 }
139
140 void AccessibilityRenderObject::detachRemoteParts(AccessibilityDetachmentType detachmentType)
141 {
142     AccessibilityNodeObject::detachRemoteParts(detachmentType);
143     
144     detachRemoteSVGRoot();
145     
146 #ifndef NDEBUG
147     if (m_renderer)
148         m_renderer->setHasAXObject(false);
149 #endif
150     m_renderer = nullptr;
151 }
152
153 RenderBoxModelObject* AccessibilityRenderObject::renderBoxModelObject() const
154 {
155     if (!is<RenderBoxModelObject>(renderer()))
156         return nullptr;
157     return downcast<RenderBoxModelObject>(renderer());
158 }
159
160 void AccessibilityRenderObject::setRenderer(RenderObject* renderer)
161 {
162     m_renderer = makeWeakPtr(renderer);
163     setNode(renderer->node());
164 }
165
166 static inline bool isInlineWithContinuation(RenderObject& object)
167 {
168     return is<RenderInline>(object) && downcast<RenderInline>(object).continuation();
169 }
170
171 static inline RenderObject* firstChildInContinuation(RenderInline& renderer)
172 {
173     auto* continuation = renderer.continuation();
174
175     while (continuation) {
176         if (is<RenderBlock>(*continuation))
177             return continuation;
178         if (RenderObject* child = continuation->firstChild())
179             return child;
180         continuation = downcast<RenderInline>(*continuation).continuation();
181     }
182
183     return nullptr;
184 }
185
186 static inline RenderObject* firstChildConsideringContinuation(RenderObject& renderer)
187 {
188     RenderObject* firstChild = renderer.firstChildSlow();
189
190     // We don't want to include the end of a continuation as the firstChild of the
191     // anonymous parent, because everything has already been linked up via continuation.
192     // CSS first-letter selector is an example of this case.
193     if (renderer.isAnonymous() && is<RenderInline>(firstChild) && downcast<RenderInline>(*firstChild).isContinuation())
194         firstChild = nullptr;
195     
196     if (!firstChild && isInlineWithContinuation(renderer))
197         firstChild = firstChildInContinuation(downcast<RenderInline>(renderer));
198
199     return firstChild;
200 }
201
202
203 static inline RenderObject* lastChildConsideringContinuation(RenderObject& renderer)
204 {
205     if (!is<RenderInline>(renderer) && !is<RenderBlock>(renderer))
206         return &renderer;
207
208     RenderObject* lastChild = downcast<RenderBoxModelObject>(renderer).lastChild();
209     for (auto* current = &downcast<RenderBoxModelObject>(renderer); current; ) {
210         if (RenderObject* newLastChild = current->lastChild())
211             lastChild = newLastChild;
212
213         current = current->inlineContinuation();
214     }
215
216     return lastChild;
217 }
218
219 AccessibilityObject* AccessibilityRenderObject::firstChild() const
220 {
221     if (!m_renderer)
222         return nullptr;
223     
224     RenderObject* firstChild = firstChildConsideringContinuation(*m_renderer);
225
226     // If an object can't have children, then it is using this method to help
227     // calculate some internal property (like its description).
228     // In this case, it should check the Node level for children in case they're
229     // not rendered (like a <meter> element).
230     if (!firstChild && !canHaveChildren())
231         return AccessibilityNodeObject::firstChild();
232
233     auto objectCache = axObjectCache();
234     return objectCache ? objectCache->getOrCreate(firstChild) : nullptr;
235 }
236
237 AccessibilityObject* AccessibilityRenderObject::lastChild() const
238 {
239     if (!m_renderer)
240         return nullptr;
241
242     RenderObject* lastChild = lastChildConsideringContinuation(*m_renderer);
243
244     if (!lastChild && !canHaveChildren())
245         return AccessibilityNodeObject::lastChild();
246
247     auto objectCache = axObjectCache();
248     return objectCache ? objectCache->getOrCreate(lastChild) : nullptr;
249 }
250
251 static inline RenderInline* startOfContinuations(RenderObject& renderer)
252 {
253     if (!is<RenderElement>(renderer))
254         return nullptr;
255     auto& renderElement = downcast<RenderElement>(renderer);
256     if (is<RenderInline>(renderElement) && renderElement.isContinuation() && is<RenderInline>(renderElement.element()->renderer()))
257         return downcast<RenderInline>(renderer.node()->renderer());
258
259     // Blocks with a previous continuation always have a next continuation
260     if (is<RenderBlock>(renderElement) && downcast<RenderBlock>(renderElement).inlineContinuation())
261         return downcast<RenderInline>(downcast<RenderBlock>(renderElement).inlineContinuation()->element()->renderer());
262
263     return nullptr;
264 }
265
266 static inline RenderObject* endOfContinuations(RenderObject& renderer)
267 {
268     if (!is<RenderInline>(renderer) && !is<RenderBlock>(renderer))
269         return &renderer;
270
271     auto* previous = &downcast<RenderBoxModelObject>(renderer);
272     for (auto* current = previous; current; ) {
273         previous = current;
274         current = current->inlineContinuation();
275     }
276
277     return previous;
278 }
279
280
281 static inline RenderObject* childBeforeConsideringContinuations(RenderInline* renderer, RenderObject* child)
282 {
283     RenderObject* previous = nullptr;
284     for (RenderBoxModelObject* currentContainer = renderer; currentContainer; ) {
285         if (is<RenderInline>(*currentContainer)) {
286             auto* current = currentContainer->firstChild();
287             while (current) {
288                 if (current == child)
289                     return previous;
290                 previous = current;
291                 current = current->nextSibling();
292             }
293
294             currentContainer = currentContainer->continuation();
295         } else if (is<RenderBlock>(*currentContainer)) {
296             if (currentContainer == child)
297                 return previous;
298
299             previous = currentContainer;
300             currentContainer = currentContainer->inlineContinuation();
301         }
302     }
303
304     ASSERT_NOT_REACHED();
305     return nullptr;
306 }
307
308 static inline bool firstChildIsInlineContinuation(RenderElement& renderer)
309 {
310     RenderObject* child = renderer.firstChild();
311     return is<RenderInline>(child) && downcast<RenderInline>(*child).isContinuation();
312 }
313
314 AccessibilityObject* AccessibilityRenderObject::previousSibling() const
315 {
316     if (!m_renderer)
317         return nullptr;
318
319     RenderObject* previousSibling = nullptr;
320
321     // Case 1: The node is a block and is an inline's continuation. In that case, the inline's
322     // last child is our previous sibling (or further back in the continuation chain)
323     RenderInline* startOfConts;
324     if (is<RenderBox>(*m_renderer) && (startOfConts = startOfContinuations(*m_renderer)))
325         previousSibling = childBeforeConsideringContinuations(startOfConts, renderer());
326
327     // Case 2: Anonymous block parent of the end of a continuation - skip all the way to before
328     // the parent of the start, since everything in between will be linked up via the continuation.
329     else if (m_renderer->isAnonymousBlock() && firstChildIsInlineContinuation(downcast<RenderBlock>(*m_renderer))) {
330         RenderBlock& renderBlock = downcast<RenderBlock>(*m_renderer);
331         auto* firstParent = startOfContinuations(*renderBlock.firstChild())->parent();
332         ASSERT(firstParent);
333         while (firstChildIsInlineContinuation(*firstParent))
334             firstParent = startOfContinuations(*firstParent->firstChild())->parent();
335         previousSibling = firstParent->previousSibling();
336     }
337
338     // Case 3: The node has an actual previous sibling
339     else if (RenderObject* ps = m_renderer->previousSibling())
340         previousSibling = ps;
341
342     // Case 4: This node has no previous siblings, but its parent is an inline,
343     // and is another node's inline continutation. Follow the continuation chain.
344     else if (is<RenderInline>(m_renderer->parent()) && (startOfConts = startOfContinuations(*m_renderer->parent())))
345         previousSibling = childBeforeConsideringContinuations(startOfConts, m_renderer->parent()->firstChild());
346
347     if (!previousSibling)
348         return nullptr;
349
350     if (auto* objectCache = axObjectCache())
351         return objectCache->getOrCreate(previousSibling);
352
353     return nullptr;
354 }
355
356 static inline bool lastChildHasContinuation(RenderElement& renderer)
357 {
358     RenderObject* child = renderer.lastChild();
359     return child && isInlineWithContinuation(*child);
360 }
361
362 AccessibilityObject* AccessibilityRenderObject::nextSibling() const
363 {
364     if (!m_renderer || is<RenderView>(*m_renderer))
365         return nullptr;
366
367     RenderObject* nextSibling = nullptr;
368
369     // Case 1: node is a block and has an inline continuation. Next sibling is the inline continuation's
370     // first child.
371     RenderInline* inlineContinuation;
372     if (is<RenderBlock>(*m_renderer) && (inlineContinuation = downcast<RenderBlock>(*m_renderer).inlineContinuation()))
373         nextSibling = firstChildConsideringContinuation(*inlineContinuation);
374
375     // Case 2: Anonymous block parent of the start of a continuation - skip all the way to
376     // after the parent of the end, since everything in between will be linked up via the continuation.
377     else if (m_renderer->isAnonymousBlock() && lastChildHasContinuation(downcast<RenderBlock>(*m_renderer))) {
378         RenderElement* lastParent = endOfContinuations(*downcast<RenderBlock>(*m_renderer).lastChild())->parent();
379         ASSERT(lastParent);
380         while (lastChildHasContinuation(*lastParent))
381             lastParent = endOfContinuations(*lastParent->lastChild())->parent();
382         nextSibling = lastParent->nextSibling();
383     }
384
385     // Case 3: node has an actual next sibling
386     else if (RenderObject* ns = m_renderer->nextSibling())
387         nextSibling = ns;
388
389     // Case 4: node is an inline with a continuation. Next sibling is the next sibling of the end 
390     // of the continuation chain.
391     else if (isInlineWithContinuation(*m_renderer))
392         nextSibling = endOfContinuations(*m_renderer)->nextSibling();
393
394     // Case 5: node has no next sibling, and its parent is an inline with a continuation.
395     // Case 5.1: After case 4, (the element was inline w/ continuation but had no sibling), then check it's parent.
396     if (!nextSibling && m_renderer->parent() && isInlineWithContinuation(*m_renderer->parent())) {
397         auto& continuation = *downcast<RenderInline>(*m_renderer->parent()).continuation();
398         
399         // Case 5a: continuation is a block - in this case the block itself is the next sibling.
400         if (is<RenderBlock>(continuation))
401             nextSibling = &continuation;
402         // Case 5b: continuation is an inline - in this case the inline's first child is the next sibling
403         else
404             nextSibling = firstChildConsideringContinuation(continuation);
405         
406         // After case 4, there are chances that nextSibling has the same node as the current renderer,
407         // which might lead to adding the same child repeatedly.
408         if (nextSibling && nextSibling->node() == m_renderer->node()) {
409             if (AccessibilityObject* nextObj = axObjectCache()->getOrCreate(nextSibling))
410                 return nextObj->nextSibling();
411         }
412     }
413
414     if (!nextSibling)
415         return nullptr;
416
417     auto* objectCache = axObjectCache();
418     if (!objectCache)
419         return nullptr;
420
421     // Make sure next sibling has the same parent.
422     auto* nextObject = objectCache->getOrCreate(nextSibling);
423     if (nextObject && nextObject->parentObject() != this->parentObject())
424         return nullptr;
425
426     return nextObject;
427 }
428
429 static RenderBoxModelObject* nextContinuation(RenderObject& renderer)
430 {
431     if (is<RenderInline>(renderer) && !renderer.isReplaced())
432         return downcast<RenderInline>(renderer).continuation();
433     if (is<RenderBlock>(renderer))
434         return downcast<RenderBlock>(renderer).inlineContinuation();
435     return nullptr;
436 }
437     
438 RenderObject* AccessibilityRenderObject::renderParentObject() const
439 {
440     if (!m_renderer)
441         return nullptr;
442
443     RenderElement* parent = m_renderer->parent();
444
445     // Case 1: node is a block and is an inline's continuation. Parent
446     // is the start of the continuation chain.
447     RenderInline* startOfConts = nullptr;
448     RenderObject* firstChild = nullptr;
449     if (is<RenderBlock>(*m_renderer) && (startOfConts = startOfContinuations(*m_renderer)))
450         parent = startOfConts;
451
452     // Case 2: node's parent is an inline which is some node's continuation; parent is 
453     // the earliest node in the continuation chain.
454     else if (is<RenderInline>(parent) && (startOfConts = startOfContinuations(*parent)))
455         parent = startOfConts;
456     
457     // Case 3: The first sibling is the beginning of a continuation chain. Find the origin of that continuation.
458     else if (parent && (firstChild = parent->firstChild()) && firstChild->node()) {
459         // Get the node's renderer and follow that continuation chain until the first child is found
460         RenderObject* nodeRenderFirstChild = firstChild->node()->renderer();
461         while (nodeRenderFirstChild != firstChild) {
462             for (RenderObject* contsTest = nodeRenderFirstChild; contsTest; contsTest = nextContinuation(*contsTest)) {
463                 if (contsTest == firstChild) {
464                     parent = nodeRenderFirstChild->parent();
465                     break;
466                 }
467             }
468             RenderObject* parentFirstChild = parent->firstChild();
469             if (firstChild == parentFirstChild)
470                 break;
471             firstChild = parentFirstChild;
472             if (!firstChild->node())
473                 break;
474             nodeRenderFirstChild = firstChild->node()->renderer();
475         }
476     }
477         
478     return parent;
479 }
480     
481 AccessibilityObject* AccessibilityRenderObject::parentObjectIfExists() const
482 {
483     AXObjectCache* cache = axObjectCache();
484     if (!cache)
485         return nullptr;
486     
487     // WebArea's parent should be the scroll view containing it.
488     if (isWebArea())
489         return cache->get(&m_renderer->view().frameView());
490
491     return cache->get(renderParentObject());
492 }
493     
494 AccessibilityObject* AccessibilityRenderObject::parentObject() const
495 {
496     if (!m_renderer)
497         return nullptr;
498     
499     if (ariaRoleAttribute() == AccessibilityRole::MenuBar)
500         return axObjectCache()->getOrCreate(m_renderer->parent());
501
502     // menuButton and its corresponding menu are DOM siblings, but Accessibility needs them to be parent/child
503     if (ariaRoleAttribute() == AccessibilityRole::Menu) {
504         AccessibilityObject* parent = menuButtonForMenu();
505         if (parent)
506             return parent;
507     }
508     
509     AXObjectCache* cache = axObjectCache();
510     if (!cache)
511         return nullptr;
512     
513     RenderObject* parentObj = renderParentObject();
514     if (parentObj)
515         return cache->getOrCreate(parentObj);
516     
517     // WebArea's parent should be the scroll view containing it.
518     if (isWebArea())
519         return cache->getOrCreate(&m_renderer->view().frameView());
520     
521     return nullptr;
522 }
523     
524 bool AccessibilityRenderObject::isAttachment() const
525 {
526     RenderBoxModelObject* renderer = renderBoxModelObject();
527     if (!renderer)
528         return false;
529     // Widgets are the replaced elements that we represent to AX as attachments
530     bool isWidget = renderer->isWidget();
531
532     return isWidget && ariaRoleAttribute() == AccessibilityRole::Unknown;
533 }
534
535 bool AccessibilityRenderObject::isFileUploadButton() const
536 {
537     if (m_renderer && is<HTMLInputElement>(m_renderer->node())) {
538         HTMLInputElement& input = downcast<HTMLInputElement>(*m_renderer->node());
539         return input.isFileUpload();
540     }
541     
542     return false;
543 }
544
545 bool AccessibilityRenderObject::isOffScreen() const
546 {
547     if (!m_renderer)
548         return true;
549
550     IntRect contentRect = snappedIntRect(m_renderer->absoluteClippedOverflowRect());
551     // FIXME: unclear if we need LegacyIOSDocumentVisibleRect.
552     IntRect viewRect = m_renderer->view().frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect);
553     viewRect.intersect(contentRect);
554     return viewRect.isEmpty();
555 }
556
557 Element* AccessibilityRenderObject::anchorElement() const
558 {
559     if (!m_renderer)
560         return nullptr;
561     
562     AXObjectCache* cache = axObjectCache();
563     if (!cache)
564         return nullptr;
565     
566     RenderObject* currentRenderer;
567     
568     // Search up the render tree for a RenderObject with a DOM node.  Defer to an earlier continuation, though.
569     for (currentRenderer = renderer(); currentRenderer && !currentRenderer->node(); currentRenderer = currentRenderer->parent()) {
570         if (currentRenderer->isAnonymousBlock()) {
571             if (RenderObject* continuation = downcast<RenderBlock>(*currentRenderer).continuation())
572                 return cache->getOrCreate(continuation)->anchorElement();
573         }
574     }
575     
576     // bail if none found
577     if (!currentRenderer)
578         return nullptr;
579     
580     // search up the DOM tree for an anchor element
581     // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
582     for (Node* node = currentRenderer->node(); node; node = node->parentNode()) {
583         if (is<HTMLAnchorElement>(*node) || (node->renderer() && cache->getOrCreate(node->renderer())->isLink()))
584             return downcast<Element>(node);
585     }
586     
587     return nullptr;
588 }
589
590 String AccessibilityRenderObject::helpText() const
591 {
592     if (!m_renderer)
593         return String();
594     
595     const AtomString& ariaHelp = getAttribute(aria_helpAttr);
596     if (!ariaHelp.isEmpty())
597         return ariaHelp;
598     
599     String describedBy = ariaDescribedByAttribute();
600     if (!describedBy.isEmpty())
601         return describedBy;
602     
603     String description = accessibilityDescription();
604     for (RenderObject* ancestor = renderer(); ancestor; ancestor = ancestor->parent()) {
605         if (is<HTMLElement>(ancestor->node())) {
606             HTMLElement& element = downcast<HTMLElement>(*ancestor->node());
607             const AtomString& summary = element.getAttribute(summaryAttr);
608             if (!summary.isEmpty())
609                 return summary;
610             
611             // The title attribute should be used as help text unless it is already being used as descriptive text.
612             const AtomString& title = element.getAttribute(titleAttr);
613             if (!title.isEmpty() && description != title)
614                 return title;
615         }
616         
617         // Only take help text from an ancestor element if its a group or an unknown role. If help was 
618         // added to those kinds of elements, it is likely it was meant for a child element.
619         if (AccessibilityObject* axObj = axObjectCache()->getOrCreate(ancestor)) {
620             if (!axObj->isGroup() && axObj->roleValue() != AccessibilityRole::Unknown)
621                 break;
622         }
623     }
624     
625     return String();
626 }
627
628 String AccessibilityRenderObject::textUnderElement(AccessibilityTextUnderElementMode mode) const
629 {
630     if (!m_renderer)
631         return String();
632
633     if (is<RenderFileUploadControl>(*m_renderer))
634         return downcast<RenderFileUploadControl>(*m_renderer).buttonValue();
635     
636     // Reflect when a content author has explicitly marked a line break.
637     if (m_renderer->isBR())
638         return "\n"_s;
639
640     if (shouldGetTextFromNode(mode))
641         return AccessibilityNodeObject::textUnderElement(mode);
642
643     // We use a text iterator for text objects AND for those cases where we are
644     // explicitly asking for the full text under a given element.
645     if (is<RenderText>(*m_renderer) || mode.childrenInclusion == AccessibilityTextUnderElementMode::TextUnderElementModeIncludeAllChildren) {
646         // If possible, use a text iterator to get the text, so that whitespace
647         // is handled consistently.
648         Document* nodeDocument = nullptr;
649         Optional<SimpleRange> textRange;
650         if (Node* node = m_renderer->node()) {
651             nodeDocument = &node->document();
652             textRange = makeRangeSelectingNodeContents(*node);
653         } else {
654             // For anonymous blocks, we work around not having a direct node to create a range from
655             // defining one based in the two external positions defining the boundaries of the subtree.
656             RenderObject* firstChildRenderer = m_renderer->firstChildSlow();
657             RenderObject* lastChildRenderer = m_renderer->lastChildSlow();
658             if (firstChildRenderer && firstChildRenderer->node() && lastChildRenderer && lastChildRenderer->node()) {
659                 // We define the start and end positions for the range as the ones right before and after
660                 // the first and the last nodes in the DOM tree that is wrapped inside the anonymous block.
661                 auto& firstNodeInBlock = *firstChildRenderer->node();
662                 nodeDocument = &firstNodeInBlock.document();
663                 textRange = makeSimpleRange(positionInParentBeforeNode(&firstNodeInBlock), positionInParentAfterNode(lastChildRenderer->node()));
664             }
665         }
666
667         if (nodeDocument && textRange) {
668             if (Frame* frame = nodeDocument->frame()) {
669                 // catch stale WebCoreAXObject (see <rdar://problem/3960196>)
670                 if (frame->document() != nodeDocument)
671                     return String();
672
673                 // Renders referenced by accessibility objects could get destroyed, if TextIterator ends up triggering
674                 // style update/layout here. See also AXObjectCache::deferTextChangedIfNeeded().
675                 ASSERT_WITH_SECURITY_IMPLICATION(!nodeDocument->childNeedsStyleRecalc());
676                 ASSERT_WITH_SECURITY_IMPLICATION(!nodeDocument->view()->layoutContext().isInRenderTreeLayout());
677                 return plainText(*textRange, textIteratorBehaviorForTextRange());
678             }
679         }
680     
681         // Sometimes text fragments don't have Nodes associated with them (like when
682         // CSS content is used to insert text or when a RenderCounter is used.)
683         if (is<RenderText>(*m_renderer)) {
684             RenderText& renderTextObject = downcast<RenderText>(*m_renderer);
685             if (is<RenderTextFragment>(renderTextObject)) {
686                 RenderTextFragment& renderTextFragment = downcast<RenderTextFragment>(renderTextObject);
687                 // The alt attribute may be set on a text fragment through CSS, which should be honored.
688                 const String& altText = renderTextFragment.altText();
689                 if (!altText.isEmpty())
690                     return altText;
691                 return renderTextFragment.contentString();
692             }
693
694             return renderTextObject.text();
695         }
696     }
697     
698     return AccessibilityNodeObject::textUnderElement(mode);
699 }
700
701 bool AccessibilityRenderObject::shouldGetTextFromNode(AccessibilityTextUnderElementMode mode) const
702 {
703     if (!m_renderer)
704         return false;
705
706     // AccessibilityRenderObject::textUnderElement() gets the text of anonymous blocks by using
707     // the child nodes to define positions. CSS tables and their anonymous descendants lack
708     // children with nodes.
709     if (m_renderer->isAnonymous() && m_renderer->isTablePart())
710         return mode.childrenInclusion == AccessibilityTextUnderElementMode::TextUnderElementModeIncludeAllChildren;
711
712     // AccessibilityRenderObject::textUnderElement() calls rangeOfContents() to create the text
713     // range. rangeOfContents() does not include CSS-generated content.
714     if (m_renderer->isBeforeOrAfterContent())
715         return true;
716     if (Node* node = m_renderer->node()) {
717         Node* firstChild = node->pseudoAwareFirstChild();
718         Node* lastChild = node->pseudoAwareLastChild();
719         if ((firstChild && firstChild->isPseudoElement()) || (lastChild && lastChild->isPseudoElement()))
720             return true;
721     }
722
723     return false;
724 }
725
726 Node* AccessibilityRenderObject::node() const
727 {
728     if (!m_renderer)
729         return nullptr;
730     if (m_renderer->isRenderView())
731         return &m_renderer->document();
732     return m_renderer->node();
733 }    
734
735 String AccessibilityRenderObject::stringValue() const
736 {
737     if (!m_renderer)
738         return String();
739
740     if (isPasswordField())
741         return passwordFieldValue();
742
743     RenderBoxModelObject* cssBox = renderBoxModelObject();
744
745     if (isARIAStaticText()) {
746         String staticText = text();
747         if (!staticText.length())
748             staticText = textUnderElement();
749         return staticText;
750     }
751         
752     if (is<RenderText>(*m_renderer))
753         return textUnderElement();
754
755     if (is<RenderMenuList>(cssBox)) {
756         // RenderMenuList will go straight to the text() of its selected item.
757         // This has to be overridden in the case where the selected item has an ARIA label.
758         HTMLSelectElement& selectElement = downcast<HTMLSelectElement>(*m_renderer->node());
759         int selectedIndex = selectElement.selectedIndex();
760         const Vector<HTMLElement*>& listItems = selectElement.listItems();
761         if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems.size()) {
762             const AtomString& overriddenDescription = listItems[selectedIndex]->attributeWithoutSynchronization(aria_labelAttr);
763             if (!overriddenDescription.isNull())
764                 return overriddenDescription;
765         }
766         return downcast<RenderMenuList>(*m_renderer).text();
767     }
768     
769     if (is<RenderListMarker>(*m_renderer))
770         return downcast<RenderListMarker>(*m_renderer).text();
771     
772     if (isWebArea())
773         return String();
774     
775     if (isTextControl())
776         return text();
777     
778 #if PLATFORM(IOS_FAMILY)
779     if (isInputTypePopupButton())
780         return textUnderElement();
781 #endif
782     
783     if (is<RenderFileUploadControl>(*m_renderer))
784         return downcast<RenderFileUploadControl>(*m_renderer).fileTextValue();
785     
786     // FIXME: We might need to implement a value here for more types
787     // FIXME: It would be better not to advertise a value at all for the types for which we don't implement one;
788     // this would require subclassing or making accessibilityAttributeNames do something other than return a
789     // single static array.
790     return String();
791 }
792
793 bool AccessibilityRenderObject::canHavePlainText() const
794 {
795     return isARIAStaticText() || is<RenderText>(*m_renderer) || isTextControl();
796 }
797
798 HTMLLabelElement* AccessibilityRenderObject::labelElementContainer() const
799 {
800     if (!m_renderer)
801         return nullptr;
802
803     // the control element should not be considered part of the label
804     if (isControl())
805         return nullptr;
806     
807     // find if this has a parent that is a label
808     for (Node* parentNode = m_renderer->node(); parentNode; parentNode = parentNode->parentNode()) {
809         if (is<HTMLLabelElement>(*parentNode))
810             return downcast<HTMLLabelElement>(parentNode);
811     }
812     
813     return nullptr;
814 }
815
816 // The boundingBox for elements within the remote SVG element needs to be offset by its position
817 // within the parent page, otherwise they are in relative coordinates only.
818 void AccessibilityRenderObject::offsetBoundingBoxForRemoteSVGElement(LayoutRect& rect) const
819 {
820     for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
821         if (parent->isAccessibilitySVGRoot()) {
822             rect.moveBy(parent->parentObject()->boundingBoxRect().location());
823             break;
824         }
825     }
826 }
827     
828 LayoutRect AccessibilityRenderObject::boundingBoxRect() const
829 {
830     RenderObject* obj = renderer();
831     
832     if (!obj)
833         return LayoutRect();
834     
835     if (obj->node()) // If we are a continuation, we want to make sure to use the primary renderer.
836         obj = obj->node()->renderer();
837     
838     // absoluteFocusRingQuads will query the hierarchy below this element, which for large webpages can be very slow.
839     // For a web area, which will have the most elements of any element, absoluteQuads should be used.
840     // We should also use absoluteQuads for SVG elements, otherwise transforms won't be applied.
841     Vector<FloatQuad> quads;
842     bool isSVGRoot = false;
843
844     if (obj->isSVGRoot())
845         isSVGRoot = true;
846
847     if (is<RenderText>(*obj))
848         quads = downcast<RenderText>(*obj).absoluteQuadsClippedToEllipsis();
849     else if (isWebArea() || isSVGRoot)
850         obj->absoluteQuads(quads);
851     else
852         obj->absoluteFocusRingQuads(quads);
853     
854     LayoutRect result = boundingBoxForQuads(obj, quads);
855
856     Document* document = this->document();
857     if (document && document->isSVGDocument())
858         offsetBoundingBoxForRemoteSVGElement(result);
859     
860     // The size of the web area should be the content size, not the clipped size.
861     if (isWebArea())
862         result.setSize(obj->view().frameView().contentsSize());
863     
864     return result;
865 }
866     
867 LayoutRect AccessibilityRenderObject::checkboxOrRadioRect() const
868 {
869     if (!m_renderer)
870         return LayoutRect();
871     
872     HTMLLabelElement* label = labelForElement(downcast<Element>(m_renderer->node()));
873     if (!label || !label->renderer())
874         return boundingBoxRect();
875     
876     LayoutRect labelRect = axObjectCache()->getOrCreate(label)->elementRect();
877     labelRect.unite(boundingBoxRect());
878     return labelRect;
879 }
880
881 LayoutRect AccessibilityRenderObject::elementRect() const
882 {
883     // a checkbox or radio button should encompass its label
884     if (isCheckboxOrRadio())
885         return checkboxOrRadioRect();
886     
887     return boundingBoxRect();
888 }
889     
890 bool AccessibilityRenderObject::supportsPath() const
891 {
892     return is<RenderSVGShape>(renderer());
893 }
894
895 Path AccessibilityRenderObject::elementPath() const
896 {
897     if (is<RenderSVGShape>(renderer()) && downcast<RenderSVGShape>(*m_renderer).hasPath()) {
898         Path path = downcast<RenderSVGShape>(*m_renderer).path();
899         
900         // The SVG path is in terms of the parent's bounding box. The path needs to be offset to frame coordinates.
901         if (auto svgRoot = ancestorsOfType<RenderSVGRoot>(*m_renderer).first()) {
902             LayoutPoint parentOffset = axObjectCache()->getOrCreate(&*svgRoot)->elementRect().location();
903             path.transform(AffineTransform().translate(parentOffset.x(), parentOffset.y()));
904         }
905         
906         return path;
907     }
908     
909     return Path();
910 }
911
912 IntPoint AccessibilityRenderObject::linkClickPoint()
913 {
914     ASSERT(isLink());
915     /* A link bounding rect can contain points that are not part of the link.
916      For instance, a link that starts at the end of a line and finishes at the
917      beginning of the next line will have a bounding rect that includes the
918      entire two lines. In such a case, the middle point of the bounding rect
919      may not belong to the link element and thus may not activate the link.
920      Hence, return the middle point of the first character in the link if exists.
921      */
922     if (auto range = elementRange()) {
923         auto start = VisiblePosition { createLegacyEditingPosition(range->start) };
924         auto end = nextVisiblePosition(start);
925         if (isPointInRange(*range, makeBoundaryPoint(end)))
926             return { boundsForRange(*makeSimpleRange(start, end)).center() };
927     }
928     return AccessibilityObject::clickPoint();
929 }
930
931 IntPoint AccessibilityRenderObject::clickPoint()
932 {
933     // Headings are usually much wider than their textual content. If the mid point is used, often it can be wrong.
934     if (isHeading() && children().size() == 1)
935         return children().first()->clickPoint();
936
937     if (isLink())
938         return linkClickPoint();
939
940     // use the default position unless this is an editable web area, in which case we use the selection bounds.
941     if (!isWebArea() || !canSetValueAttribute())
942         return AccessibilityObject::clickPoint();
943     
944     return boundsForVisiblePositionRange(selection()).center();
945 }
946     
947 AccessibilityObject* AccessibilityRenderObject::internalLinkElement() const
948 {
949     auto element = anchorElement();
950
951     // Right now, we do not support ARIA links as internal link elements
952     if (!is<HTMLAnchorElement>(element))
953         return nullptr;
954     auto& anchor = downcast<HTMLAnchorElement>(*element);
955
956     auto linkURL = anchor.href();
957     auto fragmentIdentifier = linkURL.fragmentIdentifier();
958     if (fragmentIdentifier.isEmpty())
959         return nullptr;
960
961     // check if URL is the same as current URL
962     auto documentURL = m_renderer->document().url();
963     if (!equalIgnoringFragmentIdentifier(documentURL, linkURL))
964         return nullptr;
965
966     auto linkedNode = m_renderer->document().findAnchor(fragmentIdentifier.toStringWithoutCopying());
967     if (!linkedNode)
968         return nullptr;
969
970     // The element we find may not be accessible, so find the first accessible object.
971     return firstAccessibleObjectFromNode(linkedNode);
972 }
973
974 OptionSet<SpeakAs> AccessibilityRenderObject::speakAsProperty() const
975 {
976     if (!m_renderer)
977         return AccessibilityObject::speakAsProperty();
978     
979     return m_renderer->style().speakAs();
980 }
981     
982 void AccessibilityRenderObject::addRadioButtonGroupChildren(AXCoreObject* parent, AccessibilityChildrenVector& linkedUIElements) const
983 {
984     for (const auto& child : parent->children()) {
985         if (child->roleValue() == AccessibilityRole::RadioButton)
986             linkedUIElements.append(child);
987         else
988             addRadioButtonGroupChildren(child.get(), linkedUIElements);
989     }
990 }
991     
992 void AccessibilityRenderObject::addRadioButtonGroupMembers(AccessibilityChildrenVector& linkedUIElements) const
993 {
994     if (roleValue() != AccessibilityRole::RadioButton)
995         return;
996     
997     Node* node = this->node();
998     if (is<HTMLInputElement>(node)) {
999         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
1000         for (auto& radioSibling : input.radioButtonGroup()) {
1001             if (AccessibilityObject* object = axObjectCache()->getOrCreate(radioSibling.ptr()))
1002                 linkedUIElements.append(object);
1003         }
1004     } else {
1005         // If we didn't find any radio button siblings with the traditional naming, lets search for a radio group role and find its children.
1006         for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
1007             if (parent->roleValue() == AccessibilityRole::RadioGroup)
1008                 addRadioButtonGroupChildren(parent, linkedUIElements);
1009         }
1010     }
1011 }
1012     
1013 // linked ui elements could be all the related radio buttons in a group
1014 // or an internal anchor connection
1015 void AccessibilityRenderObject::linkedUIElements(AccessibilityChildrenVector& linkedUIElements) const
1016 {
1017     ariaFlowToElements(linkedUIElements);
1018
1019     if (isLink()) {
1020         AccessibilityObject* linkedAXElement = internalLinkElement();
1021         if (linkedAXElement)
1022             linkedUIElements.append(linkedAXElement);
1023     }
1024
1025     if (roleValue() == AccessibilityRole::RadioButton)
1026         addRadioButtonGroupMembers(linkedUIElements);
1027 }
1028
1029 bool AccessibilityRenderObject::hasTextAlternative() const
1030 {
1031     // ARIA: section 2A, bullet #3 says if aria-labeledby or aria-label appears, it should
1032     // override the "label" element association.
1033     return ariaAccessibilityDescription().length();
1034 }
1035
1036 bool AccessibilityRenderObject::hasPopup() const
1037 {
1038     // Return true if this has the aria-haspopup attribute, or if it has an ancestor of type link with the aria-haspopup attribute.
1039     return Accessibility::findAncestor<AccessibilityObject>(*this, true, [this] (const AccessibilityObject& object) {
1040         return (this == &object) ? !equalLettersIgnoringASCIICase(object.popupValue(), "false")
1041             : object.isLink() && !equalLettersIgnoringASCIICase(object.popupValue(), "false");
1042     });
1043 }
1044
1045 bool AccessibilityRenderObject::supportsDropping() const 
1046 {
1047     return determineDropEffects().size();
1048 }
1049
1050 bool AccessibilityRenderObject::supportsDragging() const
1051 {
1052     const AtomString& grabbed = getAttribute(aria_grabbedAttr);
1053     return equalLettersIgnoringASCIICase(grabbed, "true") || equalLettersIgnoringASCIICase(grabbed, "false") || hasAttribute(draggableAttr);
1054 }
1055
1056 bool AccessibilityRenderObject::isGrabbed()
1057 {
1058 #if ENABLE(DRAG_SUPPORT)
1059     if (mainFrame() && mainFrame()->eventHandler().draggingElement() == element())
1060         return true;
1061 #endif
1062
1063     return elementAttributeValue(aria_grabbedAttr);
1064 }
1065
1066 Vector<String> AccessibilityRenderObject::determineDropEffects() const
1067 {
1068     // Order is aria-dropeffect, dropzone, webkitdropzone
1069     const AtomString& dropEffects = getAttribute(aria_dropeffectAttr);
1070     if (!dropEffects.isEmpty()) {
1071         String dropEffectsString = dropEffects.string();
1072         dropEffectsString.replace('\n', ' ');
1073         return dropEffectsString.split(' ');
1074     }
1075     
1076     auto dropzone = getAttribute(dropzoneAttr);
1077     if (!dropzone.isEmpty())
1078         return Vector<String> { dropzone };
1079     
1080     auto webkitdropzone = getAttribute(webkitdropzoneAttr);
1081     if (!webkitdropzone.isEmpty())
1082         return Vector<String> { webkitdropzone };
1083     
1084     return { };
1085 }
1086     
1087 bool AccessibilityRenderObject::exposesTitleUIElement() const
1088 {
1089     if (!isControl() && !isFigureElement())
1090         return false;
1091
1092     // If this control is ignored (because it's invisible), 
1093     // then the label needs to be exposed so it can be visible to accessibility.
1094     if (accessibilityIsIgnored())
1095         return true;
1096     
1097     // When controls have their own descriptions, the title element should be ignored.
1098     if (hasTextAlternative())
1099         return false;
1100     
1101     // When <label> element has aria-label or aria-labelledby on it, we shouldn't expose it as the
1102     // titleUIElement, otherwise its inner text will be announced by a screenreader.
1103     if (isLabelable()) {
1104         if (HTMLLabelElement* label = labelForElement(downcast<Element>(node()))) {
1105             if (!label->attributeWithoutSynchronization(aria_labelAttr).isEmpty())
1106                 return false;
1107             if (AccessibilityObject* labelObject = axObjectCache()->getOrCreate(label)) {
1108                 if (!labelObject->ariaLabeledByAttribute().isEmpty())
1109                     return false;
1110                 // To simplify instances where the labeling element includes widget descendants
1111                 // which it does not label.
1112                 if (is<AccessibilityLabel>(*labelObject)
1113                     && downcast<AccessibilityLabel>(*labelObject).containsUnrelatedControls())
1114                     return false;
1115             }
1116         }
1117     }
1118     
1119     return true;
1120 }
1121
1122 #if ENABLE(APPLE_PAY)
1123 String AccessibilityRenderObject::applePayButtonDescription() const
1124 {
1125     switch (applePayButtonType()) {
1126     case ApplePayButtonType::Plain:
1127         return AXApplePayPlainLabel();
1128     case ApplePayButtonType::Buy:
1129         return AXApplePayBuyLabel();
1130     case ApplePayButtonType::SetUp:
1131         return AXApplePaySetupLabel();
1132     case ApplePayButtonType::Donate:
1133         return AXApplePayDonateLabel();
1134     case ApplePayButtonType::CheckOut:
1135         return AXApplePayCheckOutLabel();
1136     case ApplePayButtonType::Book:
1137         return AXApplePayBookLabel();
1138     case ApplePayButtonType::Subscribe:
1139         return AXApplePaySubscribeLabel();
1140 #if ENABLE(APPLE_PAY_NEW_BUTTON_TYPES)
1141     case ApplePayButtonType::Reload:
1142         return AXApplePayReloadLabel();
1143     case ApplePayButtonType::AddMoney:
1144         return AXApplePayAddMoneyLabel();
1145     case ApplePayButtonType::TopUp:
1146         return AXApplePayTopUpLabel();
1147     case ApplePayButtonType::Order:
1148         return AXApplePayOrderLabel();
1149     case ApplePayButtonType::Rent:
1150         return AXApplePayRentLabel();
1151     case ApplePayButtonType::Support:
1152         return AXApplePaySupportLabel();
1153     case ApplePayButtonType::Contribute:
1154         return AXApplePayContributeLabel();
1155     case ApplePayButtonType::Tip:
1156         return AXApplePayTipLabel();
1157 #endif
1158     }
1159 }
1160 #endif
1161
1162 void AccessibilityRenderObject::titleElementText(Vector<AccessibilityText>& textOrder) const
1163 {
1164 #if ENABLE(APPLE_PAY)
1165     if (isApplePayButton()) {
1166         textOrder.append(AccessibilityText(applePayButtonDescription(), AccessibilityTextSource::Alternative));
1167         return;
1168     }
1169 #endif
1170
1171     AccessibilityNodeObject::titleElementText(textOrder);
1172 }
1173     
1174 AccessibilityObject* AccessibilityRenderObject::titleUIElement() const
1175 {
1176     if (!m_renderer)
1177         return nullptr;
1178     
1179     // if isFieldset is true, the renderer is guaranteed to be a RenderFieldset
1180     if (isFieldset())
1181         return axObjectCache()->getOrCreate(downcast<RenderBlock>(*m_renderer).findFieldsetLegend(RenderBlock::FieldsetIncludeFloatingOrOutOfFlow));
1182     
1183     if (isFigureElement())
1184         return captionForFigure();
1185     
1186     Node* node = m_renderer->node();
1187     if (!is<Element>(node))
1188         return nullptr;
1189     HTMLLabelElement* label = labelForElement(downcast<Element>(node));
1190     if (label && label->renderer())
1191         return axObjectCache()->getOrCreate(label);
1192
1193     return nullptr;
1194 }
1195     
1196 bool AccessibilityRenderObject::isAllowedChildOfTree() const
1197 {
1198     // Determine if this is in a tree. If so, we apply special behavior to make it work like an AXOutline.
1199     AccessibilityObject* axObj = parentObject();
1200     bool isInTree = false;
1201     bool isTreeItemDescendant = false;
1202     while (axObj) {
1203         if (axObj->roleValue() == AccessibilityRole::TreeItem)
1204             isTreeItemDescendant = true;
1205         if (axObj->isTree()) {
1206             isInTree = true;
1207             break;
1208         }
1209         axObj = axObj->parentObject();
1210     }
1211     
1212     // If the object is in a tree, only tree items should be exposed (and the children of tree items).
1213     if (isInTree) {
1214         AccessibilityRole role = roleValue();
1215         if (role != AccessibilityRole::TreeItem && role != AccessibilityRole::StaticText && !isTreeItemDescendant)
1216             return false;
1217     }
1218     return true;
1219 }
1220
1221 static AccessibilityObjectInclusion objectInclusionFromAltText(const String& altText)
1222 {
1223     // Don't ignore an image that has an alt tag.
1224     if (!altText.isAllSpecialCharacters<isHTMLSpace>())
1225         return AccessibilityObjectInclusion::IncludeObject;
1226
1227     // The informal standard is to ignore images with zero-length alt strings:
1228     // https://www.w3.org/WAI/tutorials/images/decorative/.
1229     if (!altText.isNull())
1230         return AccessibilityObjectInclusion::IgnoreObject;
1231
1232     return AccessibilityObjectInclusion::DefaultBehavior;
1233 }
1234
1235 AccessibilityObjectInclusion AccessibilityRenderObject::defaultObjectInclusion() const
1236 {
1237     // The following cases can apply to any element that's a subclass of AccessibilityRenderObject.
1238     
1239     if (!m_renderer)
1240         return AccessibilityObjectInclusion::IgnoreObject;
1241
1242     if (m_renderer->style().visibility() != Visibility::Visible) {
1243         // aria-hidden is meant to override visibility as the determinant in AX hierarchy inclusion.
1244         if (equalLettersIgnoringASCIICase(getAttribute(aria_hiddenAttr), "false"))
1245             return AccessibilityObjectInclusion::DefaultBehavior;
1246
1247         return AccessibilityObjectInclusion::IgnoreObject;
1248     }
1249
1250     return AccessibilityObject::defaultObjectInclusion();
1251 }
1252     
1253 static bool webAreaIsPresentational(RenderObject* renderer)
1254 {
1255     if (!renderer || !is<RenderView>(*renderer))
1256         return false;
1257     
1258     if (auto ownerElement = renderer->document().ownerElement())
1259         return nodeHasPresentationRole(ownerElement);
1260     
1261     return false;
1262 }
1263     
1264 bool AccessibilityRenderObject::computeAccessibilityIsIgnored() const
1265 {
1266     AXTRACE("AccessibilityRenderObject::computeAccessibilityIsIgnored");
1267 #ifndef NDEBUG
1268     ASSERT(m_initialized);
1269 #endif
1270
1271     if (!m_renderer)
1272         return true;
1273     
1274     // Check first if any of the common reasons cause this element to be ignored.
1275     // Then process other use cases that need to be applied to all the various roles
1276     // that AccessibilityRenderObjects take on.
1277     AccessibilityObjectInclusion decision = defaultObjectInclusion();
1278     if (decision == AccessibilityObjectInclusion::IncludeObject)
1279         return false;
1280     if (decision == AccessibilityObjectInclusion::IgnoreObject)
1281         return true;
1282     
1283     // If this element is within a parent that cannot have children, it should not be exposed.
1284     if (isDescendantOfBarrenParent())
1285         return true;    
1286     
1287     if (roleValue() == AccessibilityRole::Ignored)
1288         return true;
1289     
1290     if (roleValue() == AccessibilityRole::Presentational || inheritsPresentationalRole())
1291         return true;
1292     
1293     // WebAreas should be ignored if their iframe container is marked as presentational.
1294     if (webAreaIsPresentational(renderer()))
1295         return true;
1296
1297     // An ARIA tree can only have tree items and static text as children.
1298     if (!isAllowedChildOfTree())
1299         return true;
1300
1301     // Allow the platform to decide if the attachment is ignored or not.
1302     if (isAttachment())
1303         return accessibilityIgnoreAttachment();
1304     
1305     // ignore popup menu items because AppKit does
1306     if (m_renderer && ancestorsOfType<RenderMenuList>(*m_renderer).first())
1307         return true;
1308
1309     // https://webkit.org/b/161276 Getting the controlObject might cause the m_renderer to be nullptr.
1310     if (!m_renderer)
1311         return true;
1312
1313     if (m_renderer->isBR())
1314         return true;
1315
1316     if (is<RenderText>(*m_renderer)) {
1317         // static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level
1318         AXCoreObject* parent = parentObjectUnignored();
1319         if (parent && (parent->isMenuItem() || parent->ariaRoleAttribute() == AccessibilityRole::MenuButton))
1320             return true;
1321         auto& renderText = downcast<RenderText>(*m_renderer);
1322         if (!renderText.hasRenderedText())
1323             return true;
1324
1325         if (renderText.parent()->isFirstLetter())
1326             return true;
1327
1328         // static text beneath TextControls is reported along with the text control text so it's ignored.
1329         for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) { 
1330             if (parent->roleValue() == AccessibilityRole::TextField)
1331                 return true;
1332         }
1333         
1334         // Walking up the parent chain might reset the m_renderer.
1335         if (!m_renderer)
1336             return true;
1337         
1338         // The alt attribute may be set on a text fragment through CSS, which should be honored.
1339         if (is<RenderTextFragment>(renderText)) {
1340             AccessibilityObjectInclusion altTextInclusion = objectInclusionFromAltText(downcast<RenderTextFragment>(renderText).altText());
1341             if (altTextInclusion == AccessibilityObjectInclusion::IgnoreObject)
1342                 return true;
1343             if (altTextInclusion == AccessibilityObjectInclusion::IncludeObject)
1344                 return false;
1345         }
1346
1347         // text elements that are just empty whitespace should not be returned
1348         return renderText.text().isAllSpecialCharacters<isHTMLSpace>();
1349     }
1350     
1351     if (isHeading())
1352         return false;
1353     
1354     if (isLink())
1355         return false;
1356     
1357     if (isLandmark())
1358         return false;
1359
1360     // all controls are accessible
1361     if (isControl())
1362         return false;
1363     
1364     if (isFigureElement())
1365         return false;
1366
1367     switch (roleValue()) {
1368     case AccessibilityRole::Audio:
1369     case AccessibilityRole::DescriptionListTerm:
1370     case AccessibilityRole::DescriptionListDetail:
1371     case AccessibilityRole::Details:
1372     case AccessibilityRole::DocumentArticle:
1373     case AccessibilityRole::Footer:
1374     case AccessibilityRole::LandmarkRegion:
1375     case AccessibilityRole::ListItem:
1376     case AccessibilityRole::Time:
1377     case AccessibilityRole::Video:
1378         return false;
1379     default:
1380         break;
1381     }
1382
1383     if (isImage()) {
1384         // If the image can take focus, it should not be ignored, lest the user not be able to interact with something important.
1385         if (canSetFocusAttribute())
1386             return false;
1387
1388         // First check the RenderImage's altText (which can be set through a style sheet, or come from the Element).
1389         // However, if this is not a native image, fallback to the attribute on the Element.
1390         AccessibilityObjectInclusion altTextInclusion = AccessibilityObjectInclusion::DefaultBehavior;
1391         bool isRenderImage = is<RenderImage>(renderer());
1392         if (isRenderImage)
1393             altTextInclusion = objectInclusionFromAltText(downcast<RenderImage>(*m_renderer).altText());
1394         else
1395             altTextInclusion = objectInclusionFromAltText(getAttribute(altAttr).string());
1396
1397         if (altTextInclusion == AccessibilityObjectInclusion::IgnoreObject)
1398             return true;
1399         if (altTextInclusion == AccessibilityObjectInclusion::IncludeObject)
1400             return false;
1401
1402         // If an image has the title or label attributes, accessibility should be lenient and allow it to appear in the hierarchy (according to WAI-ARIA).
1403         if (!getAttribute(titleAttr).isEmpty() || !getAttribute(aria_labelAttr).isEmpty())
1404             return false;
1405
1406         if (isRenderImage) {
1407             // check for one-dimensional image
1408             RenderImage& image = downcast<RenderImage>(*m_renderer);
1409             if (image.height() <= 1 || image.width() <= 1)
1410                 return true;
1411
1412             // check whether rendered image was stretched from one-dimensional file image
1413             if (image.cachedImage()) {
1414                 LayoutSize imageSize = image.cachedImage()->imageSizeForRenderer(&image, image.view().zoomFactor());
1415                 return imageSize.height() <= 1 || imageSize.width() <= 1;
1416             }
1417         }
1418         return false;
1419     }
1420
1421     if (ariaRoleAttribute() != AccessibilityRole::Unknown)
1422         return false;
1423
1424     if (roleValue() == AccessibilityRole::HorizontalRule)
1425         return false;
1426     
1427     // don't ignore labels, because they serve as TitleUIElements
1428     Node* node = m_renderer->node();
1429     if (is<HTMLLabelElement>(node))
1430         return false;
1431     
1432     // Anything that is content editable should not be ignored.
1433     // However, one cannot just call node->hasEditableStyle() since that will ask if its parents
1434     // are also editable. Only the top level content editable region should be exposed.
1435     if (hasContentEditableAttributeSet())
1436         return false;
1437
1438     // if this element has aria attributes on it, it should not be ignored.
1439     if (supportsARIAAttributes())
1440         return false;
1441
1442 #if ENABLE(MATHML)
1443     // First check if this is a special case within the math tree that needs to be ignored.
1444     if (isIgnoredElementWithinMathTree())
1445         return true;
1446     // Otherwise all other math elements are in the tree.
1447     if (isMathElement())
1448         return false;
1449 #endif
1450     
1451     if (is<RenderBlockFlow>(*m_renderer) && m_renderer->childrenInline() && !canSetFocusAttribute())
1452         return !downcast<RenderBlockFlow>(*m_renderer).hasLines() && !mouseButtonListener();
1453     
1454     if (isCanvas()) {
1455         if (canvasHasFallbackContent())
1456             return false;
1457
1458         if (is<RenderBox>(*m_renderer)) {
1459             auto& canvasBox = downcast<RenderBox>(*m_renderer);
1460             if (canvasBox.height() <= 1 || canvasBox.width() <= 1)
1461                 return true;
1462         }
1463         // Otherwise fall through; use presence of help text, title, or description to decide.
1464     }
1465
1466     if (m_renderer->isListMarker()) {
1467         AXCoreObject* parent = parentObjectUnignored();
1468         return parent && !parent->isListItem();
1469     }
1470
1471     if (isWebArea())
1472         return false;
1473     
1474     // The render tree of meter includes a RenderBlock (meter) and a RenderMeter (div).
1475     // We expose the latter and thus should ignore the former. However, if the author
1476     // includes a title attribute on the element, hasAttributesRequiredForInclusion()
1477     // will return true, potentially resulting in a redundant accessible object.
1478     if (is<HTMLMeterElement>(node))
1479         return true;
1480
1481     // Using the presence of an accessible name to decide an element's visibility is not
1482     // as definitive as previous checks, so this should remain as one of the last.
1483     if (hasAttributesRequiredForInclusion())
1484         return false;
1485
1486     // Don't ignore generic focusable elements like <div tabindex=0>
1487     // unless they're completely empty, with no children.
1488     if (isGenericFocusableElement() && node->firstChild())
1489         return false;
1490
1491     // <span> tags are inline tags and not meant to convey information if they have no other aria
1492     // information on them. If we don't ignore them, they may emit signals expected to come from
1493     // their parent. In addition, because included spans are AccessibilityRole::Group objects, and AccessibilityRole::Group
1494     // objects are often containers with meaningful information, the inclusion of a span can have
1495     // the side effect of causing the immediate parent accessible to be ignored. This is especially
1496     // problematic for platforms which have distinct roles for textual block elements.
1497     if (node && node->hasTagName(spanTag))
1498         return true;
1499
1500     // Other non-ignored host language elements
1501     if (node && node->hasTagName(dfnTag))
1502         return false;
1503     
1504     if (isStyleFormatGroup())
1505         return false;
1506     
1507     // Make sure that ruby containers are not ignored.
1508     if (m_renderer->isRubyRun() || m_renderer->isRubyBlock() || m_renderer->isRubyInline())
1509         return false;
1510
1511     // Find out if this element is inside of a label element.
1512     // If so, it may be ignored because it's the label for a checkbox or radio button.
1513     AccessibilityObject* controlObject = correspondingControlForLabelElement();
1514     if (controlObject && !controlObject->exposesTitleUIElement() && controlObject->isCheckboxOrRadio())
1515         return true;
1516
1517     // By default, objects should be ignored so that the AX hierarchy is not
1518     // filled with unnecessary items.
1519     return true;
1520 }
1521
1522 bool AccessibilityRenderObject::isLoaded() const
1523 {
1524     return m_renderer ? !m_renderer->document().parser() : false;
1525 }
1526
1527 double AccessibilityRenderObject::estimatedLoadingProgress() const
1528 {
1529     if (!m_renderer)
1530         return 0;
1531     
1532     if (isLoaded())
1533         return 1.0;
1534     
1535     return m_renderer->page().progress().estimatedProgress();
1536 }
1537     
1538 int AccessibilityRenderObject::layoutCount() const
1539 {
1540     if (!m_renderer || !is<RenderView>(*m_renderer))
1541         return 0;
1542     return downcast<RenderView>(*m_renderer).frameView().layoutContext().layoutCount();
1543 }
1544
1545 String AccessibilityRenderObject::text() const
1546 {
1547     if (isPasswordField())
1548         return passwordFieldValue();
1549
1550     return AccessibilityNodeObject::text();
1551 }
1552     
1553 int AccessibilityRenderObject::textLength() const
1554 {
1555     ASSERT(isTextControl());
1556     
1557     if (isPasswordField())
1558         return passwordFieldValue().length();
1559
1560     return text().length();
1561 }
1562
1563 PlainTextRange AccessibilityRenderObject::documentBasedSelectedTextRange() const
1564 {
1565     Node* node = m_renderer->node();
1566     if (!node)
1567         return PlainTextRange();
1568
1569     auto visibleSelection = selection();
1570     auto selectionRange = visibleSelection.firstRange();
1571     if (!selectionRange || !intersects(*selectionRange, *node))
1572         return PlainTextRange();
1573
1574     int start = indexForVisiblePosition(visibleSelection.start());
1575     int end = indexForVisiblePosition(visibleSelection.end());
1576     return PlainTextRange(start, end - start);
1577 }
1578
1579 String AccessibilityRenderObject::selectedText() const
1580 {
1581     ASSERT(isTextControl());
1582     
1583     if (isPasswordField())
1584         return String(); // need to return something distinct from empty string
1585     
1586     if (isNativeTextControl()) {
1587         HTMLTextFormControlElement& textControl = downcast<RenderTextControl>(*m_renderer).textFormControlElement();
1588         return textControl.selectedText();
1589     }
1590     
1591     return doAXStringForRange(documentBasedSelectedTextRange());
1592 }
1593
1594 String AccessibilityRenderObject::accessKey() const
1595 {
1596     if (!m_renderer)
1597         return String();
1598
1599     Node* node = m_renderer->node();
1600     if (!is<Element>(node))
1601         return String();
1602
1603     return downcast<Element>(*node).attributeWithoutSynchronization(accesskeyAttr);
1604 }
1605
1606 VisibleSelection AccessibilityRenderObject::selection() const
1607 {
1608     return m_renderer->frame().selection().selection();
1609 }
1610
1611 PlainTextRange AccessibilityRenderObject::selectedTextRange() const
1612 {
1613     ASSERT(isTextControl());
1614
1615     if (isPasswordField())
1616         return PlainTextRange();
1617
1618     // Use the text control native range if it's a native object.
1619     if (isNativeTextControl()) {
1620         auto& textControl = downcast<RenderTextControl>(*m_renderer).textFormControlElement();
1621         return PlainTextRange(textControl.selectionStart(), textControl.selectionEnd() - textControl.selectionStart());
1622     }
1623
1624     return documentBasedSelectedTextRange();
1625 }
1626
1627 static void setTextSelectionIntent(AXObjectCache* cache, AXTextStateChangeType type)
1628 {
1629     if (!cache)
1630         return;
1631     AXTextStateChangeIntent intent(type, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, false });
1632     cache->setTextSelectionIntent(intent);
1633     cache->setIsSynchronizingSelection(true);
1634 }
1635
1636 static void clearTextSelectionIntent(AXObjectCache* cache)
1637 {
1638     if (!cache)
1639         return;
1640     cache->setTextSelectionIntent(AXTextStateChangeIntent());
1641     cache->setIsSynchronizingSelection(false);
1642 }
1643
1644 void AccessibilityRenderObject::setSelectedTextRange(const PlainTextRange& range)
1645 {
1646     setTextSelectionIntent(axObjectCache(), range.length ? AXTextStateChangeTypeSelectionExtend : AXTextStateChangeTypeSelectionMove);
1647
1648     if (isNativeTextControl()) {
1649         HTMLTextFormControlElement& textControl = downcast<RenderTextControl>(*m_renderer).textFormControlElement();
1650         textControl.setSelectionRange(range.start, range.start + range.length);
1651     } else {
1652         ASSERT(node());
1653         auto& node = *this->node();
1654         auto elementRange = this->elementRange();
1655         auto start = visiblePositionForIndexUsingCharacterIterator(node, range.start);
1656         if (!isPointInRange(*elementRange, makeBoundaryPoint(start)))
1657             start = createLegacyEditingPosition(elementRange->start);
1658         auto end = visiblePositionForIndexUsingCharacterIterator(node, range.start + range.length);
1659         if (!isPointInRange(*elementRange, makeBoundaryPoint(end)))
1660             end = createLegacyEditingPosition(elementRange->start);
1661         m_renderer->frame().selection().setSelection(VisibleSelection(start, end), FrameSelection::defaultSetSelectionOptions(UserTriggered));
1662     }
1663     
1664     clearTextSelectionIntent(axObjectCache());
1665 }
1666
1667 URL AccessibilityRenderObject::url() const
1668 {
1669     auto* node = this->node();
1670     if (isLink() && is<HTMLAnchorElement>(node)) {
1671         if (HTMLAnchorElement* anchor = downcast<HTMLAnchorElement>(anchorElement()))
1672             return anchor->href();
1673     }
1674
1675     if (m_renderer && isWebArea())
1676         return m_renderer->document().url();
1677
1678     if (isImage() && is<HTMLImageElement>(node))
1679         return downcast<HTMLImageElement>(node)->src();
1680
1681     if (isInputImage() && is<HTMLInputElement>(node))
1682         return downcast<HTMLInputElement>(node)->src();
1683
1684     return URL();
1685 }
1686
1687 bool AccessibilityRenderObject::isUnvisited() const
1688 {
1689     if (!m_renderer)
1690         return true;
1691
1692     // FIXME: Is it a privacy violation to expose unvisited information to accessibility APIs?
1693     return m_renderer->style().isLink() && m_renderer->style().insideLink() == InsideLink::InsideUnvisited;
1694 }
1695
1696 bool AccessibilityRenderObject::isVisited() const
1697 {
1698     if (!m_renderer)
1699         return false;
1700
1701     // FIXME: Is it a privacy violation to expose visited information to accessibility APIs?
1702     return m_renderer->style().isLink() && m_renderer->style().insideLink() == InsideLink::InsideVisited;
1703 }
1704
1705 void AccessibilityRenderObject::setElementAttributeValue(const QualifiedName& attributeName, bool value)
1706 {
1707     if (!m_renderer)
1708         return;
1709     
1710     Node* node = m_renderer->node();
1711     if (!is<Element>(node))
1712         return;
1713     
1714     downcast<Element>(*node).setAttribute(attributeName, (value) ? "true" : "false");
1715 }
1716     
1717 bool AccessibilityRenderObject::elementAttributeValue(const QualifiedName& attributeName) const
1718 {
1719     if (!m_renderer)
1720         return false;
1721     
1722     return equalLettersIgnoringASCIICase(getAttribute(attributeName), "true");
1723 }
1724     
1725 bool AccessibilityRenderObject::isSelected() const
1726 {
1727     if (!m_renderer)
1728         return false;
1729     
1730     if (!m_renderer->node())
1731         return false;
1732     
1733     if (equalLettersIgnoringASCIICase(getAttribute(aria_selectedAttr), "true"))
1734         return true;    
1735     
1736     if (isTabItem() && isTabItemSelected())
1737         return true;
1738
1739     // Menu items are considered selectable by assistive technologies
1740     if (isMenuItem())
1741         return isFocused() || parentObjectUnignored()->activeDescendant() == this;
1742
1743     return false;
1744 }
1745
1746 bool AccessibilityRenderObject::isTabItemSelected() const
1747 {
1748     if (!isTabItem() || !m_renderer)
1749         return false;
1750     
1751     Node* node = m_renderer->node();
1752     if (!node || !node->isElementNode())
1753         return false;
1754     
1755     // The ARIA spec says a tab item can also be selected if it is aria-labeled by a tabpanel
1756     // that has keyboard focus inside of it, or if a tabpanel in its aria-controls list has KB
1757     // focus inside of it.
1758     AccessibilityObject* focusedElement = static_cast<AccessibilityObject*>(focusedUIElement());
1759     if (!focusedElement)
1760         return false;
1761     
1762     Vector<Element*> elements;
1763     elementsFromAttribute(elements, aria_controlsAttr);
1764     
1765     AXObjectCache* cache = axObjectCache();
1766     if (!cache)
1767         return false;
1768     
1769     for (const auto& element : elements) {
1770         AccessibilityObject* tabPanel = cache->getOrCreate(element);
1771
1772         // A tab item should only control tab panels.
1773         if (!tabPanel || tabPanel->roleValue() != AccessibilityRole::TabPanel)
1774             continue;
1775         
1776         AccessibilityObject* checkFocusElement = focusedElement;
1777         // Check if the focused element is a descendant of the element controlled by the tab item.
1778         while (checkFocusElement) {
1779             if (tabPanel == checkFocusElement)
1780                 return true;
1781             checkFocusElement = checkFocusElement->parentObject();
1782         }
1783     }
1784     
1785     return false;
1786 }
1787     
1788 bool AccessibilityRenderObject::isFocused() const
1789 {
1790     if (!m_renderer)
1791         return false;
1792     
1793     Document& document = m_renderer->document();
1794
1795     Element* focusedElement = document.focusedElement();
1796     if (!focusedElement)
1797         return false;
1798     
1799     // A web area is represented by the Document node in the DOM tree, which isn't focusable.
1800     // Check instead if the frame's selection controller is focused
1801     if (focusedElement == m_renderer->node()
1802         || (roleValue() == AccessibilityRole::WebArea && document.frame()->selection().isFocusedAndActive()))
1803         return true;
1804     
1805     return false;
1806 }
1807
1808 void AccessibilityRenderObject::setFocused(bool on)
1809 {
1810     if (!canSetFocusAttribute())
1811         return;
1812     
1813     Document* document = this->document();
1814     Node* node = this->node();
1815
1816     if (!on || !is<Element>(node)) {
1817         document->setFocusedElement(nullptr);
1818         return;
1819     }
1820
1821     // When a node is told to set focus, that can cause it to be deallocated, which means that doing
1822     // anything else inside this object will crash. To fix this, we added a RefPtr to protect this object
1823     // long enough for duration.
1824     RefPtr<AccessibilityObject> protectedThis(this);
1825     
1826     // If this node is already the currently focused node, then calling focus() won't do anything.
1827     // That is a problem when focus is removed from the webpage to chrome, and then returns.
1828     // In these cases, we need to do what keyboard and mouse focus do, which is reset focus first.
1829     if (document->focusedElement() == node)
1830         document->setFocusedElement(nullptr);
1831
1832     // If we return from setFocusedElement and our element has been removed from a tree, axObjectCache() may be null.
1833     if (AXObjectCache* cache = axObjectCache()) {
1834         cache->setIsSynchronizingSelection(true);
1835         downcast<Element>(*node).focus();
1836         cache->setIsSynchronizingSelection(false);
1837     }
1838 }
1839
1840 void AccessibilityRenderObject::setSelectedRows(AccessibilityChildrenVector& selectedRows)
1841 {
1842     // Setting selected only makes sense in trees and tables (and tree-tables).
1843     AccessibilityRole role = roleValue();
1844     if (role != AccessibilityRole::Tree && role != AccessibilityRole::TreeGrid && role != AccessibilityRole::Table && role != AccessibilityRole::Grid)
1845         return;
1846     
1847     bool isMulti = isMultiSelectable();
1848     unsigned count = selectedRows.size();
1849     if (count > 1 && !isMulti)
1850         count = 1;
1851     
1852     for (const auto& selectedRow : selectedRows)
1853         selectedRow->setSelected(true);
1854 }
1855     
1856 bool AccessibilityRenderObject::setValue(const String& string)
1857 {
1858     if (!m_renderer || !is<Element>(m_renderer->node()))
1859         return false;
1860     
1861     Element& element = downcast<Element>(*m_renderer->node());
1862     RenderObject& renderer = *m_renderer;
1863     
1864     // We should use the editor's insertText to mimic typing into the field.
1865     // Also only do this when the field is in editing mode.
1866     if (Frame* frame = renderer.document().frame()) {
1867         Editor& editor = frame->editor();
1868         if (element.shouldUseInputMethod()) {
1869             editor.clearText();
1870             editor.insertText(string, nullptr);
1871             return true;
1872         }
1873     }
1874     // FIXME: Do we want to do anything here for ARIA textboxes?
1875     if (renderer.isTextField() && is<HTMLInputElement>(element)) {
1876         downcast<HTMLInputElement>(element).setValue(string);
1877         return true;
1878     }
1879     if (renderer.isTextArea() && is<HTMLTextAreaElement>(element)) {
1880         downcast<HTMLTextAreaElement>(element).setValue(string);
1881         return true;
1882     }
1883     
1884     return false;
1885 }
1886
1887 bool AccessibilityRenderObject::supportsARIAOwns() const
1888 {
1889     if (!m_renderer)
1890         return false;
1891     const AtomString& ariaOwns = getAttribute(aria_ownsAttr);
1892
1893     return !ariaOwns.isEmpty();
1894 }
1895     
1896 RenderView* AccessibilityRenderObject::topRenderer() const
1897 {
1898     Document* topDoc = topDocument();
1899     if (!topDoc)
1900         return nullptr;
1901     
1902     return topDoc->renderView();
1903 }
1904
1905 Document* AccessibilityRenderObject::document() const
1906 {
1907     if (!m_renderer)
1908         return nullptr;
1909     return &m_renderer->document();
1910 }
1911
1912 Widget* AccessibilityRenderObject::widget() const
1913 {
1914     if (!m_renderer || !is<RenderWidget>(*m_renderer))
1915         return nullptr;
1916     return downcast<RenderWidget>(*m_renderer).widget();
1917 }
1918
1919 AccessibilityObject* AccessibilityRenderObject::accessibilityParentForImageMap(HTMLMapElement* map) const
1920 {
1921     // find an image that is using this map
1922     if (!map)
1923         return nullptr;
1924
1925     HTMLImageElement* imageElement = map->imageElement();
1926     if (!imageElement)
1927         return nullptr;
1928     
1929     if (AXObjectCache* cache = axObjectCache())
1930         return cache->getOrCreate(imageElement);
1931     
1932     return nullptr;
1933 }
1934
1935 AXCoreObject::AccessibilityChildrenVector AccessibilityRenderObject::documentLinks()
1936 {
1937     AccessibilityChildrenVector result;
1938     Document& document = m_renderer->document();
1939     Ref<HTMLCollection> links = document.links();
1940     for (unsigned i = 0; auto* current = links->item(i); ++i) {
1941         if (auto* renderer = current->renderer()) {
1942             RefPtr<AccessibilityObject> axObject = document.axObjectCache()->getOrCreate(renderer);
1943             ASSERT(axObject);
1944             if (!axObject->accessibilityIsIgnored() && axObject->isLink())
1945                 result.append(axObject);
1946         } else {
1947             auto* parent = current->parentNode();
1948             if (is<HTMLAreaElement>(*current) && is<HTMLMapElement>(parent)) {
1949                 auto& areaObject = downcast<AccessibilityImageMapLink>(*axObjectCache()->create(AccessibilityRole::ImageMapLink));
1950                 HTMLMapElement& map = downcast<HTMLMapElement>(*parent);
1951                 areaObject.setHTMLAreaElement(downcast<HTMLAreaElement>(current));
1952                 areaObject.setHTMLMapElement(&map);
1953                 areaObject.setParent(accessibilityParentForImageMap(&map));
1954
1955                 result.append(&areaObject);
1956             }
1957         }
1958     }
1959
1960     return result;
1961 }
1962
1963 FrameView* AccessibilityRenderObject::documentFrameView() const 
1964
1965     if (!m_renderer)
1966         return nullptr;
1967
1968     // this is the RenderObject's Document's Frame's FrameView 
1969     return &m_renderer->view().frameView();
1970 }
1971
1972 Widget* AccessibilityRenderObject::widgetForAttachmentView() const
1973 {
1974     if (!isAttachment())
1975         return nullptr;
1976     return downcast<RenderWidget>(*m_renderer).widget();
1977 }
1978
1979 // This function is like a cross-platform version of - (WebCoreTextMarkerRange*)textMarkerRange. It returns
1980 // a Range that we can convert to a WebCoreTextMarkerRange in the Obj-C file
1981 VisiblePositionRange AccessibilityRenderObject::visiblePositionRange() const
1982 {
1983     if (!m_renderer)
1984         return VisiblePositionRange();
1985     
1986     Node* node = m_renderer->node();
1987     if (!node)
1988         return VisiblePositionRange();
1989
1990     VisiblePosition startPos = firstPositionInOrBeforeNode(node);
1991     VisiblePosition endPos = lastPositionInOrAfterNode(node);
1992
1993     // the VisiblePositions are equal for nodes like buttons, so adjust for that
1994     // FIXME: Really?  [button, 0] and [button, 1] are distinct (before and after the button)
1995     // I expect this code is only hit for things like empty divs?  In which case I don't think
1996     // the behavior is correct here -- eseidel
1997     if (startPos == endPos) {
1998         endPos = endPos.next();
1999         if (endPos.isNull())
2000             endPos = startPos;
2001     }
2002
2003     return { WTFMove(startPos), WTFMove(endPos) };
2004 }
2005
2006 VisiblePositionRange AccessibilityRenderObject::visiblePositionRangeForLine(unsigned lineCount) const
2007 {
2008     if (!lineCount || !m_renderer)
2009         return VisiblePositionRange();
2010     
2011     // iterate over the lines
2012     // FIXME: This is wrong when lineNumber is lineCount+1, because nextLinePosition takes you to the last offset of the last line.
2013     VisiblePosition position = m_renderer->view().positionForPoint(IntPoint(), nullptr);
2014     while (--lineCount) {
2015         auto previousLinePosition = position;
2016         position = nextLinePosition(position, 0);
2017         if (position.isNull() || position == previousLinePosition)
2018             return VisiblePositionRange();
2019     }
2020
2021     // make a caret selection for the marker position, then extend it to the line
2022     // NOTE: Ignores results of sel.modify because it returns false when starting at an empty line.
2023     // The resulting selection in that case will be a caret at position.
2024     FrameSelection selection;
2025     selection.setSelection(position);
2026     selection.modify(FrameSelection::AlterationExtend, SelectionDirection::Right, TextGranularity::LineBoundary);
2027     return selection.selection();
2028 }
2029     
2030 VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(int index) const
2031 {
2032     if (!m_renderer)
2033         return VisiblePosition();
2034
2035     if (isNativeTextControl())
2036         return downcast<RenderTextControl>(*m_renderer).textFormControlElement().visiblePositionForIndex(index);
2037
2038     if (!allowsTextRanges() && !is<RenderText>(*m_renderer))
2039         return VisiblePosition();
2040     
2041     Node* node = m_renderer->node();
2042     if (!node)
2043         return VisiblePosition();
2044
2045     return visiblePositionForIndexUsingCharacterIterator(*node, index);
2046 }
2047     
2048 int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& position) const
2049 {
2050     if (isNativeTextControl())
2051         return downcast<RenderTextControl>(*m_renderer).textFormControlElement().indexForVisiblePosition(position);
2052
2053     if (!isTextControl())
2054         return 0;
2055     
2056     Node* node = m_renderer->node();
2057     if (!node)
2058         return 0;
2059
2060     Position indexPosition = position.deepEquivalent();
2061     if (indexPosition.isNull() || highestEditableRoot(indexPosition, HasEditableAXRole) != node)
2062         return 0;
2063
2064 #if USE(ATK)
2065     // We need to consider replaced elements for GTK, as they will be
2066     // presented with the 'object replacement character' (0xFFFC).
2067     bool forSelectionPreservation = true;
2068 #else
2069     bool forSelectionPreservation = false;
2070 #endif
2071
2072     return WebCore::indexForVisiblePosition(*node, position, forSelectionPreservation);
2073 }
2074
2075 Element* AccessibilityRenderObject::rootEditableElementForPosition(const Position& position) const
2076 {
2077     // Find the root editable or pseudo-editable (i.e. having an editable ARIA role) element.
2078     Element* result = nullptr;
2079     
2080     Element* rootEditableElement = position.rootEditableElement();
2081
2082     for (Element* e = position.element(); e && e != rootEditableElement; e = e->parentElement()) {
2083         if (nodeIsTextControl(e))
2084             result = e;
2085         if (e->hasTagName(bodyTag))
2086             break;
2087     }
2088
2089     if (result)
2090         return result;
2091
2092     return rootEditableElement;
2093 }
2094
2095 bool AccessibilityRenderObject::nodeIsTextControl(const Node* node) const
2096 {
2097     if (!node)
2098         return false;
2099
2100     if (AXObjectCache* cache = axObjectCache()) {
2101         if (AccessibilityObject* axObjectForNode = cache->getOrCreate(const_cast<Node*>(node)))
2102             return axObjectForNode->isTextControl();
2103     }
2104
2105     return false;
2106 }
2107
2108 static IntRect boundsForRects(const LayoutRect& rect1, const LayoutRect& rect2, const SimpleRange& dataRange)
2109 {
2110     LayoutRect ourRect = rect1;
2111     ourRect.unite(rect2);
2112
2113     // If the rectangle spans lines and contains multiple text characters, use the range's bounding box intead.
2114     if (rect1.maxY() != rect2.maxY() && characterCount(dataRange) > 1) {
2115         if (auto boundingBox = unionRect(RenderObject::absoluteTextRects(dataRange)); !boundingBox.isEmpty())
2116             ourRect = boundingBox;
2117     }
2118
2119     return snappedIntRect(ourRect);
2120 }
2121
2122 IntRect AccessibilityRenderObject::boundsForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
2123 {
2124     if (visiblePositionRange.isNull())
2125         return IntRect();
2126     
2127     // Create a mutable VisiblePositionRange.
2128     VisiblePositionRange range(visiblePositionRange);
2129     LayoutRect rect1 = range.start.absoluteCaretBounds();
2130     LayoutRect rect2 = range.end.absoluteCaretBounds();
2131     
2132     // readjust for position at the edge of a line.  This is to exclude line rect that doesn't need to be accounted in the range bounds
2133     if (rect2.y() != rect1.y()) {
2134         VisiblePosition endOfFirstLine = endOfLine(range.start);
2135         if (range.start == endOfFirstLine) {
2136             range.start.setAffinity(Affinity::Downstream);
2137             rect1 = range.start.absoluteCaretBounds();
2138         }
2139         if (range.end == endOfFirstLine) {
2140             range.end.setAffinity(Affinity::Upstream);
2141             rect2 = range.end.absoluteCaretBounds();
2142         }
2143     }
2144     
2145     return boundsForRects(rect1, rect2, *makeSimpleRange(range));
2146 }
2147
2148 IntRect AccessibilityRenderObject::boundsForRange(const SimpleRange& range) const
2149 {
2150     auto cache = axObjectCache();
2151     if (!cache)
2152         return { };
2153
2154     auto start = cache->startOrEndCharacterOffsetForRange(range, true);
2155     auto end = cache->startOrEndCharacterOffsetForRange(range, false);
2156
2157     auto rect1 = cache->absoluteCaretBoundsForCharacterOffset(start);
2158     auto rect2 = cache->absoluteCaretBoundsForCharacterOffset(end);
2159
2160     // Readjust for position at the edge of a line. This is to exclude line rect that doesn't need to be accounted in the range bounds.
2161     if (rect2.y() != rect1.y()) {
2162         auto endOfFirstLine = cache->endCharacterOffsetOfLine(start);
2163         if (start.isEqual(endOfFirstLine)) {
2164             start = cache->nextCharacterOffset(start, false);
2165             rect1 = cache->absoluteCaretBoundsForCharacterOffset(start);
2166         }
2167         if (end.isEqual(endOfFirstLine)) {
2168             end = cache->previousCharacterOffset(end, false);
2169             rect2 = cache->absoluteCaretBoundsForCharacterOffset(end);
2170         }
2171     }
2172
2173     return boundsForRects(rect1, rect2, range);
2174 }
2175
2176 bool AccessibilityRenderObject::isVisiblePositionRangeInDifferentDocument(const VisiblePositionRange& range) const
2177 {
2178     if (range.start.isNull() || range.end.isNull())
2179         return false;
2180     
2181     VisibleSelection newSelection = VisibleSelection(range.start, range.end);
2182     if (Document* newSelectionDocument = newSelection.base().document()) {
2183         if (RefPtr<Frame> newSelectionFrame = newSelectionDocument->frame()) {
2184             Frame* frame = this->frame();
2185             if (!frame || (newSelectionFrame != frame && newSelectionDocument != frame->document()))
2186                 return true;
2187         }
2188     }
2189     
2190     return false;
2191 }
2192
2193 void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePositionRange& range) const
2194 {
2195     if (range.isNull())
2196         return;
2197
2198     // In WebKit1, when the top web area sets the selection to be an input element in an iframe, the caret will disappear.
2199     // FrameSelection::setSelectionWithoutUpdatingAppearance is setting the selection on the new frame in this case, and causing this behavior.
2200     if (isWebArea() && parentObject() && parentObject()->isAttachment()
2201         && isVisiblePositionRangeInDifferentDocument(range))
2202         return;
2203
2204     // make selection and tell the document to use it. if it's zero length, then move to that position
2205     if (range.start == range.end) {
2206         setTextSelectionIntent(axObjectCache(), AXTextStateChangeTypeSelectionMove);
2207
2208         auto start = range.start;
2209         if (auto elementRange = this->elementRange()) {
2210             if (!isPointInRange(*elementRange, makeBoundaryPoint(start)))
2211                 start = createLegacyEditingPosition(elementRange->start);
2212         }
2213
2214         m_renderer->frame().selection().moveTo(start, UserTriggered);
2215     } else {
2216         setTextSelectionIntent(axObjectCache(), AXTextStateChangeTypeSelectionExtend);
2217
2218         VisibleSelection newSelection = VisibleSelection(range.start, range.end);
2219         m_renderer->frame().selection().setSelection(newSelection, FrameSelection::defaultSetSelectionOptions());
2220     }
2221
2222     clearTextSelectionIntent(axObjectCache());
2223 }
2224
2225 VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoint& point) const
2226 {
2227     if (!m_renderer)
2228         return VisiblePosition();
2229
2230     // convert absolute point to view coordinates
2231     RenderView* renderView = topRenderer();
2232     if (!renderView)
2233         return VisiblePosition();
2234
2235 #if PLATFORM(COCOA)
2236     FrameView* frameView = &renderView->frameView();
2237 #endif
2238
2239     Node* innerNode = nullptr;
2240     
2241     // Locate the node containing the point
2242     // FIXME: Remove this loop and instead add HitTestRequest::AllowVisibleChildFrameContentOnly to the hit test request type.
2243     LayoutPoint pointResult;
2244     while (1) {
2245         LayoutPoint pointToUse;
2246 #if PLATFORM(MAC)
2247         pointToUse = frameView->screenToContents(point);
2248 #else
2249         pointToUse = point;
2250 #endif
2251         constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active };
2252         HitTestResult result { pointToUse };
2253         renderView->document().hitTest(hitType, result);
2254         innerNode = result.innerNode();
2255         if (!innerNode)
2256             return VisiblePosition();
2257         
2258         RenderObject* renderer = innerNode->renderer();
2259         if (!renderer)
2260             return VisiblePosition();
2261         
2262         pointResult = result.localPoint();
2263
2264         // done if hit something other than a widget
2265         if (!is<RenderWidget>(*renderer))
2266             break;
2267
2268         // descend into widget (FRAME, IFRAME, OBJECT...)
2269         Widget* widget = downcast<RenderWidget>(*renderer).widget();
2270         if (!is<FrameView>(widget))
2271             break;
2272         Frame& frame = downcast<FrameView>(*widget).frame();
2273         renderView = frame.document()->renderView();
2274 #if PLATFORM(COCOA)
2275         frameView = downcast<FrameView>(widget);
2276 #endif
2277     }
2278     
2279     return innerNode->renderer()->positionForPoint(pointResult, nullptr);
2280 }
2281
2282 // NOTE: Consider providing this utility method as AX API
2283 VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const
2284 {
2285     if (!isTextControl())
2286         return VisiblePosition();
2287     
2288     // lastIndexOK specifies whether the position after the last character is acceptable
2289     if (indexValue >= text().length()) {
2290         if (!lastIndexOK || indexValue > text().length())
2291             return VisiblePosition();
2292     }
2293     VisiblePosition position = visiblePositionForIndex(indexValue);
2294     position.setAffinity(Affinity::Downstream);
2295     return position;
2296 }
2297
2298 // NOTE: Consider providing this utility method as AX API
2299 int AccessibilityRenderObject::index(const VisiblePosition& position) const
2300 {
2301     if (position.isNull() || !isTextControl())
2302         return -1;
2303
2304     if (renderObjectContainsPosition(renderer(), position.deepEquivalent()))
2305         return indexForVisiblePosition(position);
2306     
2307     return -1;
2308 }
2309
2310 void AccessibilityRenderObject::lineBreaks(Vector<int>& lineBreaks) const
2311 {
2312     if (!isTextControl())
2313         return;
2314
2315     VisiblePosition visiblePos = visiblePositionForIndex(0);
2316     VisiblePosition savedVisiblePos = visiblePos;
2317     visiblePos = nextLinePosition(visiblePos, 0);
2318     while (!visiblePos.isNull() && visiblePos != savedVisiblePos) {
2319         lineBreaks.append(indexForVisiblePosition(visiblePos));
2320         savedVisiblePos = visiblePos;
2321         visiblePos = nextLinePosition(visiblePos, 0);
2322     }
2323 }
2324
2325 // Given a line number, the range of characters of the text associated with this accessibility
2326 // object that contains the line number.
2327 PlainTextRange AccessibilityRenderObject::doAXRangeForLine(unsigned lineNumber) const
2328 {
2329     if (!isTextControl())
2330         return PlainTextRange();
2331     
2332     // iterate to the specified line
2333     VisiblePosition visiblePos = visiblePositionForIndex(0);
2334     VisiblePosition savedVisiblePos;
2335     for (unsigned lineCount = lineNumber; lineCount; lineCount -= 1) {
2336         savedVisiblePos = visiblePos;
2337         visiblePos = nextLinePosition(visiblePos, 0);
2338         if (visiblePos.isNull() || visiblePos == savedVisiblePos)
2339             return PlainTextRange();
2340     }
2341
2342     // Get the end of the line based on the starting position.
2343     VisiblePosition endPosition = endOfLine(visiblePos);
2344
2345     int index1 = indexForVisiblePosition(visiblePos);
2346     int index2 = indexForVisiblePosition(endPosition);
2347     
2348     // add one to the end index for a line break not caused by soft line wrap (to match AppKit)
2349     if (endPosition.affinity() == Affinity::Downstream && endPosition.next().isNotNull())
2350         index2 += 1;
2351     
2352     // return nil rather than an zero-length range (to match AppKit)
2353     if (index1 == index2)
2354         return PlainTextRange();
2355     
2356     return PlainTextRange(index1, index2 - index1);
2357 }
2358
2359 // The composed character range in the text associated with this accessibility object that
2360 // is specified by the given index value. This parameterized attribute returns the complete
2361 // range of characters (including surrogate pairs of multi-byte glyphs) at the given index.
2362 PlainTextRange AccessibilityRenderObject::doAXRangeForIndex(unsigned index) const
2363 {
2364     if (!isTextControl())
2365         return PlainTextRange();
2366     
2367     String elementText = text();
2368     if (!elementText.length() || index > elementText.length() - 1)
2369         return PlainTextRange();
2370     
2371     return PlainTextRange(index, 1);
2372 }
2373
2374 // A substring of the text associated with this accessibility object that is
2375 // specified by the given character range.
2376 String AccessibilityRenderObject::doAXStringForRange(const PlainTextRange& range) const
2377 {
2378     if (!range.length)
2379         return String();
2380     
2381     if (!isTextControl())
2382         return String();
2383     
2384     String elementText = isPasswordField() ? passwordFieldValue() : text();
2385     return elementText.substring(range.start, range.length);
2386 }
2387
2388 // The bounding rectangle of the text associated with this accessibility object that is
2389 // specified by the given range. This is the bounding rectangle a sighted user would see
2390 // on the display screen, in pixels.
2391 IntRect AccessibilityRenderObject::doAXBoundsForRange(const PlainTextRange& range) const
2392 {
2393     if (allowsTextRanges())
2394         return boundsForVisiblePositionRange(visiblePositionRangeForRange(range));
2395     return IntRect();
2396 }
2397
2398 IntRect AccessibilityRenderObject::doAXBoundsForRangeUsingCharacterOffset(const PlainTextRange& characterRange) const
2399 {
2400     if (!allowsTextRanges())
2401         return { };
2402     auto range = rangeForPlainTextRange(characterRange);
2403     if (!range)
2404         return { };
2405     return boundsForRange(*range);
2406 }
2407
2408 AXCoreObject* AccessibilityRenderObject::accessibilityImageMapHitTest(HTMLAreaElement* area, const IntPoint& point) const
2409 {
2410     if (!area)
2411         return nullptr;
2412
2413     auto* mapParent = ancestorsOfType<HTMLMapElement>(*area).first();
2414     if (!mapParent)
2415         return nullptr;
2416
2417     auto* parent = accessibilityParentForImageMap(mapParent);
2418     if (!parent)
2419         return nullptr;
2420
2421     for (const auto& child : parent->children()) {
2422         if (child->elementRect().contains(point))
2423             return child.get();
2424     }
2425
2426     return nullptr;
2427 }
2428
2429 AXCoreObject* AccessibilityRenderObject::remoteSVGElementHitTest(const IntPoint& point) const
2430 {
2431     AccessibilityObject* remote = remoteSVGRootElement(Create);
2432     if (!remote)
2433         return nullptr;
2434     
2435     IntSize offset = point - roundedIntPoint(boundingBoxRect().location());
2436     return remote->accessibilityHitTest(IntPoint(offset));
2437 }
2438
2439 AXCoreObject* AccessibilityRenderObject::elementAccessibilityHitTest(const IntPoint& point) const
2440 {
2441     if (isSVGImage())
2442         return remoteSVGElementHitTest(point);
2443     
2444     return AccessibilityObject::elementAccessibilityHitTest(point);
2445 }
2446     
2447 static bool shouldUseShadowHostForHitTesting(Node* shadowHost)
2448 {
2449     // We need to allow automation of mouse events on video tags.
2450     return shadowHost && !shadowHost->hasTagName(videoTag);
2451 }
2452
2453 AXCoreObject* AccessibilityRenderObject::accessibilityHitTest(const IntPoint& point) const
2454 {
2455     if (!m_renderer || !m_renderer->hasLayer())
2456         return nullptr;
2457     
2458     m_renderer->document().updateLayout();
2459
2460     if (!m_renderer || !m_renderer->hasLayer())
2461         return nullptr;
2462
2463     RenderLayer* layer = downcast<RenderBox>(*m_renderer).layer();
2464      
2465     constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::AccessibilityHitTest };
2466     HitTestResult hitTestResult { point };
2467     layer->hitTest(hitType, hitTestResult);
2468     Node* node = hitTestResult.innerNode();
2469     if (!node)
2470         return nullptr;
2471     Node* shadowAncestorNode = node->shadowHost();
2472     if (shouldUseShadowHostForHitTesting(shadowAncestorNode))
2473         node = shadowAncestorNode;
2474     ASSERT(node);
2475
2476     if (is<HTMLAreaElement>(*node))
2477         return accessibilityImageMapHitTest(downcast<HTMLAreaElement>(node), point);
2478     
2479     if (is<HTMLOptionElement>(*node))
2480         node = downcast<HTMLOptionElement>(*node).ownerSelectElement();
2481     
2482     RenderObject* obj = node->renderer();
2483     if (!obj)
2484         return nullptr;
2485     
2486     AXCoreObject* result = obj->document().axObjectCache()->getOrCreate(obj);
2487     result->updateChildrenIfNecessary();
2488
2489     // Allow the element to perform any hit-testing it might need to do to reach non-render children.
2490     result = static_cast<AccessibilityObject*>(result->elementAccessibilityHitTest(point));
2491     
2492     if (result && result->accessibilityIsIgnored()) {
2493         // If this element is the label of a control, a hit test should return the control.
2494         AXCoreObject* controlObject = result->correspondingControlForLabelElement();
2495         if (controlObject && !controlObject->exposesTitleUIElement())
2496             return controlObject;
2497
2498         result = result->parentObjectUnignored();
2499     }
2500
2501     return result;
2502 }
2503
2504 bool AccessibilityRenderObject::shouldNotifyActiveDescendant() const
2505 {
2506 #if USE(ATK)
2507     // According to the Core AAM spec, ATK expects object:state-changed:focused notifications
2508     // whenever the active descendant changes.
2509     return true;
2510 #endif
2511     // We want to notify that the combo box has changed its active descendant,
2512     // but we do not want to change the focus, because focus should remain with the combo box.
2513     if (isComboBox())
2514         return true;
2515     
2516     return shouldFocusActiveDescendant();
2517 }
2518
2519 bool AccessibilityRenderObject::shouldFocusActiveDescendant() const
2520 {
2521     switch (ariaRoleAttribute()) {
2522     case AccessibilityRole::ApplicationGroup:
2523     case AccessibilityRole::ListBox:
2524     case AccessibilityRole::Menu:
2525     case AccessibilityRole::MenuBar:
2526     case AccessibilityRole::RadioGroup:
2527     case AccessibilityRole::Row:
2528     case AccessibilityRole::PopUpButton:
2529     case AccessibilityRole::Meter:
2530     case AccessibilityRole::ProgressIndicator:
2531     case AccessibilityRole::Toolbar:
2532     case AccessibilityRole::Outline:
2533     case AccessibilityRole::Tree:
2534     case AccessibilityRole::Grid:
2535     /* FIXME: replace these with actual roles when they are added to AccessibilityRole
2536     composite
2537     alert
2538     alertdialog
2539     status
2540     timer
2541     */
2542         return true;
2543     default:
2544         return false;
2545     }
2546 }
2547
2548 AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
2549 {
2550     if (!m_renderer)
2551         return nullptr;
2552     
2553     const AtomString& activeDescendantAttrStr = getAttribute(aria_activedescendantAttr);
2554     if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
2555         return nullptr;
2556     Element* element = this->element();
2557     if (!element)
2558         return nullptr;
2559     
2560     Element* target = element->treeScope().getElementById(activeDescendantAttrStr);
2561     if (!target)
2562         return nullptr;
2563     
2564     if (AXObjectCache* cache = axObjectCache()) {
2565         AccessibilityObject* obj = cache->getOrCreate(target);
2566         if (obj && obj->isAccessibilityRenderObject())
2567             // an activedescendant is only useful if it has a renderer, because that's what's needed to post the notification
2568             return obj;
2569     }
2570     
2571     return nullptr;
2572 }
2573
2574 RenderObject* AccessibilityRenderObject::targetElementForActiveDescendant(const QualifiedName& attributeName, AccessibilityObject* activeDescendant) const
2575 {
2576     AccessibilityObject::AccessibilityChildrenVector elements;
2577     ariaElementsFromAttribute(elements, attributeName);
2578     for (const auto& element : elements) {
2579         if (activeDescendant->isDescendantOfObject(element.get()))
2580             return element->renderer();
2581     }
2582
2583     return nullptr;
2584 }
2585
2586 void AccessibilityRenderObject::handleActiveDescendantChanged()
2587 {
2588     Element* element = downcast<Element>(renderer()->node());
2589     if (!element)
2590         return;
2591     if (!renderer()->frame().selection().isFocusedAndActive() || renderer()->document().focusedElement() != element)
2592         return;
2593
2594     auto* activeDescendant = this->activeDescendant();
2595     if (activeDescendant && shouldNotifyActiveDescendant()) {
2596         auto* targetRenderer = renderer();
2597         
2598 #if PLATFORM(COCOA)
2599         // If the combobox's activeDescendant is inside another object, the target element should be that parent.
2600         if (isComboBox()) {
2601             if (auto* ariaOwner = targetElementForActiveDescendant(aria_ownsAttr, activeDescendant))
2602                 targetRenderer = ariaOwner;
2603             else if (auto* ariaController = targetElementForActiveDescendant(aria_controlsAttr, activeDescendant))
2604                 targetRenderer = ariaController;
2605         }
2606 #endif
2607     
2608         renderer()->document().axObjectCache()->postNotification(targetRenderer, AXObjectCache::AXActiveDescendantChanged);
2609     }
2610 }
2611
2612 AccessibilityObject* AccessibilityRenderObject::correspondingControlForLabelElement() const
2613 {
2614     HTMLLabelElement* labelElement = labelElementContainer();
2615     if (!labelElement)
2616         return nullptr;
2617     
2618     auto correspondingControl = labelElement->control();
2619     if (!correspondingControl)
2620         return nullptr;
2621
2622     // Make sure the corresponding control isn't a descendant of this label that's in the middle of being destroyed.
2623     if (correspondingControl->renderer() && !correspondingControl->renderer()->parent())
2624         return nullptr;
2625     
2626     return axObjectCache()->getOrCreate(correspondingControl.get());
2627 }
2628
2629 AccessibilityObject* AccessibilityRenderObject::correspondingLabelForControlElement() const
2630 {
2631     if (!m_renderer)
2632         return nullptr;
2633
2634     // ARIA: section 2A, bullet #3 says if aria-labeledby or aria-label appears, it should
2635     // override the "label" element association.
2636     if (hasTextAlternative())
2637         return nullptr;
2638
2639     Node* node = m_renderer->node();
2640     if (is<HTMLElement>(node)) {
2641         if (HTMLLabelElement* label = labelForElement(downcast<HTMLElement>(node)))
2642             return axObjectCache()->getOrCreate(label);
2643     }
2644
2645     return nullptr;
2646 }
2647
2648 bool AccessibilityRenderObject::renderObjectIsObservable(RenderObject& renderer) const
2649 {
2650     // AX clients will listen for AXValueChange on a text control.
2651     if (is<RenderTextControl>(renderer))
2652         return true;
2653     
2654     // AX clients will listen for AXSelectedChildrenChanged on listboxes.
2655     Node* node = renderer.node();
2656     if (!node)
2657         return false;
2658     
2659     if (nodeHasRole(node, "listbox") || (is<RenderBoxModelObject>(renderer) && downcast<RenderBoxModelObject>(renderer).isListBox()))
2660         return true;
2661
2662     // Textboxes should send out notifications.
2663     if (nodeHasRole(node, "textbox") || (is<Element>(*node) && contentEditableAttributeIsEnabled(downcast<Element>(node))))
2664         return true;
2665     
2666     return false;
2667 }
2668     
2669 AccessibilityObject* AccessibilityRenderObject::observableObject() const
2670 {
2671     // Find the object going up the parent chain that is used in accessibility to monitor certain notifications.
2672     for (RenderObject* renderer = this->renderer(); renderer && renderer->node(); renderer = renderer->parent()) {
2673         if (renderObjectIsObservable(*renderer)) {
2674             if (AXObjectCache* cache = axObjectCache())
2675                 return cache->getOrCreate(renderer);
2676         }
2677     }
2678     
2679     return nullptr;
2680 }
2681
2682 bool AccessibilityRenderObject::isDescendantOfElementType(const HashSet<QualifiedName>& tagNames) const
2683 {
2684     for (auto& ancestor : ancestorsOfType<RenderElement>(*m_renderer)) {
2685         if (ancestor.element() && tagNames.contains(ancestor.element()->tagQName()))
2686             return true;
2687     }
2688     return false;
2689 }
2690
2691 bool AccessibilityRenderObject::isDescendantOfElementType(const QualifiedName& tagName) const
2692 {
2693     for (auto& ancestor : ancestorsOfType<RenderElement>(*m_renderer)) {
2694         if (ancestor.element() && ancestor.element()->hasTagName(tagName))
2695             return true;
2696     }
2697     return false;
2698 }
2699     
2700 String AccessibilityRenderObject::expandedTextValue() const
2701 {
2702     if (AccessibilityObject* parent = parentObject()) {
2703         if (parent->hasTagName(abbrTag) || parent->hasTagName(acronymTag))
2704             return parent->getAttribute(titleAttr);
2705     }
2706     
2707     return String();
2708 }
2709
2710 bool AccessibilityRenderObject::supportsExpandedTextValue() const
2711 {
2712     if (roleValue() == AccessibilityRole::StaticText) {
2713         if (AccessibilityObject* parent = parentObject())
2714             return parent->hasTagName(abbrTag) || parent->hasTagName(acronymTag);
2715     }
2716     
2717     return false;
2718 }
2719
2720 AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole()
2721 {
2722     AXTRACE("AccessibilityRenderObject::determineAccessibilityRole");
2723     if (!m_renderer)
2724         return AccessibilityRole::Unknown;
2725
2726 #if ENABLE(APPLE_PAY)
2727     if (isApplePayButton())
2728         return AccessibilityRole::Button;
2729 #endif
2730
2731     // Sometimes we need to ignore the attribute role. Like if a tree is malformed,
2732     // we want to ignore the treeitem's attribute role.
2733     if ((m_ariaRole = determineAriaRoleAttribute()) != AccessibilityRole::Unknown && !shouldIgnoreAttributeRole())
2734         return m_ariaRole;
2735
2736     Node* node = m_renderer->node();
2737     RenderBoxModelObject* cssBox = renderBoxModelObject();
2738
2739     if (node && node->isLink())
2740         return AccessibilityRole::WebCoreLink;
2741     if (node && is<HTMLImageElement>(*node) && downcast<HTMLImageElement>(*node).hasAttributeWithoutSynchronization(usemapAttr))
2742         return AccessibilityRole::ImageMap;
2743     if ((cssBox && cssBox->isListItem()) || (node && node->hasTagName(liTag)))
2744         return AccessibilityRole::ListItem;
2745     if (m_renderer->isListMarker())
2746         return AccessibilityRole::ListMarker;
2747     if (node && node->hasTagName(buttonTag))
2748         return buttonRoleType();
2749     if (node && node->hasTagName(legendTag))
2750         return AccessibilityRole::Legend;
2751     if (m_renderer->isText())
2752         return AccessibilityRole::StaticText;
2753     if (cssBox && cssBox->isImage()) {
2754         if (is<HTMLInputElement>(node))
2755             return hasPopup() ? AccessibilityRole::PopUpButton : AccessibilityRole::Button;
2756         if (isSVGImage())
2757             return AccessibilityRole::SVGRoot;
2758         return AccessibilityRole::Image;
2759     }
2760     
2761     if (node && node->hasTagName(canvasTag))
2762         return AccessibilityRole::Canvas;
2763
2764     if (cssBox && cssBox->isRenderView())
2765         return AccessibilityRole::WebArea;
2766     
2767     if (cssBox && cssBox->isTextField()) {
2768         if (is<HTMLInputElement>(node))
2769             return downcast<HTMLInputElement>(*node).isSearchField() ? AccessibilityRole::SearchField : AccessibilityRole::TextField;
2770     }
2771     
2772     if (cssBox && cssBox->isTextArea())
2773         return AccessibilityRole::TextArea;
2774
2775     if (is<HTMLInputElement>(node)) {
2776         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
2777         if (input.isCheckbox())
2778             return AccessibilityRole::CheckBox;
2779         if (input.isRadioButton())
2780             return AccessibilityRole::RadioButton;
2781         if (input.isTextButton())
2782             return buttonRoleType();
2783         // On iOS, the date field and time field are popup buttons. On other platforms they are text fields.
2784 #if PLATFORM(IOS_FAMILY)
2785         if (input.isDateField() || input.isTimeField())
2786             return AccessibilityRole::PopUpButton;
2787 #endif
2788 #if ENABLE(INPUT_TYPE_COLOR)
2789         if (input.isColorControl())
2790             return AccessibilityRole::ColorWell;
2791 #endif
2792     }
2793     
2794     if (hasContentEditableAttributeSet())
2795         return AccessibilityRole::TextArea;
2796     
2797     if (isFileUploadButton())
2798         return AccessibilityRole::Button;
2799     
2800     if (cssBox && cssBox->isMenuList())
2801         return AccessibilityRole::PopUpButton;
2802     
2803     if (headingLevel())
2804         return AccessibilityRole::Heading;
2805     
2806     if (m_renderer->isSVGRoot())
2807         return AccessibilityRole::SVGRoot;
2808     
2809     if (isStyleFormatGroup()) {
2810         if (node->hasTagName(delTag))
2811             return AccessibilityRole::Deletion;
2812         if (node->hasTagName(insTag))
2813             return AccessibilityRole::Insertion;
2814         if (node->hasTagName(subTag))
2815             return AccessibilityRole::Subscript;
2816         if (node->hasTagName(supTag))
2817             return AccessibilityRole::Superscript;
2818         return is<RenderInline>(*m_renderer) ? AccessibilityRole::Inline : AccessibilityRole::TextGroup;
2819     }
2820     
2821     if (node && node->hasTagName(ddTag))
2822         return AccessibilityRole::DescriptionListDetail;
2823     
2824     if (node && node->hasTagName(dtTag))
2825         return AccessibilityRole::DescriptionListTerm;
2826
2827     if (node && node->hasTagName(dlTag))
2828         return AccessibilityRole::DescriptionList;
2829
2830     if (node && node->hasTagName(fieldsetTag))
2831         return AccessibilityRole::Group;
2832
2833     if (node && node->hasTagName(figureTag))
2834         return AccessibilityRole::Figure;
2835
2836     // Check for Ruby elements
2837     if (m_renderer->isRubyText())
2838         return AccessibilityRole::RubyText;
2839     if (m_renderer->isRubyBase())
2840         return AccessibilityRole::RubyBase;
2841     if (m_renderer->isRubyRun())
2842         return AccessibilityRole::RubyRun;
2843     if (m_renderer->isRubyBlock())
2844         return AccessibilityRole::RubyBlock;
2845     if (m_renderer->isRubyInline())
2846         return AccessibilityRole::RubyInline;
2847     
2848     // This return value is what will be used if AccessibilityTableCell determines
2849     // the cell should not be treated as a cell (e.g. because it is a layout table.
2850     if (is<RenderTableCell>(renderer()))
2851         return AccessibilityRole::TextGroup;
2852
2853     // Table sections should be ignored.
2854     if (m_renderer->isTableSection())
2855         return AccessibilityRole::Ignored;
2856
2857     if (m_renderer->isHR())
2858         return AccessibilityRole::HorizontalRule;
2859
2860     if (node && node->hasTagName(pTag))
2861         return AccessibilityRole::Paragraph;
2862
2863     if (is<HTMLLabelElement>(node))
2864         return AccessibilityRole::Label;
2865
2866     if (node && node->hasTagName(dfnTag))
2867         return AccessibilityRole::Definition;
2868
2869     if (node && node->hasTagName(divTag))
2870         return AccessibilityRole::Div;
2871
2872     if (is<HTMLFormElement>(node))
2873         return AccessibilityRole::Form;
2874
2875     if (node && node->hasTagName(articleTag))
2876         return AccessibilityRole::DocumentArticle;
2877
2878     if (node && node->hasTagName(mainTag))
2879         return AccessibilityRole::LandmarkMain;
2880
2881     if (node && node->hasTagName(navTag))
2882         return AccessibilityRole::LandmarkNavigation;
2883
2884     if (node && node->hasTagName(asideTag))
2885         return AccessibilityRole::LandmarkComplementary;
2886
2887     // The default role attribute value for the section element, region, became a landmark in ARIA 1.1.
2888     // The HTML AAM spec says it is "strongly recommended" that ATs only convey and provide navigation
2889     // for section elements which have names.
2890     if (node && node->hasTagName(sectionTag))
2891         return hasAttribute(aria_labelAttr) || hasAttribute(aria_labelledbyAttr) ? AccessibilityRole::LandmarkRegion : AccessibilityRole::TextGroup;
2892
2893     if (node && node->hasTagName(addressTag))
2894         return AccessibilityRole::Group;
2895
2896     if (node && node->hasTagName(blockquoteTag))
2897         return AccessibilityRole::Blockquote;
2898
2899     if (node && node->hasTagName(captionTag))
2900         return AccessibilityRole::Caption;
2901     
2902     if (node && node->hasTagName(markTag))
2903         return AccessibilityRole::Mark;
2904
2905     if (node && node->hasTagName(preTag))
2906         return AccessibilityRole::Pre;
2907
2908     if (is<HTMLDetailsElement>(node))
2909         return AccessibilityRole::Details;
2910     if (is<HTMLSummaryElement>(node))
2911         return AccessibilityRole::Summary;
2912     
2913     // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
2914     // Output elements should be mapped to status role.
2915     if (isOutput())
2916         return AccessibilityRole::ApplicationStatus;
2917
2918 #if ENABLE(VIDEO)
2919     if (is<HTMLVideoElement>(node))
2920         return AccessibilityRole::Video;
2921     if (is<HTMLAudioElement>(node))
2922         return AccessibilityRole::Audio;
2923 #endif
2924     
2925     // The HTML element should not be exposed as an element. That's what the RenderView element does.
2926     if (node && node->hasTagName(htmlTag))
2927         return AccessibilityRole::Ignored;
2928
2929     // There should only be one banner/contentInfo per page. If header/footer are being used within an article or section
2930     // then it should not be exposed as whole page's banner/contentInfo
2931     if (node && node->hasTagName(headerTag) && !isDescendantOfElementType({ articleTag, sectionTag }))
2932         return AccessibilityRole::LandmarkBanner;
2933
2934     // http://webkit.org/b/190138 Footers should become contentInfo's if scoped to body (and consequently become a landmark).
2935     // It should remain a footer if scoped to main, sectioning elements (article, section) or root sectioning element (blockquote, details, dialog, fieldset, figure, td).
2936     if (node && node->hasTagName(footerTag)) {
2937         if (!isDescendantOfElementType({ articleTag, sectionTag, mainTag, blockquoteTag, detailsTag, fieldsetTag, figureTag, tdTag }))
2938             return AccessibilityRole::LandmarkContentInfo;
2939         return AccessibilityRole::Footer;
2940     }
2941     
2942     // menu tags with toolbar type should have Toolbar role.
2943     if (node && node->hasTagName(menuTag) && equalLettersIgnoringASCIICase(getAttribute(typeAttr), "toolbar"))
2944         return AccessibilityRole::Toolbar;
2945     
2946     if (node && node->hasTagName(timeTag))
2947         return AccessibilityRole::Time;
2948     
2949     // If the element does not have role, but it has ARIA attributes, or accepts tab focus, accessibility should fallback to exposing it as a group.
2950     if (supportsARIAAttributes() || canSetFocusAttribute())
2951         return AccessibilityRole::Group;
2952
2953     if (m_renderer->isRenderBlockFlow())
2954         return m_renderer->isAnonymousBlock() ? AccessibilityRole::TextGroup : AccessibilityRole::Group;
2955     
2956     // InlineRole is the final fallback before assigning AccessibilityRole::Unknown to an object. It makes it
2957     // possible to distinguish truly unknown objects from non-focusable inline text elements
2958     // which have an event handler or attribute suggesting possible inclusion by the platform.
2959     if (is<RenderInline>(*m_renderer)
2960         && (hasAttributesRequiredForInclusion()
2961             || (node && node->hasEventListeners())
2962             || (supportsDatetimeAttribute() && !getAttribute(datetimeAttr).isEmpty())))
2963         return AccessibilityRole::Inline;
2964
2965     return AccessibilityRole::Unknown;
2966 }
2967
2968 AccessibilityOrientation AccessibilityRenderObject::orientation() const
2969 {
2970     const AtomString& ariaOrientation = getAttribute(aria_orientationAttr);
2971     if (equalLettersIgnoringASCIICase(ariaOrientation, "horizontal"))
2972         return AccessibilityOrientation::Horizontal;
2973     if (equalLettersIgnoringASCIICase(ariaOrientation, "vertical"))
2974         return AccessibilityOrientation::Vertical;
2975     if (equalLettersIgnoringASCIICase(ariaOrientation, "undefined"))
2976         return AccessibilityOrientation::Undefined;
2977
2978     // In ARIA 1.1, the implicit value of aria-orientation changed from horizontal
2979     // to undefined on all roles that don't have their own role-specific values. In
2980     // addition, the implicit value of combobox became undefined.
2981     if (isComboBox() || isRadioGroup() || isTreeGrid())
2982         return AccessibilityOrientation::Undefined;
2983
2984     if (isScrollbar() || isListBox() || isMenu() || isTree())
2985         return AccessibilityOrientation::Vertical;
2986     
2987     if (isMenuBar() || isSplitter() || isTabList() || isToolbar() || isSlider())
2988         return AccessibilityOrientation::Horizontal;
2989     
2990     return AccessibilityObject::orientation();
2991 }
2992
2993 bool AccessibilityRenderObject::inheritsPresentationalRole() const
2994 {
2995     // ARIA states if an item can get focus, it should not be presentational.
2996     if (canSetFocusAttribute())
2997         return false;
2998     
2999     // ARIA spec says that when a parent object is presentational, and it has required child elements,
3000     // those child elements are also presentational. For example, <li> becomes presentational from <ul>.
3001     // http://www.w3.org/WAI/PF/aria/complete#presentation
3002
3003     const Vector<const HTMLQualifiedName*>* parentTags;
3004     switch (roleValue()) {
3005     case AccessibilityRole::ListItem:
3006     case AccessibilityRole::ListMarker: {
3007         static const auto listItemParents = makeNeverDestroyed(Vector<const HTMLQualifiedName*> { &dlTag.get(), &olTag.get(), &ulTag.get() });
3008         parentTags = &listItemParents.get();
3009         break;
3010     }
3011     case AccessibilityRole::GridCell:
3012     case AccessibilityRole::Cell: {
3013         static const auto tableCellParents = makeNeverDestroyed(Vector<const HTMLQualifiedName*> { &tableTag.get() });
3014         parentTags = &tableCellParents.get();
3015         break;
3016     }
3017     default:
3018         // Not all elements need to do the following check, only ones that are required children.
3019         return false;
3020     }
3021
3022     for (auto* parent = parentObject(); parent; parent = parent->parentObject()) {
3023         if (!is<AccessibilityRenderObject>(*parent))
3024             continue;
3025
3026         Node* node = downcast<AccessibilityRenderObject>(*parent).node();
3027         if (!is<Element>(node))
3028             continue;
3029
3030         // If native tag of the parent element matches an acceptable name, then return
3031         // based on its presentational status.
3032         auto& name = downcast<Element>(*node).tagQName();
3033         if (std::any_of(parentTags->begin(), parentTags->end(), [&name] (auto* possibleName) { return *possibleName == name; }))
3034             return parent->roleValue() == AccessibilityRole::Presentational;
3035     }
3036
3037     return false;
3038 }
3039     
3040 bool AccessibilityRenderObject::isPresentationalChildOfAriaRole() const
3041 {
3042     // Walk the parent chain looking for a parent that has presentational children
3043     AccessibilityObject* parent;
3044     for (parent = parentObject(); parent && !parent->ariaRoleHasPresentationalChildren(); parent = parent->parentObject())
3045     { }
3046     
3047     return parent;
3048 }
3049     
3050 bool AccessibilityRenderObject::ariaRoleHasPresentationalChildren() const
3051 {
3052     switch (m_ariaRole) {
3053     case AccessibilityRole::Button:
3054     case AccessibilityRole::Slider:
3055     case AccessibilityRole::Image:
3056     case AccessibilityRole::ProgressIndicator:
3057     case AccessibilityRole::SpinButton:
3058     // case SeparatorRole:
3059         return true;
3060     default:
3061         return false;
3062     }
3063 }
3064
3065 bool AccessibilityRenderObject::canSetExpandedAttribute() const
3066 {
3067     if (roleValue() == AccessibilityRole::Details)
3068         return true;
3069     
3070     // An object can be expanded if it aria-expanded is true or false.
3071     const AtomString& expanded = getAttribute(aria_expandedAttr);
3072     if (equalLettersIgnoringASCIICase(expanded, "true") || equalLettersIgnoringASCIICase(expanded, "false"))
3073         return true;
3074     return false;
3075 }
3076
3077 bool AccessibilityRenderObject::canSetTextRangeAttributes() const
3078 {
3079     return isTextControl();
3080 }
3081
3082 void AccessibilityRenderObject::textChanged()
3083 {
3084     // If this element supports ARIA live regions, or is part of a region with an ARIA editable role,
3085     // then notify the AT of changes.
3086     AXObjectCache* cache = axObjectCache();
3087     if (!cache)
3088         return;
3089     
3090     for (RenderObject* renderParent = renderer(); renderParent; renderParent = renderParent->parent()) {
3091         AccessibilityObject* parent = cache->get(renderParent);
3092         if (!parent)
3093             continue;
3094         
3095         if (parent->supportsLiveRegion())
3096             cache->postLiveRegionChangeNotification(parent);
3097
3098         if (parent->isNonNativeTextControl())
3099             cache->postNotification(renderParent, AXObjectCache::AXValueChanged);
3100     }
3101 }
3102
3103 void AccessibilityRenderObject::clearChildren()
3104 {
3105     AccessibilityObject::clearChildren();
3106     m_childrenDirty = false;
3107 }
3108
3109 void AccessibilityRenderObject::addImageMapChildren()
3110 {
3111     RenderBoxModelObject* cssBox = renderBoxModelObject();
3112     if (!is<RenderImage>(cssBox))
3113         return;
3114     
3115     HTMLMapElement* map = downcast<RenderImage>(*cssBox).imageMap();
3116     if (!map)
3117         return;
3118
3119     for (auto& area : descendantsOfType<HTMLAreaElement>(*map)) {
3120         // add an <area> element for this child if it has a link
3121         if (!area.isLink())
3122             continue;
3123         auto& areaObject = downcast<AccessibilityImageMapLink>(*axObjectCache()->create(AccessibilityRole::ImageMapLink));
3124         areaObject.setHTMLAreaElement(&area);
3125         areaObject.setHTMLMapElement(map);
3126         areaObject.setParent(this);
3127         if (!areaObject.accessibilityIsIgnored())
3128             m_children.append(&areaObject);
3129         else
3130             axObjectCache()->remove(areaObject.objectID());
3131     }
3132 }
3133
3134 void AccessibilityRenderObject::updateChildrenIfNecessary()
3135 {
3136     if (needsToUpdateChildren())
3137         clearChildren();
3138     
3139     AccessibilityObject::updateChildrenIfNecessary();
3140 }
3141     
3142 void AccessibilityRenderObject::addTextFieldChildren()
3143 {
3144     Node* node = this->node();
3145     if (!is<HTMLInputElement>(node))
3146         return;
3147     
3148     HTMLInputElement& input = downcast<HTMLInputElement>(*node);
3149     if (HTMLElement* autoFillElement = input.autoFillButtonElement()) {
3150         if (AccessibilityObject* axAutoFill = axObjectCache()->getOrCreate(autoFillElement))
3151             m_children.append(axAutoFill);
3152     }
3153     
3154     HTMLElement* spinButtonElement = input.innerSpinButtonElement();
3155     if (!is<SpinButtonElement>(spinButtonElement))
3156         return;
3157
3158     auto& axSpinButton = downcast<AccessibilitySpinButton>(*axObjectCache()->create(AccessibilityRole::SpinButton));
3159     axSpinButton.setSpinButtonElement(downcast<SpinButtonElement>(spinButtonElement));
3160     axSpinButton.setParent(this);
3161     m_children.append(&axSpinButton);
3162 }
3163     
3164 bool AccessibilityRenderObject::isSVGImage() const
3165 {
3166     return remoteSVGRootElement(Create);
3167 }
3168     
3169 void AccessibilityRenderObject::detachRemoteSVGRoot()
3170 {
3171     if (AccessibilitySVGRoot* root = remoteSVGRootElement(Retrieve))
3172         root->setParent(nullptr);
3173 }
3174
3175 AccessibilitySVGRoot* AccessibilityRenderObject::remoteSVGRootElement(CreationChoice createIfNecessary) const
3176 {
3177     if (!is<RenderImage>(renderer()))
3178         return nullptr;
3179     
3180     CachedImage* cachedImage = downcast<RenderImage>(*m_renderer).cachedImage();
3181     if (!cachedImage)
3182         return nullptr;
3183     
3184     Image* image = cachedImage->image();
3185     if (!is<SVGImage>(image))
3186         return nullptr;
3187     
3188     FrameView* frameView = downcast<SVGImage>(*image).frameView();
3189     if (!frameView)
3190         return nullptr;
3191     Frame& frame = frameView->frame();
3192     
3193     Document* document = frame.document();
3194     if (!is<SVGDocument>(document))
3195         return nullptr;
3196     
3197     auto rootElement = SVGDocument::rootElement(*document);
3198     if (!rootElement)
3199         return nullptr;
3200     RenderObject* rendererRoot = rootElement->renderer();
3201     if (!rendererRoot)
3202         return nullptr;
3203     
3204     AXObjectCache* cache = frame.document()->axObjectCache();
3205     if (!cache)
3206         return nullptr;
3207     AccessibilityObject* rootSVGObject = createIfNecessary == Create ? cache->getOrCreate(rendererRoot) : cache->get(rendererRoot);
3208
3209     // In order to connect the AX hierarchy from the SVG root element from the loaded resource
3210     // the parent must be set, because there's no other way to get back to who created the image.
3211     ASSERT(!createIfNecessary || rootSVGObject);
3212     if (!is<AccessibilitySVGRoot>(rootSVGObject))
3213         return nullptr;
3214     
3215     return downcast<AccessibilitySVGRoot>(rootSVGObject);
3216 }
3217     
3218 void AccessibilityRenderObject::addRemoteSVGChildren()
3219 {
3220     AccessibilitySVGRoot* root = remoteSVGRootElement(Create);
3221     if (!root)
3222         return;
3223     
3224     root->setParent(this);
3225     
3226     if (root->accessibilityIsIgnored()) {
3227         for (const auto& child : root->children())
3228             m_children.append(child);
3229     } else
3230         m_children.append(root);
3231 }
3232
3233 void AccessibilityRenderObject::addCanvasChildren()
3234 {
3235     // Add the unrendered canvas children as AX nodes, unless we're not using a canvas renderer
3236     // because JS is disabled for example.
3237     if (!node() || !node()->hasTagName(canvasTag) || (renderer() && !renderer()->isCanvas()))
3238         return;
3239
3240     // If it's a canvas, it won't have rendered children, but it might have accessible fallback content.
3241     // Clear m_haveChildren because AccessibilityNodeObject::addChildren will expect it to be false.
3242     ASSERT(!m_children.size());
3243     m_haveChildren = false;
3244     AccessibilityNodeObject::addChildren();
3245 }
3246
3247 void AccessibilityRenderObject::addAttachmentChildren()
3248 {
3249     if (!isAttachment())
3250         return;
3251
3252     // FrameView's need to be inserted into the AX hierarchy when encountered.
3253     Widget* widget = widgetForAttachmentView();