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