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