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