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