AX: Recursive crash at WebCore::accessibleNameForNode
[WebKit-https.git] / Source / WebCore / accessibility / AccessibilityNodeObject.cpp
1 /*
2 * Copyright (C) 2012, Google 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 "AccessibilityNodeObject.h"
31
32 #include "AXObjectCache.h"
33 #include "AccessibilityImageMapLink.h"
34 #include "AccessibilityList.h"
35 #include "AccessibilityListBox.h"
36 #include "AccessibilitySpinButton.h"
37 #include "AccessibilityTable.h"
38 #include "ElementIterator.h"
39 #include "EventNames.h"
40 #include "FloatRect.h"
41 #include "Frame.h"
42 #include "FrameLoader.h"
43 #include "FrameSelection.h"
44 #include "FrameView.h"
45 #include "HTMLAreaElement.h"
46 #include "HTMLCanvasElement.h"
47 #include "HTMLFieldSetElement.h"
48 #include "HTMLFormElement.h"
49 #include "HTMLFrameElementBase.h"
50 #include "HTMLImageElement.h"
51 #include "HTMLInputElement.h"
52 #include "HTMLLabelElement.h"
53 #include "HTMLLegendElement.h"
54 #include "HTMLMapElement.h"
55 #include "HTMLNames.h"
56 #include "HTMLOptGroupElement.h"
57 #include "HTMLOptionElement.h"
58 #include "HTMLOptionsCollection.h"
59 #include "HTMLParserIdioms.h"
60 #include "HTMLPlugInImageElement.h"
61 #include "HTMLSelectElement.h"
62 #include "HTMLTextAreaElement.h"
63 #include "HTMLTextFormControlElement.h"
64 #include "HitTestRequest.h"
65 #include "HitTestResult.h"
66 #include "LabelableElement.h"
67 #include "LocalizedStrings.h"
68 #include "MathMLElement.h"
69 #include "MathMLNames.h"
70 #include "NodeList.h"
71 #include "NodeTraversal.h"
72 #include "Page.h"
73 #include "ProgressTracker.h"
74 #include "RenderImage.h"
75 #include "RenderView.h"
76 #include "SVGElement.h"
77 #include "SVGNames.h"
78 #include "Text.h"
79 #include "TextControlInnerElements.h"
80 #include "UserGestureIndicator.h"
81 #include "VisibleUnits.h"
82 #include "Widget.h"
83 #include "htmlediting.h"
84 #include <wtf/StdLibExtras.h>
85 #include <wtf/text/StringBuilder.h>
86 #include <wtf/unicode/CharacterNames.h>
87
88 namespace WebCore {
89
90 using namespace HTMLNames;
91
92 static String accessibleNameForNode(Node* node, Node* labelledbyNode = nullptr);
93
94 AccessibilityNodeObject::AccessibilityNodeObject(Node* node)
95     : AccessibilityObject()
96     , m_ariaRole(UnknownRole)
97     , m_childrenDirty(false)
98     , m_roleForMSAA(UnknownRole)
99 #ifndef NDEBUG
100     , m_initialized(false)
101 #endif
102     , m_node(node)
103 {
104 }
105
106 AccessibilityNodeObject::~AccessibilityNodeObject()
107 {
108     ASSERT(isDetached());
109 }
110
111 void AccessibilityNodeObject::init()
112 {
113 #ifndef NDEBUG
114     ASSERT(!m_initialized);
115     m_initialized = true;
116 #endif
117     m_role = determineAccessibilityRole();
118 }
119
120 PassRefPtr<AccessibilityNodeObject> AccessibilityNodeObject::create(Node* node)
121 {
122     return adoptRef(new AccessibilityNodeObject(node));
123 }
124
125 void AccessibilityNodeObject::detach(AccessibilityDetachmentType detachmentType, AXObjectCache* cache)
126 {
127     // AccessibilityObject calls clearChildren.
128     AccessibilityObject::detach(detachmentType, cache);
129     m_node = nullptr;
130 }
131
132 void AccessibilityNodeObject::childrenChanged()
133 {
134     // This method is meant as a quick way of marking a portion of the accessibility tree dirty.
135     if (!node() && !renderer())
136         return;
137
138     AXObjectCache* cache = axObjectCache();
139     if (!cache)
140         return;
141     cache->postNotification(this, document(), AXObjectCache::AXChildrenChanged);
142
143     // Go up the accessibility parent chain, but only if the element already exists. This method is
144     // called during render layouts, minimal work should be done. 
145     // If AX elements are created now, they could interrogate the render tree while it's in a funky state.
146     // At the same time, process ARIA live region changes.
147     for (AccessibilityObject* parent = this; parent; parent = parent->parentObjectIfExists()) {
148         parent->setNeedsToUpdateChildren();
149
150         // These notifications always need to be sent because screenreaders are reliant on them to perform. 
151         // In other words, they need to be sent even when the screen reader has not accessed this live region since the last update.
152
153         // If this element supports ARIA live regions, then notify the AT of changes.
154         if (parent->supportsARIALiveRegion())
155             cache->postNotification(parent, parent->document(), AXObjectCache::AXLiveRegionChanged);
156         
157         // If this element is an ARIA text control, notify the AT of changes.
158         if ((parent->isARIATextControl() || parent->hasContentEditableAttributeSet()) && !parent->isNativeTextControl())
159             cache->postNotification(parent, parent->document(), AXObjectCache::AXValueChanged);
160     }
161 }
162
163 void AccessibilityNodeObject::updateAccessibilityRole()
164 {
165     bool ignoredStatus = accessibilityIsIgnored();
166     m_role = determineAccessibilityRole();
167     
168     // The AX hierarchy only needs to be updated if the ignored status of an element has changed.
169     if (ignoredStatus != accessibilityIsIgnored())
170         childrenChanged();
171 }
172     
173 AccessibilityObject* AccessibilityNodeObject::firstChild() const
174 {
175     if (!node())
176         return nullptr;
177     
178     Node* firstChild = node()->firstChild();
179
180     if (!firstChild)
181         return nullptr;
182     
183     return axObjectCache()->getOrCreate(firstChild);
184 }
185
186 AccessibilityObject* AccessibilityNodeObject::lastChild() const
187 {
188     if (!node())
189         return nullptr;
190     
191     Node* lastChild = node()->lastChild();
192     if (!lastChild)
193         return nullptr;
194     
195     return axObjectCache()->getOrCreate(lastChild);
196 }
197
198 AccessibilityObject* AccessibilityNodeObject::previousSibling() const
199 {
200     if (!node())
201         return nullptr;
202
203     Node* previousSibling = node()->previousSibling();
204     if (!previousSibling)
205         return nullptr;
206
207     return axObjectCache()->getOrCreate(previousSibling);
208 }
209
210 AccessibilityObject* AccessibilityNodeObject::nextSibling() const
211 {
212     if (!node())
213         return nullptr;
214
215     Node* nextSibling = node()->nextSibling();
216     if (!nextSibling)
217         return nullptr;
218
219     return axObjectCache()->getOrCreate(nextSibling);
220 }
221     
222 AccessibilityObject* AccessibilityNodeObject::parentObjectIfExists() const
223 {
224     return parentObject();
225 }
226     
227 AccessibilityObject* AccessibilityNodeObject::parentObject() const
228 {
229     if (!node())
230         return nullptr;
231
232     Node* parentObj = node()->parentNode();
233     if (!parentObj)
234         return nullptr;
235     
236     if (AXObjectCache* cache = axObjectCache())
237         return cache->getOrCreate(parentObj);
238     
239     return nullptr;
240 }
241
242 LayoutRect AccessibilityNodeObject::elementRect() const
243 {
244     return boundingBoxRect();
245 }
246     
247 LayoutRect AccessibilityNodeObject::boundingBoxRect() const
248 {
249     // AccessibilityNodeObjects have no mechanism yet to return a size or position.
250     // For now, let's return the position of the ancestor that does have a position,
251     // and make it the width of that parent, and about the height of a line of text, so that it's clear the object is a child of the parent.
252     
253     LayoutRect boundingBox;
254     
255     for (AccessibilityObject* positionProvider = parentObject(); positionProvider; positionProvider = positionProvider->parentObject()) {
256         if (positionProvider->isAccessibilityRenderObject()) {
257             LayoutRect parentRect = positionProvider->elementRect();
258             boundingBox.setSize(LayoutSize(parentRect.width(), LayoutUnit(std::min(10.0f, parentRect.height().toFloat()))));
259             boundingBox.setLocation(parentRect.location());
260             break;
261         }
262     }
263     
264     return boundingBox;
265 }
266
267 void AccessibilityNodeObject::setNode(Node* node)
268 {
269     m_node = node;
270 }
271
272 Document* AccessibilityNodeObject::document() const
273 {
274     if (!node())
275         return nullptr;
276     return &node()->document();
277 }
278
279 AccessibilityRole AccessibilityNodeObject::determineAccessibilityRole()
280 {
281     if (!node())
282         return UnknownRole;
283
284     if ((m_ariaRole = determineAriaRoleAttribute()) != UnknownRole)
285         return m_ariaRole;
286     
287     if (node()->isLink())
288         return WebCoreLinkRole;
289     if (node()->isTextNode())
290         return StaticTextRole;
291     if (node()->hasTagName(buttonTag))
292         return buttonRoleType();
293     if (is<HTMLInputElement>(*node())) {
294         HTMLInputElement& input = downcast<HTMLInputElement>(*node());
295         if (input.isCheckbox())
296             return CheckBoxRole;
297         if (input.isRadioButton())
298             return RadioButtonRole;
299         if (input.isTextButton())
300             return buttonRoleType();
301         if (input.isRangeControl())
302             return SliderRole;
303         if (input.isInputTypeHidden())
304             return IgnoredRole;
305         
306 #if ENABLE(INPUT_TYPE_COLOR)
307         const AtomicString& type = input.getAttribute(typeAttr);
308         if (equalIgnoringCase(type, "color"))
309             return ColorWellRole;
310 #endif
311
312         return TextFieldRole;
313     }
314     if (node()->hasTagName(selectTag)) {
315         HTMLSelectElement& selectElement = downcast<HTMLSelectElement>(*node());
316         return selectElement.multiple() ? ListBoxRole : PopUpButtonRole;
317     }
318     if (is<HTMLTextAreaElement>(*node()))
319         return TextAreaRole;
320     if (headingLevel())
321         return HeadingRole;
322     if (node()->hasTagName(blockquoteTag))
323         return BlockquoteRole;
324     if (node()->hasTagName(divTag))
325         return DivRole;
326     if (node()->hasTagName(pTag))
327         return ParagraphRole;
328     if (is<HTMLLabelElement>(*node()))
329         return LabelRole;
330     if (is<Element>(*node()) && downcast<Element>(*node()).isFocusable())
331         return GroupRole;
332     
333     return UnknownRole;
334 }
335
336 void AccessibilityNodeObject::insertChild(AccessibilityObject* child, unsigned index)
337 {
338     if (!child)
339         return;
340     
341     // If the parent is asking for this child's children, then either it's the first time (and clearing is a no-op),
342     // or its visibility has changed. In the latter case, this child may have a stale child cached.
343     // This can prevent aria-hidden changes from working correctly. Hence, whenever a parent is getting children, ensure data is not stale.
344     child->clearChildren();
345     
346     if (child->accessibilityIsIgnored()) {
347         const auto& children = child->children();
348         size_t length = children.size();
349         for (size_t i = 0; i < length; ++i)
350             m_children.insert(index + i, children[i]);
351     } else {
352         ASSERT(child->parentObject() == this);
353         m_children.insert(index, child);
354     }
355 }
356
357 void AccessibilityNodeObject::addChild(AccessibilityObject* child)
358 {
359     insertChild(child, m_children.size());
360 }
361
362 void AccessibilityNodeObject::addChildren()
363 {
364     // If the need to add more children in addition to existing children arises, 
365     // childrenChanged should have been called, leaving the object with no children.
366     ASSERT(!m_haveChildren); 
367     
368     if (!m_node)
369         return;
370
371     m_haveChildren = true;
372
373     // The only time we add children from the DOM tree to a node with a renderer is when it's a canvas.
374     if (renderer() && !m_node->hasTagName(canvasTag))
375         return;
376     
377     for (Node* child = m_node->firstChild(); child; child = child->nextSibling())
378         addChild(axObjectCache()->getOrCreate(child));
379 }
380
381 bool AccessibilityNodeObject::canHaveChildren() const
382 {
383     // If this is an AccessibilityRenderObject, then it's okay if this object
384     // doesn't have a node - there are some renderers that don't have associated
385     // nodes, like scroll areas and css-generated text.
386     if (!node() && !isAccessibilityRenderObject())
387         return false;
388
389     // When <noscript> is not being used (its renderer() == 0), ignore its children.
390     if (node() && !renderer() && node()->hasTagName(noscriptTag))
391         return false;
392     
393     // Elements that should not have children
394     switch (roleValue()) {
395     case ImageRole:
396     case ButtonRole:
397     case PopUpButtonRole:
398     case CheckBoxRole:
399     case RadioButtonRole:
400     case TabRole:
401     case ToggleButtonRole:
402     case StaticTextRole:
403     case ListBoxOptionRole:
404     case ScrollBarRole:
405     case ProgressIndicatorRole:
406         return false;
407     default:
408         return true;
409     }
410 }
411
412 bool AccessibilityNodeObject::computeAccessibilityIsIgnored() const
413 {
414 #ifndef NDEBUG
415     // Double-check that an AccessibilityObject is never accessed before
416     // it's been initialized.
417     ASSERT(m_initialized);
418 #endif
419
420     // Handle non-rendered text that is exposed through aria-hidden=false.
421     if (m_node && m_node->isTextNode() && !renderer()) {
422         // Fallback content in iframe nodes should be ignored.
423         if (m_node->parentNode() && m_node->parentNode()->hasTagName(iframeTag) && m_node->parentNode()->renderer())
424             return true;
425
426         // Whitespace only text elements should be ignored when they have no renderer.
427         String string = stringValue().stripWhiteSpace().simplifyWhiteSpace();
428         if (!string.length())
429             return true;
430     }
431
432     AccessibilityObjectInclusion decision = defaultObjectInclusion();
433     if (decision == IncludeObject)
434         return false;
435     if (decision == IgnoreObject)
436         return true;
437     // If this element is within a parent that cannot have children, it should not be exposed.
438     if (isDescendantOfBarrenParent())
439         return true;
440
441     if (roleValue() == IgnoredRole)
442         return true;
443     
444     return m_role == UnknownRole;
445 }
446
447 bool AccessibilityNodeObject::canvasHasFallbackContent() const
448 {
449     Node* node = this->node();
450     if (!is<HTMLCanvasElement>(node))
451         return false;
452     HTMLCanvasElement& canvasElement = downcast<HTMLCanvasElement>(*node);
453     // If it has any children that are elements, we'll assume it might be fallback
454     // content. If it has no children or its only children are not elements
455     // (e.g. just text nodes), it doesn't have fallback content.
456     return childrenOfType<Element>(canvasElement).first();
457 }
458
459 bool AccessibilityNodeObject::isImageButton() const
460 {
461     return isNativeImage() && isButton();
462 }
463
464 bool AccessibilityNodeObject::isNativeTextControl() const
465 {
466     Node* node = this->node();
467     if (!node)
468         return false;
469
470     if (is<HTMLTextAreaElement>(*node))
471         return true;
472
473     if (is<HTMLInputElement>(*node)) {
474         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
475         return input.isText() || input.isNumberField();
476     }
477
478     return false;
479 }
480
481 bool AccessibilityNodeObject::isSearchField() const
482 {
483     Node* node = this->node();
484     if (!node)
485         return false;
486
487     HTMLInputElement* inputElement = node->toInputElement();
488     if (!inputElement)
489         return false;
490
491     if (inputElement->isSearchField())
492         return true;
493
494     // Some websites don't label their search fields as such. However, they will
495     // use the word "search" in either the form or input type. This won't catch every case,
496     // but it will catch google.com for example.
497
498     // Check the node name of the input type, sometimes it's "search".
499     const AtomicString& nameAttribute = getAttribute(nameAttr);
500     if (nameAttribute.contains("search", false))
501         return true;
502
503     // Check the form action and the name, which will sometimes be "search".
504     HTMLFormElement* form = inputElement->form();
505     if (form && (form->name().contains("search", false) || form->action().contains("search", false)))
506         return true;
507
508     return false;
509 }
510
511 bool AccessibilityNodeObject::isNativeImage() const
512 {
513     Node* node = this->node();
514     if (!node)
515         return false;
516
517     if (is<HTMLImageElement>(*node))
518         return true;
519
520     if (node->hasTagName(appletTag) || node->hasTagName(embedTag) || node->hasTagName(objectTag))
521         return true;
522
523     if (is<HTMLInputElement>(*node)) {
524         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
525         return input.isImageButton();
526     }
527
528     return false;
529 }
530
531 bool AccessibilityNodeObject::isImage() const
532 {
533     return roleValue() == ImageRole;
534 }
535
536 bool AccessibilityNodeObject::isPasswordField() const
537 {
538     Node* node = this->node();
539     if (!node || !node->isHTMLElement())
540         return false;
541
542     if (ariaRoleAttribute() != UnknownRole)
543         return false;
544
545     HTMLInputElement* inputElement = node->toInputElement();
546     if (!inputElement)
547         return false;
548
549     return inputElement->isPasswordField();
550 }
551
552 bool AccessibilityNodeObject::isInputImage() const
553 {
554     Node* node = this->node();
555     if (is<HTMLInputElement>(node) && roleValue() == ButtonRole) {
556         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
557         return input.isImageButton();
558     }
559
560     return false;
561 }
562
563 bool AccessibilityNodeObject::isProgressIndicator() const
564 {
565     return roleValue() == ProgressIndicatorRole;
566 }
567
568 bool AccessibilityNodeObject::isSlider() const
569 {
570     return roleValue() == SliderRole;
571 }
572
573 bool AccessibilityNodeObject::isMenuRelated() const
574 {
575     switch (roleValue()) {
576     case MenuRole:
577     case MenuBarRole:
578     case MenuButtonRole:
579     case MenuItemRole:
580     case MenuItemCheckboxRole:
581     case MenuItemRadioRole:
582         return true;
583     default:
584         return false;
585     }
586 }
587
588 bool AccessibilityNodeObject::isMenu() const
589 {
590     return roleValue() == MenuRole;
591 }
592
593 bool AccessibilityNodeObject::isMenuBar() const
594 {
595     return roleValue() == MenuBarRole;
596 }
597
598 bool AccessibilityNodeObject::isMenuButton() const
599 {
600     return roleValue() == MenuButtonRole;
601 }
602
603 bool AccessibilityNodeObject::isMenuItem() const
604 {
605     switch (roleValue()) {
606     case MenuItemRole:
607     case MenuItemRadioRole:
608     case MenuItemCheckboxRole:
609         return true;
610     default:
611         return false;
612     }
613 }
614
615 bool AccessibilityNodeObject::isNativeCheckboxOrRadio() const
616 {
617     Node* node = this->node();
618     if (!node)
619         return false;
620
621     HTMLInputElement* input = node->toInputElement();
622     if (input)
623         return input->isCheckbox() || input->isRadioButton();
624
625     return false;
626 }
627
628 bool AccessibilityNodeObject::isEnabled() const
629 {
630     // ARIA says that the disabled status applies to the current element and all descendant elements.
631     for (AccessibilityObject* object = const_cast<AccessibilityNodeObject*>(this); object; object = object->parentObject()) {
632         const AtomicString& disabledStatus = object->getAttribute(aria_disabledAttr);
633         if (equalIgnoringCase(disabledStatus, "true"))
634             return false;
635         if (equalIgnoringCase(disabledStatus, "false"))
636             break;
637     }
638     
639     if (roleValue() == HorizontalRuleRole)
640         return false;
641     
642     Node* node = this->node();
643     if (!is<Element>(node))
644         return true;
645
646     return !downcast<Element>(*node).isDisabledFormControl();
647 }
648
649 bool AccessibilityNodeObject::isIndeterminate() const
650 {
651     Node* node = this->node();
652     if (!node)
653         return false;
654
655     HTMLInputElement* inputElement = node->toInputElement();
656     if (!inputElement)
657         return false;
658
659     return inputElement->shouldAppearIndeterminate();
660 }
661
662 bool AccessibilityNodeObject::isPressed() const
663 {
664     if (!isButton())
665         return false;
666
667     Node* node = this->node();
668     if (!node)
669         return false;
670
671     // If this is an ARIA button, check the aria-pressed attribute rather than node()->active()
672     if (ariaRoleAttribute() == ButtonRole) {
673         if (equalIgnoringCase(getAttribute(aria_pressedAttr), "true"))
674             return true;
675         return false;
676     }
677
678     if (!is<Element>(*node))
679         return false;
680     return downcast<Element>(*node).active();
681 }
682
683 bool AccessibilityNodeObject::isChecked() const
684 {
685     Node* node = this->node();
686     if (!node)
687         return false;
688
689     // First test for native checkedness semantics
690     HTMLInputElement* inputElement = node->toInputElement();
691     if (inputElement)
692         return inputElement->shouldAppearChecked();
693
694     // Else, if this is an ARIA checkbox or radio, respect the aria-checked attribute
695     bool validRole = false;
696     switch (ariaRoleAttribute()) {
697     case RadioButtonRole:
698     case CheckBoxRole:
699     case MenuItemRole:
700     case MenuItemCheckboxRole:
701     case MenuItemRadioRole:
702         validRole = true;
703         break;
704     default:
705         break;
706     }
707     
708     if (validRole && equalIgnoringCase(getAttribute(aria_checkedAttr), "true"))
709         return true;
710
711     return false;
712 }
713
714 bool AccessibilityNodeObject::isHovered() const
715 {
716     Node* node = this->node();
717     return is<Element>(node) && downcast<Element>(*node).hovered();
718 }
719
720 bool AccessibilityNodeObject::isMultiSelectable() const
721 {
722     const AtomicString& ariaMultiSelectable = getAttribute(aria_multiselectableAttr);
723     if (equalIgnoringCase(ariaMultiSelectable, "true"))
724         return true;
725     if (equalIgnoringCase(ariaMultiSelectable, "false"))
726         return false;
727     
728     return node() && node()->hasTagName(selectTag) && downcast<HTMLSelectElement>(*node()).multiple();
729 }
730
731 bool AccessibilityNodeObject::isReadOnly() const
732 {
733     Node* node = this->node();
734     if (!node)
735         return true;
736
737     if (is<HTMLTextAreaElement>(*node))
738         return downcast<HTMLTextAreaElement>(*node).isReadOnly();
739
740     if (is<HTMLInputElement>(*node)) {
741         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
742         if (input.isTextField())
743             return input.isReadOnly();
744     }
745
746     return !node->hasEditableStyle();
747 }
748
749 bool AccessibilityNodeObject::isRequired() const
750 {
751     // Explicit aria-required values should trump native required attributes.
752     const AtomicString& requiredValue = getAttribute(aria_requiredAttr);
753     if (equalIgnoringCase(requiredValue, "true"))
754         return true;
755     if (equalIgnoringCase(requiredValue, "false"))
756         return false;
757
758     Node* n = this->node();
759     if (is<HTMLFormControlElement>(n))
760         return downcast<HTMLFormControlElement>(*n).isRequired();
761
762     return false;
763 }
764
765 bool AccessibilityNodeObject::supportsRequiredAttribute() const
766 {
767     switch (roleValue()) {
768     case ButtonRole:
769         return isFileUploadButton();
770     case CellRole:
771     case CheckBoxRole:
772     case ComboBoxRole:
773     case GridRole:
774     case IncrementorRole:
775     case ListBoxRole:
776     case PopUpButtonRole:
777     case RadioButtonRole:
778     case RadioGroupRole:
779     case RowHeaderRole:
780     case SliderRole:
781     case SpinButtonRole:
782     case TableHeaderContainerRole:
783     case TextAreaRole:
784     case TextFieldRole:
785     case ToggleButtonRole:
786         return true;
787     default:
788         return false;
789     }
790 }
791
792 int AccessibilityNodeObject::headingLevel() const
793 {
794     // headings can be in block flow and non-block flow
795     Node* node = this->node();
796     if (!node)
797         return false;
798
799     if (isHeading()) {
800         int ariaLevel = getAttribute(aria_levelAttr).toInt();
801         if (ariaLevel > 0)
802             return ariaLevel;
803     }
804
805     if (node->hasTagName(h1Tag))
806         return 1;
807
808     if (node->hasTagName(h2Tag))
809         return 2;
810
811     if (node->hasTagName(h3Tag))
812         return 3;
813
814     if (node->hasTagName(h4Tag))
815         return 4;
816
817     if (node->hasTagName(h5Tag))
818         return 5;
819
820     if (node->hasTagName(h6Tag))
821         return 6;
822
823     return 0;
824 }
825
826 String AccessibilityNodeObject::valueDescription() const
827 {
828     if (!isRangeControl())
829         return String();
830
831     return getAttribute(aria_valuetextAttr).string();
832 }
833
834 float AccessibilityNodeObject::valueForRange() const
835 {
836     if (is<HTMLInputElement>(node())) {
837         HTMLInputElement& input = downcast<HTMLInputElement>(*node());
838         if (input.isRangeControl())
839             return input.valueAsNumber();
840     }
841
842     if (!isRangeControl())
843         return 0.0f;
844
845     return getAttribute(aria_valuenowAttr).toFloat();
846 }
847
848 float AccessibilityNodeObject::maxValueForRange() const
849 {
850     if (is<HTMLInputElement>(node())) {
851         HTMLInputElement& input = downcast<HTMLInputElement>(*node());
852         if (input.isRangeControl())
853             return input.maximum();
854     }
855
856     if (!isRangeControl())
857         return 0.0f;
858
859     return getAttribute(aria_valuemaxAttr).toFloat();
860 }
861
862 float AccessibilityNodeObject::minValueForRange() const
863 {
864     if (is<HTMLInputElement>(node())) {
865         HTMLInputElement& input = downcast<HTMLInputElement>(*node());
866         if (input.isRangeControl())
867             return input.minimum();
868     }
869
870     if (!isRangeControl())
871         return 0.0f;
872
873     return getAttribute(aria_valueminAttr).toFloat();
874 }
875
876 float AccessibilityNodeObject::stepValueForRange() const
877 {
878     return getAttribute(stepAttr).toFloat();
879 }
880
881 bool AccessibilityNodeObject::isHeading() const
882 {
883     return roleValue() == HeadingRole;
884 }
885
886 bool AccessibilityNodeObject::isLink() const
887 {
888     return roleValue() == WebCoreLinkRole;
889 }
890
891 bool AccessibilityNodeObject::isControl() const
892 {
893     Node* node = this->node();
894     if (!node)
895         return false;
896
897     return is<HTMLFormControlElement>(*node) || AccessibilityObject::isARIAControl(ariaRoleAttribute());
898 }
899
900 bool AccessibilityNodeObject::isFieldset() const
901 {
902     Node* node = this->node();
903     if (!node)
904         return false;
905
906     return node->hasTagName(fieldsetTag);
907 }
908
909 bool AccessibilityNodeObject::isGroup() const
910 {
911     return roleValue() == GroupRole;
912 }
913
914 AccessibilityObject* AccessibilityNodeObject::selectedRadioButton()
915 {
916     if (!isRadioGroup())
917         return nullptr;
918
919     // Find the child radio button that is selected (ie. the intValue == 1).
920     for (const auto& child : children()) {
921         if (child->roleValue() == RadioButtonRole && child->checkboxOrRadioValue() == ButtonStateOn)
922             return child.get();
923     }
924     return nullptr;
925 }
926
927 AccessibilityObject* AccessibilityNodeObject::selectedTabItem()
928 {
929     if (!isTabList())
930         return nullptr;
931
932     // Find the child tab item that is selected (ie. the intValue == 1).
933     AccessibilityObject::AccessibilityChildrenVector tabs;
934     tabChildren(tabs);
935
936     for (const auto& child : children()) {
937         if (child->isTabItem() && child->isChecked())
938             return child.get();
939     }
940     return nullptr;
941 }
942
943 AccessibilityButtonState AccessibilityNodeObject::checkboxOrRadioValue() const
944 {
945     if (isNativeCheckboxOrRadio())
946         return isChecked() ? ButtonStateOn : ButtonStateOff;
947
948     return AccessibilityObject::checkboxOrRadioValue();
949 }
950
951 Element* AccessibilityNodeObject::anchorElement() const
952 {
953     Node* node = this->node();
954     if (!node)
955         return nullptr;
956
957     AXObjectCache* cache = axObjectCache();
958
959     // search up the DOM tree for an anchor element
960     // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
961     for ( ; node; node = node->parentNode()) {
962         if (is<HTMLAnchorElement>(*node) || (node->renderer() && cache->getOrCreate(node->renderer())->isLink()))
963             return downcast<Element>(node);
964     }
965
966     return nullptr;
967 }
968
969 static bool isNodeActionElement(Node* node)
970 {
971     if (is<HTMLInputElement>(*node)) {
972         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
973         if (!input.isDisabledFormControl() && (input.isRadioButton() || input.isCheckbox() || input.isTextButton() || input.isFileUpload() || input.isImageButton()))
974             return true;
975     } else if (node->hasTagName(buttonTag) || node->hasTagName(selectTag))
976         return true;
977
978     return false;
979 }
980     
981 static Element* nativeActionElement(Node* start)
982 {
983     if (!start)
984         return nullptr;
985     
986     // Do a deep-dive to see if any nodes should be used as the action element.
987     // We have to look at Nodes, since this method should only be called on objects that do not have children (like buttons).
988     // It solves the problem when authors put role="button" on a group and leave the actual button inside the group.
989     
990     for (Node* child = start->firstChild(); child; child = child->nextSibling()) {
991         if (isNodeActionElement(child))
992             return downcast<Element>(child);
993
994         if (Element* subChild = nativeActionElement(child))
995             return subChild;
996     }
997     return nullptr;
998 }
999     
1000 Element* AccessibilityNodeObject::actionElement() const
1001 {
1002     Node* node = this->node();
1003     if (!node)
1004         return nullptr;
1005
1006     if (isNodeActionElement(node))
1007         return downcast<Element>(node);
1008     
1009     if (AccessibilityObject::isARIAInput(ariaRoleAttribute()))
1010         return downcast<Element>(node);
1011
1012     switch (roleValue()) {
1013     case ButtonRole:
1014     case PopUpButtonRole:
1015     case ToggleButtonRole:
1016     case TabRole:
1017     case MenuItemRole:
1018     case MenuItemCheckboxRole:
1019     case MenuItemRadioRole:
1020     case ListItemRole:
1021         // Check if the author is hiding the real control element inside the ARIA element.
1022         if (Element* nativeElement = nativeActionElement(node))
1023             return nativeElement;
1024         return downcast<Element>(node);
1025     default:
1026         break;
1027     }
1028     
1029     Element* elt = anchorElement();
1030     if (!elt)
1031         elt = mouseButtonListener();
1032     return elt;
1033 }
1034
1035 Element* AccessibilityNodeObject::mouseButtonListener(MouseButtonListenerResultFilter filter) const
1036 {
1037     Node* node = this->node();
1038     if (!node)
1039         return nullptr;
1040
1041     // check if our parent is a mouse button listener
1042     // FIXME: Do the continuation search like anchorElement does
1043     for (auto& element : elementLineage(is<Element>(*node) ? downcast<Element>(node) : node->parentElement())) {
1044         // If we've reached the body and this is not a control element, do not expose press action for this element unless filter is IncludeBodyElement.
1045         // It can cause false positives, where every piece of text is labeled as accepting press actions.
1046         if (element.hasTagName(bodyTag) && isStaticText() && filter == ExcludeBodyElement)
1047             break;
1048         
1049         if (element.hasEventListeners(eventNames().clickEvent) || element.hasEventListeners(eventNames().mousedownEvent) || element.hasEventListeners(eventNames().mouseupEvent))
1050             return &element;
1051     }
1052
1053     return nullptr;
1054 }
1055
1056 bool AccessibilityNodeObject::isDescendantOfBarrenParent() const
1057 {
1058     for (AccessibilityObject* object = parentObject(); object; object = object->parentObject()) {
1059         if (!object->canHaveChildren())
1060             return true;
1061     }
1062
1063     return false;
1064 }
1065
1066 void AccessibilityNodeObject::alterSliderValue(bool increase)
1067 {
1068     if (roleValue() != SliderRole)
1069         return;
1070
1071     if (!getAttribute(stepAttr).isEmpty())
1072         changeValueByStep(increase);
1073     else
1074         changeValueByPercent(increase ? 5 : -5);
1075 }
1076     
1077 void AccessibilityNodeObject::increment()
1078 {
1079     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, document());
1080     alterSliderValue(true);
1081 }
1082
1083 void AccessibilityNodeObject::decrement()
1084 {
1085     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, document());
1086     alterSliderValue(false);
1087 }
1088
1089 void AccessibilityNodeObject::changeValueByStep(bool increase)
1090 {
1091     float step = stepValueForRange();
1092     float value = valueForRange();
1093
1094     value += increase ? step : -step;
1095
1096     setValue(String::number(value));
1097
1098     axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged);
1099 }
1100
1101 void AccessibilityNodeObject::changeValueByPercent(float percentChange)
1102 {
1103     float range = maxValueForRange() - minValueForRange();
1104     float step = range * (percentChange / 100);
1105     float value = valueForRange();
1106
1107     // Make sure the specified percent will cause a change of one integer step or larger.
1108     if (fabs(step) < 1)
1109         step = fabs(percentChange) * (1 / percentChange);
1110
1111     value += step;
1112     setValue(String::number(value));
1113
1114     axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged);
1115 }
1116
1117 bool AccessibilityNodeObject::isGenericFocusableElement() const
1118 {
1119     if (!canSetFocusAttribute())
1120         return false;
1121
1122     // If it's a control, it's not generic.
1123     if (isControl())
1124         return false;
1125     
1126     AccessibilityRole role = roleValue();
1127     if (role == VideoRole || role == AudioRole)
1128         return false;
1129
1130     // If it has an aria role, it's not generic.
1131     if (m_ariaRole != UnknownRole)
1132         return false;
1133
1134     // If the content editable attribute is set on this element, that's the reason
1135     // it's focusable, and existing logic should handle this case already - so it's not a
1136     // generic focusable element.
1137
1138     if (hasContentEditableAttributeSet())
1139         return false;
1140
1141     // The web area and body element are both focusable, but existing logic handles these
1142     // cases already, so we don't need to include them here.
1143     if (role == WebAreaRole)
1144         return false;
1145     if (node() && node()->hasTagName(bodyTag))
1146         return false;
1147
1148     // An SVG root is focusable by default, but it's probably not interactive, so don't
1149     // include it. It can still be made accessible by giving it an ARIA role.
1150     if (role == SVGRootRole)
1151         return false;
1152
1153     return true;
1154 }
1155
1156 HTMLLabelElement* AccessibilityNodeObject::labelForElement(Element* element) const
1157 {
1158     if (!is<HTMLElement>(*element) || !downcast<HTMLElement>(*element).isLabelable())
1159         return nullptr;
1160
1161     const AtomicString& id = element->getIdAttribute();
1162     if (!id.isEmpty()) {
1163         if (HTMLLabelElement* label = element->treeScope().labelElementForId(id))
1164             return label;
1165     }
1166
1167     return ancestorsOfType<HTMLLabelElement>(*element).first();
1168 }
1169
1170 String AccessibilityNodeObject::ariaAccessibilityDescription() const
1171 {
1172     String ariaLabeledBy = ariaLabeledByAttribute();
1173     if (!ariaLabeledBy.isEmpty())
1174         return ariaLabeledBy;
1175
1176     const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
1177     if (!ariaLabel.isEmpty())
1178         return ariaLabel;
1179
1180     return String();
1181 }
1182
1183 static Element* siblingWithAriaRole(String role, Node* node)
1184 {
1185     ContainerNode* parent = node->parentNode();
1186     if (!parent)
1187         return nullptr;
1188
1189     for (auto& sibling : childrenOfType<Element>(*parent)) {
1190         const AtomicString& siblingAriaRole = sibling.fastGetAttribute(roleAttr);
1191         if (equalIgnoringCase(siblingAriaRole, role))
1192             return &sibling;
1193     }
1194
1195     return nullptr;
1196 }
1197
1198 Element* AccessibilityNodeObject::menuElementForMenuButton() const
1199 {
1200     if (ariaRoleAttribute() != MenuButtonRole)
1201         return nullptr;
1202
1203     return siblingWithAriaRole("menu", node());
1204 }
1205
1206 AccessibilityObject* AccessibilityNodeObject::menuForMenuButton() const
1207 {
1208     if (AXObjectCache* cache = axObjectCache())
1209         return cache->getOrCreate(menuElementForMenuButton());
1210     return nullptr;
1211 }
1212
1213 Element* AccessibilityNodeObject::menuItemElementForMenu() const
1214 {
1215     if (ariaRoleAttribute() != MenuRole)
1216         return nullptr;
1217     
1218     return siblingWithAriaRole("menuitem", node());    
1219 }
1220
1221 AccessibilityObject* AccessibilityNodeObject::menuButtonForMenu() const
1222 {
1223     AXObjectCache* cache = axObjectCache();
1224     if (!cache)
1225         return nullptr;
1226
1227     Element* menuItem = menuItemElementForMenu();
1228
1229     if (menuItem) {
1230         // ARIA just has generic menu items. AppKit needs to know if this is a top level items like MenuBarButton or MenuBarItem
1231         AccessibilityObject* menuItemAX = cache->getOrCreate(menuItem);
1232         if (menuItemAX && menuItemAX->isMenuButton())
1233             return menuItemAX;
1234     }
1235     return nullptr;
1236 }
1237
1238 bool AccessibilityNodeObject::usesAltTagForTextComputation() const
1239 {
1240     return isImage() || isInputImage() || isNativeImage() || isCanvas() || (node() && node()->hasTagName(imgTag));
1241 }
1242     
1243 void AccessibilityNodeObject::titleElementText(Vector<AccessibilityText>& textOrder) const
1244 {
1245     Node* node = this->node();
1246     if (!node)
1247         return;
1248     
1249     bool isInputTag = is<HTMLInputElement>(*node);
1250     if (isInputTag || AccessibilityObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
1251         if (HTMLLabelElement* label = labelForElement(downcast<Element>(node))) {
1252             AccessibilityObject* labelObject = axObjectCache()->getOrCreate(label);
1253             String innerText = label->innerText();
1254             // Only use the <label> text if there's no ARIA override.
1255             if (!innerText.isEmpty() && !ariaAccessibilityDescription())
1256                 textOrder.append(AccessibilityText(innerText, LabelByElementText, labelObject));
1257             return;
1258         }
1259     }
1260     
1261     AccessibilityObject* titleUIElement = this->titleUIElement();
1262     if (titleUIElement)
1263         textOrder.append(AccessibilityText(String(), LabelByElementText, titleUIElement));
1264 }
1265
1266 void AccessibilityNodeObject::alternativeText(Vector<AccessibilityText>& textOrder) const
1267 {
1268     if (isWebArea()) {
1269         String webAreaText = alternativeTextForWebArea();
1270         if (!webAreaText.isEmpty())
1271             textOrder.append(AccessibilityText(webAreaText, AlternativeText));
1272         return;
1273     }
1274     
1275     ariaLabeledByText(textOrder);
1276     
1277     const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
1278     if (!ariaLabel.isEmpty())
1279         textOrder.append(AccessibilityText(ariaLabel, AlternativeText));
1280     
1281     if (usesAltTagForTextComputation()) {
1282         if (is<RenderImage>(renderer())) {
1283             String renderAltText = downcast<RenderImage>(*renderer()).altText();
1284
1285             // RenderImage will return title as a fallback from altText, but we don't want title here because we consider that in helpText.
1286             if (!renderAltText.isEmpty() && renderAltText != getAttribute(titleAttr)) {
1287                 textOrder.append(AccessibilityText(renderAltText, AlternativeText));
1288                 return;
1289             }
1290         }
1291         // Images should use alt as long as the attribute is present, even if empty.
1292         // Otherwise, it should fallback to other methods, like the title attribute.
1293         const AtomicString& alt = getAttribute(altAttr);
1294         if (!alt.isEmpty())
1295             textOrder.append(AccessibilityText(alt, AlternativeText));
1296     }
1297     
1298     Node* node = this->node();
1299     if (!node)
1300         return;
1301     
1302     // The fieldset element derives its alternative text from the first associated legend element if one is available.
1303     if (is<HTMLFieldSetElement>(*node)) {
1304         AccessibilityObject* object = axObjectCache()->getOrCreate(downcast<HTMLFieldSetElement>(*node).legend());
1305         if (object && !object->isHidden())
1306             textOrder.append(AccessibilityText(accessibleNameForNode(object->node()), AlternativeText));
1307     }
1308     
1309     // SVG elements all can have a <svg:title> element inside which should act as the descriptive text.
1310     if (node->isSVGElement())
1311         textOrder.append(AccessibilityText(downcast<SVGElement>(*node).title(), AlternativeText));
1312     
1313 #if ENABLE(MATHML)
1314     if (node->isMathMLElement())
1315         textOrder.append(AccessibilityText(getAttribute(MathMLNames::alttextAttr), AlternativeText));
1316 #endif
1317 }
1318
1319 void AccessibilityNodeObject::visibleText(Vector<AccessibilityText>& textOrder) const
1320 {
1321     Node* node = this->node();
1322     if (!node)
1323         return;
1324     
1325     bool isInputTag = is<HTMLInputElement>(*node);
1326     if (isInputTag) {
1327         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
1328         if (input.isTextButton()) {
1329             textOrder.append(AccessibilityText(input.valueWithDefault(), VisibleText));
1330             return;
1331         }
1332     }
1333     
1334     // If this node isn't rendered, there's no inner text we can extract from a select element.
1335     if (!isAccessibilityRenderObject() && node->hasTagName(selectTag))
1336         return;
1337     
1338     bool useTextUnderElement = false;
1339     
1340     switch (roleValue()) {
1341     case PopUpButtonRole:
1342         // Native popup buttons should not use their button children's text as a title. That value is retrieved through stringValue().
1343         if (node->hasTagName(selectTag))
1344             break;
1345         FALLTHROUGH;
1346     case ButtonRole:
1347     case ToggleButtonRole:
1348     case CheckBoxRole:
1349     case ListBoxOptionRole:
1350     // MacOS does not expect native <li> elements to expose label information, it only expects leaf node elements to do that.
1351 #if !PLATFORM(COCOA)
1352     case ListItemRole:
1353 #endif
1354     case MenuButtonRole:
1355     case MenuItemRole:
1356     case MenuItemCheckboxRole:
1357     case MenuItemRadioRole:
1358     case RadioButtonRole:
1359     case TabRole:
1360     case ProgressIndicatorRole:
1361         useTextUnderElement = true;
1362         break;
1363     default:
1364         break;
1365     }
1366     
1367     // If it's focusable but it's not content editable or a known control type, then it will appear to
1368     // the user as a single atomic object, so we should use its text as the default title.
1369     if (isHeading() || isLink())
1370         useTextUnderElement = true;
1371     
1372     if (useTextUnderElement) {
1373         AccessibilityTextUnderElementMode mode;
1374         
1375         // Headings often include links as direct children. Those links need to be included in text under element.
1376         if (isHeading())
1377             mode.includeFocusableContent = true;
1378
1379         String text = textUnderElement(mode);
1380         if (!text.isEmpty())
1381             textOrder.append(AccessibilityText(text, ChildrenText));
1382     }
1383 }
1384
1385 void AccessibilityNodeObject::helpText(Vector<AccessibilityText>& textOrder) const
1386 {
1387     const AtomicString& ariaHelp = getAttribute(aria_helpAttr);
1388     if (!ariaHelp.isEmpty())
1389         textOrder.append(AccessibilityText(ariaHelp, HelpText));
1390     
1391     String describedBy = ariaDescribedByAttribute();
1392     if (!describedBy.isEmpty())
1393         textOrder.append(AccessibilityText(describedBy, SummaryText));
1394
1395     // Summary attribute used as help text on tables.
1396     const AtomicString& summary = getAttribute(summaryAttr);
1397     if (!summary.isEmpty())
1398         textOrder.append(AccessibilityText(summary, SummaryText));
1399
1400     // The title attribute should be used as help text unless it is already being used as descriptive text.
1401     const AtomicString& title = getAttribute(titleAttr);
1402     if (!title.isEmpty())
1403         textOrder.append(AccessibilityText(title, TitleTagText));
1404 }
1405
1406 void AccessibilityNodeObject::accessibilityText(Vector<AccessibilityText>& textOrder)
1407 {
1408     titleElementText(textOrder);
1409     alternativeText(textOrder);
1410     visibleText(textOrder);
1411     helpText(textOrder);
1412     
1413     String placeholder = placeholderValue();
1414     if (!placeholder.isEmpty())
1415         textOrder.append(AccessibilityText(placeholder, PlaceholderText));
1416 }
1417     
1418 void AccessibilityNodeObject::ariaLabeledByText(Vector<AccessibilityText>& textOrder) const
1419 {
1420     String ariaLabeledBy = ariaLabeledByAttribute();
1421     if (!ariaLabeledBy.isEmpty()) {
1422         Vector<Element*> elements;
1423         ariaLabeledByElements(elements);
1424         
1425         Vector<RefPtr<AccessibilityObject>> axElements;
1426         for (const auto& element : elements) {
1427             RefPtr<AccessibilityObject> axElement = axObjectCache()->getOrCreate(element);
1428             axElements.append(axElement);
1429         }
1430         
1431         textOrder.append(AccessibilityText(ariaLabeledBy, AlternativeText, WTF::move(axElements)));
1432     }
1433 }
1434     
1435 String AccessibilityNodeObject::alternativeTextForWebArea() const
1436 {
1437     // The WebArea description should follow this order:
1438     //     aria-label on the <html>
1439     //     title on the <html>
1440     //     <title> inside the <head> (of it was set through JS)
1441     //     name on the <html>
1442     // For iframes:
1443     //     aria-label on the <iframe>
1444     //     title on the <iframe>
1445     //     name on the <iframe>
1446     
1447     Document* document = this->document();
1448     if (!document)
1449         return String();
1450     
1451     // Check if the HTML element has an aria-label for the webpage.
1452     if (Element* documentElement = document->documentElement()) {
1453         const AtomicString& ariaLabel = documentElement->fastGetAttribute(aria_labelAttr);
1454         if (!ariaLabel.isEmpty())
1455             return ariaLabel;
1456     }
1457     
1458     if (auto* owner = document->ownerElement()) {
1459         if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) {
1460             const AtomicString& title = owner->fastGetAttribute(titleAttr);
1461             if (!title.isEmpty())
1462                 return title;
1463         }
1464         return owner->getNameAttribute();
1465     }
1466     
1467     String documentTitle = document->title();
1468     if (!documentTitle.isEmpty())
1469         return documentTitle;
1470     
1471     if (auto* body = document->body())
1472         return body->getNameAttribute();
1473     
1474     return String();
1475 }
1476     
1477 String AccessibilityNodeObject::accessibilityDescription() const
1478 {
1479     // Static text should not have a description, it should only have a stringValue.
1480     if (roleValue() == StaticTextRole)
1481         return String();
1482
1483     String ariaDescription = ariaAccessibilityDescription();
1484     if (!ariaDescription.isEmpty())
1485         return ariaDescription;
1486
1487     if (usesAltTagForTextComputation()) {
1488         // Images should use alt as long as the attribute is present, even if empty.                    
1489         // Otherwise, it should fallback to other methods, like the title attribute.                    
1490         const AtomicString& alt = getAttribute(altAttr);
1491         if (!alt.isNull())
1492             return alt;
1493     }
1494
1495     // SVG elements all can have a <svg:title> element inside which should act as the descriptive text.
1496     if (m_node && m_node->isSVGElement())
1497         return downcast<SVGElement>(*m_node).title();
1498     
1499 #if ENABLE(MATHML)
1500     if (is<MathMLElement>(m_node))
1501         return getAttribute(MathMLNames::alttextAttr);
1502 #endif
1503
1504     // An element's descriptive text is comprised of title() (what's visible on the screen) and accessibilityDescription() (other descriptive text).
1505     // Both are used to generate what a screen reader speaks.                                                           
1506     // If this point is reached (i.e. there's no accessibilityDescription) and there's no title(), we should fallback to using the title attribute.
1507     // The title attribute is normally used as help text (because it is a tooltip), but if there is nothing else available, this should be used (according to ARIA).
1508     if (title().isEmpty())
1509         return getAttribute(titleAttr);
1510
1511     return String();
1512 }
1513
1514 String AccessibilityNodeObject::helpText() const
1515 {
1516     Node* node = this->node();
1517     if (!node)
1518         return String();
1519     
1520     const AtomicString& ariaHelp = getAttribute(aria_helpAttr);
1521     if (!ariaHelp.isEmpty())
1522         return ariaHelp;
1523     
1524     String describedBy = ariaDescribedByAttribute();
1525     if (!describedBy.isEmpty())
1526         return describedBy;
1527     
1528     String description = accessibilityDescription();
1529     for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) {
1530         if (is<HTMLElement>(*ancestor)) {
1531             HTMLElement& element = downcast<HTMLElement>(*ancestor);
1532             const AtomicString& summary = element.getAttribute(summaryAttr);
1533             if (!summary.isEmpty())
1534                 return summary;
1535             
1536             // The title attribute should be used as help text unless it is already being used as descriptive text.
1537             const AtomicString& title = element.getAttribute(titleAttr);
1538             if (!title.isEmpty() && description != title)
1539                 return title;
1540         }
1541         
1542         // Only take help text from an ancestor element if its a group or an unknown role. If help was 
1543         // added to those kinds of elements, it is likely it was meant for a child element.
1544         AccessibilityObject* axObj = axObjectCache()->getOrCreate(ancestor);
1545         if (axObj) {
1546             AccessibilityRole role = axObj->roleValue();
1547             if (role != GroupRole && role != UnknownRole)
1548                 break;
1549         }
1550     }
1551     
1552     return String();
1553 }
1554     
1555 unsigned AccessibilityNodeObject::hierarchicalLevel() const
1556 {
1557     Node* node = this->node();
1558     if (!is<Element>(node))
1559         return 0;
1560     Element& element = downcast<Element>(*node);
1561     const AtomicString& ariaLevel = element.fastGetAttribute(aria_levelAttr);
1562     if (!ariaLevel.isEmpty())
1563         return ariaLevel.toInt();
1564     
1565     // Only tree item will calculate its level through the DOM currently.
1566     if (roleValue() != TreeItemRole)
1567         return 0;
1568     
1569     // Hierarchy leveling starts at 1, to match the aria-level spec.
1570     // We measure tree hierarchy by the number of groups that the item is within.
1571     unsigned level = 1;
1572     for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
1573         AccessibilityRole parentRole = parent->roleValue();
1574         if (parentRole == GroupRole)
1575             level++;
1576         else if (parentRole == TreeRole)
1577             break;
1578     }
1579     
1580     return level;
1581 }
1582
1583 // When building the textUnderElement for an object, determine whether or not
1584 // we should include the inner text of this given descendant object or skip it.
1585 static bool shouldUseAccessibilityObjectInnerText(AccessibilityObject* obj, AccessibilityTextUnderElementMode mode)
1586 {
1587     // Do not use any heuristic if we are explicitly asking to include all the children.
1588     if (mode.childrenInclusion == AccessibilityTextUnderElementMode::TextUnderElementModeIncludeAllChildren)
1589         return true;
1590
1591     // Consider this hypothetical example:
1592     // <div tabindex=0>
1593     //   <h2>
1594     //     Table of contents
1595     //   </h2>
1596     //   <a href="#start">Jump to start of book</a>
1597     //   <ul>
1598     //     <li><a href="#1">Chapter 1</a></li>
1599     //     <li><a href="#1">Chapter 2</a></li>
1600     //   </ul>
1601     // </div>
1602     //
1603     // The goal is to return a reasonable title for the outer container div, because
1604     // it's focusable - but without making its title be the full inner text, which is
1605     // quite long. As a heuristic, skip links, controls, and elements that are usually
1606     // containers with lots of children.
1607
1608     // ARIA states that certain elements are not allowed to expose their children content for name calculation.
1609     if (mode.childrenInclusion == AccessibilityTextUnderElementMode::TextUnderElementModeIncludeNameFromContentsChildren
1610         && !obj->accessibleNameDerivesFromContent())
1611         return false;
1612     
1613     if (equalIgnoringCase(obj->getAttribute(aria_hiddenAttr), "true"))
1614         return false;
1615     
1616     // If something doesn't expose any children, then we can always take the inner text content.
1617     // This is what we want when someone puts an <a> inside a <button> for example.
1618     if (obj->isDescendantOfBarrenParent())
1619         return true;
1620     
1621     // Skip focusable children, so we don't include the text of links and controls.
1622     if (obj->canSetFocusAttribute() && !mode.includeFocusableContent)
1623         return false;
1624
1625     // Skip big container elements like lists, tables, etc.
1626     if (is<AccessibilityList>(*obj))
1627         return false;
1628
1629     if (is<AccessibilityTable>(*obj) && downcast<AccessibilityTable>(*obj).isExposableThroughAccessibility())
1630         return false;
1631
1632     if (obj->isTree() || obj->isCanvas())
1633         return false;
1634
1635     return true;
1636 }
1637
1638 static bool shouldAddSpaceBeforeAppendingNextElement(StringBuilder& builder, const String& childText)
1639 {
1640     if (!builder.length() || !childText.length())
1641         return false;
1642
1643     // We don't need to add an additional space before or after a line break.
1644     return !(isHTMLLineBreak(childText[0]) || isHTMLLineBreak(builder[builder.length() - 1]));
1645 }
1646     
1647 static void appendNameToStringBuilder(StringBuilder& builder, const String& text)
1648 {
1649     if (shouldAddSpaceBeforeAppendingNextElement(builder, text))
1650         builder.append(' ');
1651     builder.append(text);
1652 }
1653
1654 String AccessibilityNodeObject::textUnderElement(AccessibilityTextUnderElementMode mode) const
1655 {
1656     Node* node = this->node();
1657     if (is<Text>(node))
1658         return downcast<Text>(*node).wholeText();
1659
1660     // The render tree should be stable before going ahead. Otherwise, further uses of the
1661     // TextIterator will force a layout update, potentially altering the accessibility tree
1662     // and leading to crashes in the loop that computes the result text from the children.
1663     ASSERT(!document()->renderView()->layoutState());
1664     ASSERT(!document()->childNeedsStyleRecalc());
1665
1666     StringBuilder builder;
1667     for (AccessibilityObject* child = firstChild(); child; child = child->nextSibling()) {
1668         if (mode.ignoredChildNode && child->node() == mode.ignoredChildNode)
1669             continue;
1670         
1671         bool shouldDeriveNameFromAuthor = (mode.childrenInclusion == AccessibilityTextUnderElementMode::TextUnderElementModeIncludeNameFromContentsChildren && !child->accessibleNameDerivesFromContent());
1672         if (shouldDeriveNameFromAuthor) {
1673             appendNameToStringBuilder(builder, accessibleNameForNode(child->node()));
1674             continue;
1675         }
1676         
1677         if (!shouldUseAccessibilityObjectInnerText(child, mode))
1678             continue;
1679
1680         if (is<AccessibilityNodeObject>(*child)) {
1681             Vector<AccessibilityText> textOrder;
1682             downcast<AccessibilityNodeObject>(*child).alternativeText(textOrder);
1683             if (textOrder.size() > 0 && textOrder[0].text.length()) {
1684                 appendNameToStringBuilder(builder, textOrder[0].text);
1685                 continue;
1686             }
1687         }
1688         
1689         String childText = child->textUnderElement(mode);
1690         if (childText.length())
1691             appendNameToStringBuilder(builder, childText);
1692     }
1693
1694     return builder.toString().stripWhiteSpace().simplifyWhiteSpace(isHTMLSpaceButNotLineBreak);
1695 }
1696
1697 String AccessibilityNodeObject::title() const
1698 {
1699     Node* node = this->node();
1700     if (!node)
1701         return String();
1702
1703     bool isInputTag = is<HTMLInputElement>(*node);
1704     if (isInputTag) {
1705         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
1706         if (input.isTextButton())
1707             return input.valueWithDefault();
1708     }
1709
1710     if (isInputTag || AccessibilityObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
1711         HTMLLabelElement* label = labelForElement(downcast<Element>(node));
1712         // Use the label text as the title if 1) the title element is NOT an exposed element and 2) there's no ARIA override.
1713         if (label && !exposesTitleUIElement() && !ariaAccessibilityDescription().length())
1714             return label->innerText();
1715     }
1716
1717     // If this node isn't rendered, there's no inner text we can extract from a select element.
1718     if (!isAccessibilityRenderObject() && node->hasTagName(selectTag))
1719         return String();
1720
1721     switch (roleValue()) {
1722     case PopUpButtonRole:
1723         // Native popup buttons should not use their button children's text as a title. That value is retrieved through stringValue().
1724         if (node->hasTagName(selectTag))
1725             return String();
1726         FALLTHROUGH;
1727     case ButtonRole:
1728     case ToggleButtonRole:
1729     case CheckBoxRole:
1730     case ListBoxOptionRole:
1731     case ListItemRole:
1732     case MenuButtonRole:
1733     case MenuItemRole:
1734     case MenuItemCheckboxRole:
1735     case MenuItemRadioRole:
1736     case RadioButtonRole:
1737     case TabRole:
1738         return textUnderElement();
1739     // SVGRoots should not use the text under itself as a title. That could include the text of objects like <text>.
1740     case SVGRootRole:
1741         return String();
1742     default:
1743         break;
1744     }
1745
1746     if (isLink())
1747         return textUnderElement();
1748     if (isHeading())
1749         return textUnderElement(AccessibilityTextUnderElementMode(AccessibilityTextUnderElementMode::TextUnderElementModeSkipIgnoredChildren, true));
1750
1751     return String();
1752 }
1753
1754 String AccessibilityNodeObject::text() const
1755 {
1756     // If this is a user defined static text, use the accessible name computation.                                      
1757     if (ariaRoleAttribute() == StaticTextRole) {
1758         Vector<AccessibilityText> textOrder;
1759         alternativeText(textOrder);
1760         if (textOrder.size() > 0 && textOrder[0].text.length())
1761             return textOrder[0].text;
1762     }
1763
1764     if (!isTextControl())
1765         return String();
1766
1767     Node* node = this->node();
1768     if (!node)
1769         return String();
1770
1771     if (isNativeTextControl() && is<HTMLTextFormControlElement>(*node))
1772         return downcast<HTMLTextFormControlElement>(*node).value();
1773
1774     if (!node->isElementNode())
1775         return String();
1776
1777     return downcast<Element>(node)->innerText();
1778 }
1779
1780 String AccessibilityNodeObject::stringValue() const
1781 {
1782     Node* node = this->node();
1783     if (!node)
1784         return String();
1785
1786     if (ariaRoleAttribute() == StaticTextRole) {
1787         String staticText = text();
1788         if (!staticText.length())
1789             staticText = textUnderElement();
1790         return staticText;
1791     }
1792
1793     if (node->isTextNode())
1794         return textUnderElement();
1795
1796     if (node->hasTagName(selectTag)) {
1797         HTMLSelectElement& selectElement = downcast<HTMLSelectElement>(*node);
1798         int selectedIndex = selectElement.selectedIndex();
1799         const Vector<HTMLElement*>& listItems = selectElement.listItems();
1800         if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems.size()) {
1801             const AtomicString& overriddenDescription = listItems[selectedIndex]->fastGetAttribute(aria_labelAttr);
1802             if (!overriddenDescription.isNull())
1803                 return overriddenDescription;
1804         }
1805         if (!selectElement.multiple())
1806             return selectElement.value();
1807         return String();
1808     }
1809
1810     if (isTextControl())
1811         return text();
1812
1813     // FIXME: We might need to implement a value here for more types
1814     // FIXME: It would be better not to advertise a value at all for the types for which we don't implement one;
1815     // this would require subclassing or making accessibilityAttributeNames do something other than return a
1816     // single static array.
1817     return String();
1818 }
1819
1820 void AccessibilityNodeObject::colorValue(int& r, int& g, int& b) const
1821 {
1822     r = 0;
1823     g = 0;
1824     b = 0;
1825
1826     if (!isColorWell())
1827         return;
1828
1829     if (!is<HTMLInputElement>(node()))
1830         return;
1831
1832     HTMLInputElement& input = downcast<HTMLInputElement>(*node());
1833     const AtomicString& type = input.getAttribute(typeAttr);
1834     if (!equalIgnoringCase(type, "color"))
1835         return;
1836
1837     // HTMLInputElement::value always returns a string parseable by Color().
1838     Color color(input.value());
1839     r = color.red();
1840     g = color.green();
1841     b = color.blue();
1842 }
1843
1844 // This function implements the ARIA accessible name as described by the Mozilla                                        
1845 // ARIA Implementer's Guide.                                                                                            
1846 static String accessibleNameForNode(Node* node, Node* labelledbyNode)
1847 {
1848     ASSERT(node);
1849     if (!is<Element>(node))
1850         return String();
1851     
1852     Element& element = downcast<Element>(*node);
1853     const AtomicString& ariaLabel = element.fastGetAttribute(aria_labelAttr);
1854     if (!ariaLabel.isEmpty())
1855         return ariaLabel;
1856     
1857     const AtomicString& alt = element.fastGetAttribute(altAttr);
1858     if (!alt.isEmpty())
1859         return alt;
1860
1861     // If the node can be turned into an AX object, we can use standard name computation rules.
1862     // If however, the node cannot (because there's no renderer e.g.) fallback to using the basic text underneath.
1863     AccessibilityObject* axObject = node->document().axObjectCache()->getOrCreate(node);
1864     if (axObject) {
1865         String valueDescription = axObject->valueDescription();
1866         if (!valueDescription.isEmpty())
1867             return valueDescription;
1868     }
1869     
1870     if (is<HTMLInputElement>(*node))
1871         return downcast<HTMLInputElement>(*node).value();
1872     
1873     String text;
1874     if (axObject) {
1875         if (axObject->accessibleNameDerivesFromContent())
1876             text = axObject->textUnderElement(AccessibilityTextUnderElementMode(AccessibilityTextUnderElementMode::TextUnderElementModeIncludeNameFromContentsChildren, true, labelledbyNode));
1877     } else
1878         text = element.innerText();
1879
1880     if (!text.isEmpty())
1881         return text;
1882     
1883     const AtomicString& title = element.fastGetAttribute(titleAttr);
1884     if (!title.isEmpty())
1885         return title;
1886     
1887     return String();
1888 }
1889
1890 String AccessibilityNodeObject::accessibilityDescriptionForElements(Vector<Element*> &elements) const
1891 {
1892     StringBuilder builder;
1893     unsigned size = elements.size();
1894     for (unsigned i = 0; i < size; ++i)
1895         appendNameToStringBuilder(builder, accessibleNameForNode(elements[i], node()));
1896     return builder.toString();
1897 }
1898
1899 String AccessibilityNodeObject::ariaDescribedByAttribute() const
1900 {
1901     Vector<Element*> elements;
1902     elementsFromAttribute(elements, aria_describedbyAttr);
1903     
1904     return accessibilityDescriptionForElements(elements);
1905 }
1906
1907 void AccessibilityNodeObject::ariaLabeledByElements(Vector<Element*>& elements) const
1908 {
1909     elementsFromAttribute(elements, aria_labelledbyAttr);
1910     if (!elements.size())
1911         elementsFromAttribute(elements, aria_labeledbyAttr);
1912 }
1913
1914
1915 String AccessibilityNodeObject::ariaLabeledByAttribute() const
1916 {
1917     Vector<Element*> elements;
1918     ariaLabeledByElements(elements);
1919
1920     return accessibilityDescriptionForElements(elements);
1921 }
1922
1923 bool AccessibilityNodeObject::hasAttributesRequiredForInclusion() const
1924 {
1925     if (AccessibilityObject::hasAttributesRequiredForInclusion())
1926         return true;
1927
1928     if (!ariaAccessibilityDescription().isEmpty())
1929         return true;
1930
1931     return false;
1932 }
1933
1934 bool AccessibilityNodeObject::canSetFocusAttribute() const
1935 {
1936     Node* node = this->node();
1937     if (!node)
1938         return false;
1939
1940     if (isWebArea())
1941         return true;
1942     
1943     // NOTE: It would be more accurate to ask the document whether setFocusedElement() would
1944     // do anything. For example, setFocusedElement() will do nothing if the current focused
1945     // node will not relinquish the focus.
1946     if (!is<Element>(node))
1947         return false;
1948
1949     Element& element = downcast<Element>(*node);
1950
1951     if (element.isDisabledFormControl())
1952         return false;
1953
1954     return element.supportsFocus();
1955 }
1956
1957 AccessibilityRole AccessibilityNodeObject::determineAriaRoleAttribute() const
1958 {
1959     const AtomicString& ariaRole = getAttribute(roleAttr);
1960     if (ariaRole.isNull() || ariaRole.isEmpty())
1961         return UnknownRole;
1962     
1963     AccessibilityRole role = ariaRoleToWebCoreRole(ariaRole);
1964
1965     // ARIA states if an item can get focus, it should not be presentational.
1966     if (role == PresentationalRole && canSetFocusAttribute())
1967         return UnknownRole;
1968
1969     if (role == ButtonRole)
1970         role = buttonRoleType();
1971
1972     if (role == TextAreaRole && !ariaIsMultiline())
1973         role = TextFieldRole;
1974
1975     role = remapAriaRoleDueToParent(role);
1976     
1977     // Presentational roles are invalidated by the presence of ARIA attributes.
1978     if (role == PresentationalRole && supportsARIAAttributes())
1979         role = UnknownRole;
1980     
1981     if (role)
1982         return role;
1983
1984     return UnknownRole;
1985 }
1986
1987 AccessibilityRole AccessibilityNodeObject::ariaRoleAttribute() const
1988 {
1989     return m_ariaRole;
1990 }
1991
1992 AccessibilityRole AccessibilityNodeObject::remapAriaRoleDueToParent(AccessibilityRole role) const
1993 {
1994     // Some objects change their role based on their parent.
1995     // However, asking for the unignoredParent calls accessibilityIsIgnored(), which can trigger a loop. 
1996     // While inside the call stack of creating an element, we need to avoid accessibilityIsIgnored().
1997     // https://bugs.webkit.org/show_bug.cgi?id=65174
1998
1999     if (role != ListBoxOptionRole && role != MenuItemRole)
2000         return role;
2001     
2002     for (AccessibilityObject* parent = parentObject(); parent && !parent->accessibilityIsIgnored(); parent = parent->parentObject()) {
2003         AccessibilityRole parentAriaRole = parent->ariaRoleAttribute();
2004
2005         // Selects and listboxes both have options as child roles, but they map to different roles within WebCore.
2006         if (role == ListBoxOptionRole && parentAriaRole == MenuRole)
2007             return MenuItemRole;
2008         // An aria "menuitem" may map to MenuButton or MenuItem depending on its parent.
2009         if (role == MenuItemRole && parentAriaRole == GroupRole)
2010             return MenuButtonRole;
2011         
2012         // If the parent had a different role, then we don't need to continue searching up the chain.
2013         if (parentAriaRole)
2014             break;
2015     }
2016     
2017     return role;
2018 }   
2019
2020 bool AccessibilityNodeObject::canSetSelectedAttribute() const
2021 {
2022     // Elements that can be selected
2023     switch (roleValue()) {
2024     case CellRole:
2025     case RadioButtonRole:
2026     case RowHeaderRole:
2027     case RowRole:
2028     case TabListRole:
2029     case TabRole:
2030     case TreeGridRole:
2031     case TreeItemRole:
2032     case TreeRole:
2033         return isEnabled();
2034     default:
2035         return false;
2036     }
2037 }
2038
2039 } // namespace WebCore