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