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