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