Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / accessibility / AXRenderObject.cpp
1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple 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 "core/accessibility/AXRenderObject.h"
31
32 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
33 #include "core/InputTypeNames.h"
34 #include "core/accessibility/AXImageMapLink.h"
35 #include "core/accessibility/AXInlineTextBox.h"
36 #include "core/accessibility/AXObjectCache.h"
37 #include "core/accessibility/AXSVGRoot.h"
38 #include "core/accessibility/AXSpinButton.h"
39 #include "core/accessibility/AXTable.h"
40 #include "core/dom/ElementTraversal.h"
41 #include "core/dom/shadow/ShadowRoot.h"
42 #include "core/editing/FrameSelection.h"
43 #include "core/editing/RenderedPosition.h"
44 #include "core/editing/TextIterator.h"
45 #include "core/editing/VisibleUnits.h"
46 #include "core/editing/htmlediting.h"
47 #include "core/frame/LocalFrame.h"
48 #include "core/frame/Settings.h"
49 #include "core/html/HTMLImageElement.h"
50 #include "core/html/HTMLLabelElement.h"
51 #include "core/html/HTMLOptionElement.h"
52 #include "core/html/HTMLSelectElement.h"
53 #include "core/html/HTMLTextAreaElement.h"
54 #include "core/html/shadow/ShadowElementNames.h"
55 #include "core/loader/ProgressTracker.h"
56 #include "core/page/Page.h"
57 #include "core/rendering/HitTestResult.h"
58 #include "core/rendering/RenderFieldset.h"
59 #include "core/rendering/RenderFileUploadControl.h"
60 #include "core/rendering/RenderHTMLCanvas.h"
61 #include "core/rendering/RenderImage.h"
62 #include "core/rendering/RenderInline.h"
63 #include "core/rendering/RenderLayer.h"
64 #include "core/rendering/RenderListMarker.h"
65 #include "core/rendering/RenderMenuList.h"
66 #include "core/rendering/RenderTextControlSingleLine.h"
67 #include "core/rendering/RenderTextFragment.h"
68 #include "core/rendering/RenderView.h"
69 #include "core/rendering/RenderWidget.h"
70 #include "core/svg/SVGDocumentExtensions.h"
71 #include "core/svg/SVGSVGElement.h"
72 #include "core/svg/graphics/SVGImage.h"
73 #include "platform/text/PlatformLocale.h"
74 #include "wtf/StdLibExtras.h"
75
76 using blink::WebLocalizedString;
77
78 namespace blink {
79
80 using namespace HTMLNames;
81
82 static inline RenderObject* firstChildInContinuation(const RenderInline& renderer)
83 {
84     RenderBoxModelObject* r = renderer.continuation();
85
86     while (r) {
87         if (r->isRenderBlock())
88             return r;
89         if (RenderObject* child = r->slowFirstChild())
90             return child;
91         r = toRenderInline(r)->continuation();
92     }
93
94     return 0;
95 }
96
97 static inline bool isInlineWithContinuation(RenderObject* object)
98 {
99     if (!object->isBoxModelObject())
100         return false;
101
102     RenderBoxModelObject* renderer = toRenderBoxModelObject(object);
103     if (!renderer->isRenderInline())
104         return false;
105
106     return toRenderInline(renderer)->continuation();
107 }
108
109 static inline RenderObject* firstChildConsideringContinuation(RenderObject* renderer)
110 {
111     RenderObject* firstChild = renderer->slowFirstChild();
112
113     if (!firstChild && isInlineWithContinuation(renderer))
114         firstChild = firstChildInContinuation(toRenderInline(*renderer));
115
116     return firstChild;
117 }
118
119 static inline RenderInline* startOfContinuations(RenderObject* r)
120 {
121     if (r->isInlineElementContinuation()) {
122         return toRenderInline(r->node()->renderer());
123     }
124
125     // Blocks with a previous continuation always have a next continuation
126     if (r->isRenderBlock() && toRenderBlock(r)->inlineElementContinuation())
127         return toRenderInline(toRenderBlock(r)->inlineElementContinuation()->node()->renderer());
128
129     return 0;
130 }
131
132 static inline RenderObject* endOfContinuations(RenderObject* renderer)
133 {
134     RenderObject* prev = renderer;
135     RenderObject* cur = renderer;
136
137     if (!cur->isRenderInline() && !cur->isRenderBlock())
138         return renderer;
139
140     while (cur) {
141         prev = cur;
142         if (cur->isRenderInline()) {
143             cur = toRenderInline(cur)->inlineElementContinuation();
144             ASSERT(cur || !toRenderInline(prev)->continuation());
145         } else {
146             cur = toRenderBlock(cur)->inlineElementContinuation();
147         }
148     }
149
150     return prev;
151 }
152
153 static inline bool lastChildHasContinuation(RenderObject* renderer)
154 {
155     RenderObject* lastChild = renderer->slowLastChild();
156     return lastChild && isInlineWithContinuation(lastChild);
157 }
158
159 static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
160 {
161     ASSERT(renderer);
162     if (renderer->isRenderInline() && !renderer->isReplaced())
163         return toRenderInline(renderer)->continuation();
164     if (renderer->isRenderBlock())
165         return toRenderBlock(renderer)->inlineElementContinuation();
166     return 0;
167 }
168
169 AXRenderObject::AXRenderObject(RenderObject* renderer)
170     : AXNodeObject(renderer->node())
171     , m_renderer(renderer)
172     , m_cachedElementRectDirty(true)
173 {
174 #if ENABLE(ASSERT)
175     m_renderer->setHasAXObject(true);
176 #endif
177 }
178
179 PassRefPtr<AXRenderObject> AXRenderObject::create(RenderObject* renderer)
180 {
181     return adoptRef(new AXRenderObject(renderer));
182 }
183
184 AXRenderObject::~AXRenderObject()
185 {
186     ASSERT(isDetached());
187 }
188
189 LayoutRect AXRenderObject::elementRect() const
190 {
191     if (!m_explicitElementRect.isEmpty())
192         return m_explicitElementRect;
193     if (!m_renderer)
194         return LayoutRect();
195     if (!m_renderer->isBox())
196         return computeElementRect();
197
198     for (const AXObject* obj = this; obj; obj = obj->parentObject()) {
199         if (obj->isAXRenderObject())
200             toAXRenderObject(obj)->checkCachedElementRect();
201     }
202     for (const AXObject* obj = this; obj; obj = obj->parentObject()) {
203         if (obj->isAXRenderObject())
204             toAXRenderObject(obj)->updateCachedElementRect();
205     }
206
207     return m_cachedElementRect;
208 }
209
210 void AXRenderObject::setRenderer(RenderObject* renderer)
211 {
212     m_renderer = renderer;
213     setNode(renderer->node());
214 }
215
216 RenderBoxModelObject* AXRenderObject::renderBoxModelObject() const
217 {
218     if (!m_renderer || !m_renderer->isBoxModelObject())
219         return 0;
220     return toRenderBoxModelObject(m_renderer);
221 }
222
223 Document* AXRenderObject::topDocument() const
224 {
225     if (!document())
226         return 0;
227     return &document()->topDocument();
228 }
229
230 bool AXRenderObject::shouldNotifyActiveDescendant() const
231 {
232     // We want to notify that the combo box has changed its active descendant,
233     // but we do not want to change the focus, because focus should remain with the combo box.
234     if (isComboBox())
235         return true;
236
237     return shouldFocusActiveDescendant();
238 }
239
240 ScrollableArea* AXRenderObject::getScrollableAreaIfScrollable() const
241 {
242     // If the parent is a scroll view, then this object isn't really scrollable, the parent ScrollView should handle the scrolling.
243     if (parentObject() && parentObject()->isAXScrollView())
244         return 0;
245
246     if (!m_renderer || !m_renderer->isBox())
247         return 0;
248
249     RenderBox* box = toRenderBox(m_renderer);
250     if (!box->canBeScrolledAndHasScrollableArea())
251         return 0;
252
253     return box->scrollableArea();
254 }
255
256 AccessibilityRole AXRenderObject::determineAccessibilityRole()
257 {
258     if (!m_renderer)
259         return UnknownRole;
260
261     m_ariaRole = determineAriaRoleAttribute();
262
263     Node* node = m_renderer->node();
264     AccessibilityRole ariaRole = ariaRoleAttribute();
265     if (ariaRole != UnknownRole)
266         return ariaRole;
267
268     RenderBoxModelObject* cssBox = renderBoxModelObject();
269
270     if (node && node->isLink()) {
271         if (cssBox && cssBox->isImage())
272             return ImageMapRole;
273         return LinkRole;
274     }
275     if (cssBox && cssBox->isListItem())
276         return ListItemRole;
277     if (m_renderer->isListMarker())
278         return ListMarkerRole;
279     if (isHTMLButtonElement(node))
280         return buttonRoleType();
281     if (isHTMLDetailsElement(node))
282         return DetailsRole;
283     if (isHTMLSummaryElement(node)) {
284         if (node->parentElement() && isHTMLDetailsElement(node->parentElement()))
285             return DisclosureTriangleRole;
286         return UnknownRole;
287     }
288     if (isHTMLLegendElement(node))
289         return LegendRole;
290     if (m_renderer->isText())
291         return StaticTextRole;
292     if (cssBox && cssBox->isImage()) {
293         if (isHTMLInputElement(node))
294             return ariaHasPopup() ? PopUpButtonRole : ButtonRole;
295         if (isSVGImage())
296             return SVGRootRole;
297         return ImageRole;
298     }
299
300     // Note: if JavaScript is disabled, the renderer won't be a RenderHTMLCanvas.
301     if (isHTMLCanvasElement(node) && m_renderer->isCanvas())
302         return CanvasRole;
303
304     if (cssBox && cssBox->isRenderView())
305         return WebAreaRole;
306
307     if (cssBox && cssBox->isTextField())
308         return TextFieldRole;
309
310     if (cssBox && cssBox->isTextArea())
311         return TextAreaRole;
312
313     if (isHTMLInputElement(node)) {
314         HTMLInputElement& input = toHTMLInputElement(*node);
315         const AtomicString& type = input.type();
316         if (type == InputTypeNames::checkbox)
317             return CheckBoxRole;
318         if (type == InputTypeNames::radio)
319             return RadioButtonRole;
320         if (input.isTextButton())
321             return buttonRoleType();
322         if (type == InputTypeNames::color)
323             return ColorWellRole;
324     }
325
326     if (isFileUploadButton())
327         return ButtonRole;
328
329     if (cssBox && cssBox->isMenuList())
330         return PopUpButtonRole;
331
332     if (headingLevel())
333         return HeadingRole;
334
335     if (m_renderer->isSVGImage())
336         return ImageRole;
337     if (m_renderer->isSVGRoot())
338         return SVGRootRole;
339
340     if (node && node->hasTagName(ddTag))
341         return DescriptionListDetailRole;
342
343     if (node && node->hasTagName(dtTag))
344         return DescriptionListTermRole;
345
346     if (node && (node->hasTagName(rpTag) || node->hasTagName(rtTag)))
347         return AnnotationRole;
348
349     // Table sections should be ignored.
350     if (m_renderer->isTableSection())
351         return IgnoredRole;
352
353     if (m_renderer->isHR())
354         return HorizontalRuleRole;
355
356     if (isHTMLParagraphElement(node))
357         return ParagraphRole;
358
359     if (isHTMLLabelElement(node))
360         return LabelRole;
361
362     if (isHTMLDivElement(node))
363         return DivRole;
364
365     if (isHTMLFormElement(node))
366         return FormRole;
367
368     if (node && node->hasTagName(articleTag))
369         return ArticleRole;
370
371     if (node && node->hasTagName(mainTag))
372         return MainRole;
373
374     if (node && node->hasTagName(navTag))
375         return NavigationRole;
376
377     if (node && node->hasTagName(asideTag))
378         return ComplementaryRole;
379
380     if (node && node->hasTagName(sectionTag))
381         return RegionRole;
382
383     if (node && node->hasTagName(addressTag))
384         return ContentInfoRole;
385
386     if (node && node->hasTagName(dialogTag))
387         return DialogRole;
388
389     // The HTML element should not be exposed as an element. That's what the RenderView element does.
390     if (isHTMLHtmlElement(node))
391         return IgnoredRole;
392
393     if (node && node->hasTagName(iframeTag))
394         return IframeRole;
395
396     if (isEmbeddedObject())
397         return EmbeddedObjectRole;
398
399     if (node && node->hasTagName(figcaptionTag))
400         return FigcaptionRole;
401
402     if (node && node->hasTagName(figureTag))
403         return FigureRole;
404
405     // There should only be one banner/contentInfo per page. If header/footer are being used within an article or section
406     // then it should not be exposed as whole page's banner/contentInfo
407     if (node && node->hasTagName(headerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag))
408         return BannerRole;
409     if (node && node->hasTagName(footerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag))
410         return FooterRole;
411
412     if (isHTMLAnchorElement(node) && isClickable())
413         return LinkRole;
414
415     if (m_renderer->isRenderBlockFlow())
416         return GroupRole;
417
418     // If the element does not have role, but it has ARIA attributes, accessibility should fallback to exposing it as a group.
419     if (supportsARIAAttributes())
420         return GroupRole;
421
422     return UnknownRole;
423 }
424
425 void AXRenderObject::init()
426 {
427     AXNodeObject::init();
428 }
429
430 void AXRenderObject::detach()
431 {
432     AXNodeObject::detach();
433
434     detachRemoteSVGRoot();
435
436 #if ENABLE(ASSERT)
437     if (m_renderer)
438         m_renderer->setHasAXObject(false);
439 #endif
440     m_renderer = 0;
441 }
442
443 //
444 // Check object role or purpose.
445 //
446
447 bool AXRenderObject::isAttachment() const
448 {
449     RenderBoxModelObject* renderer = renderBoxModelObject();
450     if (!renderer)
451         return false;
452     // Widgets are the replaced elements that we represent to AX as attachments
453     bool isWidget = renderer->isWidget();
454     ASSERT(!isWidget || (renderer->isReplaced() && !isImage()));
455     return isWidget;
456 }
457
458 bool AXRenderObject::isFileUploadButton() const
459 {
460     return m_renderer && isHTMLInputElement(m_renderer->node()) && toHTMLInputElement(*m_renderer->node()).type() == InputTypeNames::file;
461 }
462
463 static bool isLinkable(const AXObject& object)
464 {
465     if (!object.renderer())
466         return false;
467
468     // See https://wiki.mozilla.org/Accessibility/AT-Windows-API for the elements
469     // Mozilla considers linkable.
470     return object.isLink() || object.isImage() || object.renderer()->isText();
471 }
472
473 bool AXRenderObject::isLinked() const
474 {
475     if (!isLinkable(*this))
476         return false;
477
478     Element* anchor = anchorElement();
479     if (!isHTMLAnchorElement(anchor))
480         return false;
481
482     return !toHTMLAnchorElement(*anchor).href().isEmpty();
483 }
484
485 bool AXRenderObject::isLoaded() const
486 {
487     return !m_renderer->document().parser();
488 }
489
490 bool AXRenderObject::isOffScreen() const
491 {
492     ASSERT(m_renderer);
493     IntRect contentRect = pixelSnappedIntRect(m_renderer->absoluteClippedOverflowRect());
494     FrameView* view = m_renderer->frame()->view();
495     IntRect viewRect = view->visibleContentRect();
496     viewRect.intersect(contentRect);
497     return viewRect.isEmpty();
498 }
499
500 bool AXRenderObject::isReadOnly() const
501 {
502     ASSERT(m_renderer);
503
504     if (isWebArea()) {
505         Document& document = m_renderer->document();
506         HTMLElement* body = document.body();
507         if (body && body->hasEditableStyle())
508             return false;
509
510         return !document.hasEditableStyle();
511     }
512
513     return AXNodeObject::isReadOnly();
514 }
515
516 bool AXRenderObject::isVisited() const
517 {
518     // FIXME: Is it a privacy violation to expose visited information to accessibility APIs?
519     return m_renderer->style()->isLink() && m_renderer->style()->insideLink() == InsideVisitedLink;
520 }
521
522 //
523 // Check object state.
524 //
525
526 bool AXRenderObject::isFocused() const
527 {
528     if (!m_renderer)
529         return false;
530
531     Document& document = m_renderer->document();
532     Element* focusedElement = document.focusedElement();
533     if (!focusedElement)
534         return false;
535
536     // A web area is represented by the Document node in the DOM tree, which isn't focusable.
537     // Check instead if the frame's selection controller is focused
538     if (focusedElement == m_renderer->node()
539         || (roleValue() == WebAreaRole && document.frame()->selection().isFocusedAndActive()))
540         return true;
541
542     return false;
543 }
544
545 bool AXRenderObject::isSelected() const
546 {
547     if (!m_renderer)
548         return false;
549
550     Node* node = m_renderer->node();
551     if (!node)
552         return false;
553
554     const AtomicString& ariaSelected = getAttribute(aria_selectedAttr);
555     if (equalIgnoringCase(ariaSelected, "true"))
556         return true;
557
558     if (isTabItem() && isTabItemSelected())
559         return true;
560
561     return false;
562 }
563
564 //
565 // Whether objects are ignored, i.e. not included in the tree.
566 //
567
568 AXObjectInclusion AXRenderObject::defaultObjectInclusion() const
569 {
570     // The following cases can apply to any element that's a subclass of AXRenderObject.
571
572     if (!m_renderer)
573         return IgnoreObject;
574
575     if (m_renderer->style()->visibility() != VISIBLE) {
576         // aria-hidden is meant to override visibility as the determinant in AX hierarchy inclusion.
577         if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "false"))
578             return DefaultBehavior;
579
580         return IgnoreObject;
581     }
582
583     return AXObject::defaultObjectInclusion();
584 }
585
586 bool AXRenderObject::computeAccessibilityIsIgnored() const
587 {
588 #if ENABLE(ASSERT)
589     ASSERT(m_initialized);
590 #endif
591
592     // Check first if any of the common reasons cause this element to be ignored.
593     // Then process other use cases that need to be applied to all the various roles
594     // that AXRenderObjects take on.
595     AXObjectInclusion decision = defaultObjectInclusion();
596     if (decision == IncludeObject)
597         return false;
598     if (decision == IgnoreObject)
599         return true;
600
601     // If this element is within a parent that cannot have children, it should not be exposed.
602     if (isDescendantOfBarrenParent())
603         return true;
604
605     if (roleValue() == IgnoredRole)
606         return true;
607
608     if ((roleValue() == NoneRole || roleValue() == PresentationalRole) || inheritsPresentationalRole())
609         return true;
610
611     // An ARIA tree can only have tree items and static text as children.
612     if (!isAllowedChildOfTree())
613         return true;
614
615     // TODO: we should refactor this - but right now this is necessary to make
616     // sure scroll areas stay in the tree.
617     if (isAttachment())
618         return false;
619
620     // ignore popup menu items because AppKit does
621     for (RenderObject* parent = m_renderer->parent(); parent; parent = parent->parent()) {
622         if (parent->isBoxModelObject() && toRenderBoxModelObject(parent)->isMenuList())
623             return true;
624     }
625
626     // find out if this element is inside of a label element.
627     // if so, it may be ignored because it's the label for a checkbox or radio button
628     AXObject* controlObject = correspondingControlForLabelElement();
629     if (controlObject && !controlObject->exposesTitleUIElement() && controlObject->isCheckboxOrRadio())
630         return true;
631
632     // NOTE: BRs always have text boxes now, so the text box check here can be removed
633     if (m_renderer->isText()) {
634         // static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level
635         AXObject* parent = parentObjectUnignored();
636         if (parent && (parent->ariaRoleAttribute() == MenuItemRole || parent->ariaRoleAttribute() == MenuButtonRole))
637             return true;
638         RenderText* renderText = toRenderText(m_renderer);
639         if (m_renderer->isBR() || !renderText->firstTextBox())
640             return true;
641
642         // Don't ignore static text in editable text controls.
643         for (AXObject* parent = parentObject(); parent; parent = parent->parentObject()) {
644             if (parent->roleValue() == TextFieldRole || parent->roleValue() == TextAreaRole)
645                 return false;
646         }
647
648         // text elements that are just empty whitespace should not be returned
649         // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'pre', or similar...
650         return renderText->text().impl()->containsOnlyWhitespace();
651     }
652
653     if (isHeading())
654         return false;
655
656     if (isLandmarkRelated())
657         return false;
658
659     if (isLink())
660         return false;
661
662     // all controls are accessible
663     if (isControl())
664         return false;
665
666     if (ariaRoleAttribute() != UnknownRole)
667         return false;
668
669     // don't ignore labels, because they serve as TitleUIElements
670     Node* node = m_renderer->node();
671     if (isHTMLLabelElement(node))
672         return false;
673
674     // Anything that is content editable should not be ignored.
675     // However, one cannot just call node->hasEditableStyle() since that will ask if its parents
676     // are also editable. Only the top level content editable region should be exposed.
677     if (hasContentEditableAttributeSet())
678         return false;
679
680     // List items play an important role in defining the structure of lists. They should not be ignored.
681     if (roleValue() == ListItemRole)
682         return false;
683
684     if (roleValue() == DialogRole)
685         return false;
686
687     if (roleValue() == FigcaptionRole)
688         return false;
689
690     if (roleValue() == FigureRole)
691         return false;
692
693     if (roleValue() == DetailsRole)
694         return false;
695
696     // if this element has aria attributes on it, it should not be ignored.
697     if (supportsARIAAttributes())
698         return false;
699
700     // <span> tags are inline tags and not meant to convey information if they have no other aria
701     // information on them. If we don't ignore them, they may emit signals expected to come from
702     // their parent. In addition, because included spans are GroupRole objects, and GroupRole
703     // objects are often containers with meaningful information, the inclusion of a span can have
704     // the side effect of causing the immediate parent accessible to be ignored. This is especially
705     // problematic for platforms which have distinct roles for textual block elements.
706     if (isHTMLSpanElement(node))
707         return true;
708
709     if (m_renderer->isRenderBlockFlow() && m_renderer->childrenInline() && !canSetFocusAttribute())
710         return !toRenderBlockFlow(m_renderer)->firstLineBox() && !mouseButtonListener();
711
712     // ignore images seemingly used as spacers
713     if (isImage()) {
714
715         // If the image can take focus, it should not be ignored, lest the user not be able to interact with something important.
716         if (canSetFocusAttribute())
717             return false;
718
719         if (node && node->isElementNode()) {
720             Element* elt = toElement(node);
721             const AtomicString& alt = elt->getAttribute(altAttr);
722             // don't ignore an image that has an alt tag
723             if (!alt.string().containsOnlyWhitespace())
724                 return false;
725             // informal standard is to ignore images with zero-length alt strings
726             if (!alt.isNull())
727                 return true;
728         }
729
730         if (isNativeImage() && m_renderer->isImage()) {
731             // check for one-dimensional image
732             RenderImage* image = toRenderImage(m_renderer);
733             if (image->height() <= 1 || image->width() <= 1)
734                 return true;
735
736             // check whether rendered image was stretched from one-dimensional file image
737             if (image->cachedImage()) {
738                 LayoutSize imageSize = image->cachedImage()->imageSizeForRenderer(m_renderer, image->view()->zoomFactor());
739                 return imageSize.height() <= 1 || imageSize.width() <= 1;
740             }
741         }
742         return false;
743     }
744
745     if (isCanvas()) {
746         if (canvasHasFallbackContent())
747             return false;
748         RenderHTMLCanvas* canvas = toRenderHTMLCanvas(m_renderer);
749         if (canvas->height() <= 1 || canvas->width() <= 1)
750             return true;
751         // Otherwise fall through; use presence of help text, title, or description to decide.
752     }
753
754     if (isWebArea() || m_renderer->isListMarker())
755         return false;
756
757     // Using the help text, title or accessibility description (so we
758     // check if there's some kind of accessible name for the element)
759     // to decide an element's visibility is not as definitive as
760     // previous checks, so this should remain as one of the last.
761     //
762     // These checks are simplified in the interest of execution speed;
763     // for example, any element having an alt attribute will make it
764     // not ignored, rather than just images.
765     if (!getAttribute(aria_helpAttr).isEmpty() || !getAttribute(aria_describedbyAttr).isEmpty() || !getAttribute(altAttr).isEmpty() || !getAttribute(titleAttr).isEmpty())
766         return false;
767
768     // Don't ignore generic focusable elements like <div tabindex=0>
769     // unless they're completely empty, with no children.
770     if (isGenericFocusableElement() && node->hasChildren())
771         return false;
772
773     if (!ariaAccessibilityDescription().isEmpty())
774         return false;
775
776     // By default, objects should be ignored so that the AX hierarchy is not
777     // filled with unnecessary items.
778     return true;
779 }
780
781 //
782 // Properties of static elements.
783 //
784
785 const AtomicString& AXRenderObject::accessKey() const
786 {
787     Node* node = m_renderer->node();
788     if (!node)
789         return nullAtom;
790     if (!node->isElementNode())
791         return nullAtom;
792     return toElement(node)->getAttribute(accesskeyAttr);
793 }
794
795 AccessibilityOrientation AXRenderObject::orientation() const
796 {
797     const AtomicString& ariaOrientation = getAttribute(aria_orientationAttr);
798     if (equalIgnoringCase(ariaOrientation, "horizontal"))
799         return AccessibilityOrientationHorizontal;
800     if (equalIgnoringCase(ariaOrientation, "vertical"))
801         return AccessibilityOrientationVertical;
802
803     return AXObject::orientation();
804 }
805
806 String AXRenderObject::text() const
807 {
808     if (isPasswordField())
809         return String();
810
811     return AXNodeObject::text();
812 }
813
814 int AXRenderObject::textLength() const
815 {
816     if (!isTextControl())
817         return -1;
818
819     if (isPasswordField())
820         return -1; // need to return something distinct from 0
821
822     return text().length();
823 }
824
825 KURL AXRenderObject::url() const
826 {
827     if (isAnchor() && isHTMLAnchorElement(m_renderer->node())) {
828         if (HTMLAnchorElement* anchor = toHTMLAnchorElement(anchorElement()))
829             return anchor->href();
830     }
831
832     if (isWebArea())
833         return m_renderer->document().url();
834
835     if (isImage() && isHTMLImageElement(m_renderer->node()))
836         return toHTMLImageElement(*m_renderer->node()).src();
837
838     if (isInputImage())
839         return toHTMLInputElement(m_renderer->node())->src();
840
841     return KURL();
842 }
843
844 //
845 // Properties of interactive elements.
846 //
847
848 static String queryString(WebLocalizedString::Name name)
849 {
850     return Locale::defaultLocale().queryString(name);
851 }
852
853 String AXRenderObject::actionVerb() const
854 {
855     switch (roleValue()) {
856     case ButtonRole:
857     case ToggleButtonRole:
858         return queryString(WebLocalizedString::AXButtonActionVerb);
859     case TextFieldRole:
860     case TextAreaRole:
861         return queryString(WebLocalizedString::AXTextFieldActionVerb);
862     case RadioButtonRole:
863         return queryString(WebLocalizedString::AXRadioButtonActionVerb);
864     case CheckBoxRole:
865         return queryString(isChecked() ? WebLocalizedString::AXCheckedCheckBoxActionVerb : WebLocalizedString::AXUncheckedCheckBoxActionVerb);
866     case LinkRole:
867         return queryString(WebLocalizedString::AXLinkActionVerb);
868     default:
869         return emptyString();
870     }
871 }
872
873 String AXRenderObject::stringValue() const
874 {
875     if (!m_renderer)
876         return String();
877
878     if (isPasswordField())
879         return String();
880
881     RenderBoxModelObject* cssBox = renderBoxModelObject();
882
883     if (ariaRoleAttribute() == StaticTextRole) {
884         String staticText = text();
885         if (!staticText.length())
886             staticText = textUnderElement();
887         return staticText;
888     }
889
890     if (m_renderer->isText())
891         return textUnderElement();
892
893     if (cssBox && cssBox->isMenuList()) {
894         // RenderMenuList will go straight to the text() of its selected item.
895         // This has to be overridden in the case where the selected item has an ARIA label.
896         HTMLSelectElement* selectElement = toHTMLSelectElement(m_renderer->node());
897         int selectedIndex = selectElement->selectedIndex();
898         const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement->listItems();
899         if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems.size()) {
900             const AtomicString& overriddenDescription = listItems[selectedIndex]->fastGetAttribute(aria_labelAttr);
901             if (!overriddenDescription.isNull())
902                 return overriddenDescription;
903         }
904         return toRenderMenuList(m_renderer)->text();
905     }
906
907     if (m_renderer->isListMarker())
908         return toRenderListMarker(m_renderer)->text();
909
910     if (isWebArea()) {
911         // FIXME: Why would a renderer exist when the Document isn't attached to a frame?
912         if (m_renderer->frame())
913             return String();
914
915         ASSERT_NOT_REACHED();
916     }
917
918     if (isTextControl())
919         return text();
920
921     if (m_renderer->isFileUploadControl())
922         return toRenderFileUploadControl(m_renderer)->fileTextValue();
923
924     // FIXME: We might need to implement a value here for more types
925     // FIXME: It would be better not to advertise a value at all for the types for which we don't implement one;
926     // this would require subclassing or making accessibilityAttributeNames do something other than return a
927     // single static array.
928     return String();
929 }
930
931 //
932 // ARIA attributes.
933 //
934
935 AXObject* AXRenderObject::activeDescendant() const
936 {
937     if (!m_renderer)
938         return 0;
939
940     if (m_renderer->node() && !m_renderer->node()->isElementNode())
941         return 0;
942
943     Element* element = toElement(m_renderer->node());
944     if (!element)
945         return 0;
946
947     const AtomicString& activeDescendantAttrStr = element->getAttribute(aria_activedescendantAttr);
948     if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
949         return 0;
950
951     Element* target = element->treeScope().getElementById(activeDescendantAttrStr);
952     if (!target)
953         return 0;
954
955     AXObject* obj = axObjectCache()->getOrCreate(target);
956
957     // An activedescendant is only useful if it has a renderer, because that's what's needed to post the notification.
958     if (obj && obj->isAXRenderObject())
959         return obj;
960
961     return 0;
962 }
963
964 void AXRenderObject::accessibilityChildrenFromAttribute(QualifiedName attr, AccessibilityChildrenVector& children) const
965 {
966     WillBeHeapVector<RawPtrWillBeMember<Element> > elements;
967     elementsFromAttribute(elements, attr);
968
969     AXObjectCache* cache = axObjectCache();
970     unsigned count = elements.size();
971     for (unsigned k = 0; k < count; ++k) {
972         Element* element = elements[k];
973         AXObject* child = cache->getOrCreate(element);
974         if (child)
975             children.append(child);
976     }
977 }
978
979 void AXRenderObject::ariaFlowToElements(AccessibilityChildrenVector& flowTo) const
980 {
981     accessibilityChildrenFromAttribute(aria_flowtoAttr, flowTo);
982 }
983
984 void AXRenderObject::ariaControlsElements(AccessibilityChildrenVector& controls) const
985 {
986     accessibilityChildrenFromAttribute(aria_controlsAttr, controls);
987 }
988
989 void AXRenderObject::ariaDescribedbyElements(AccessibilityChildrenVector& describedby) const
990 {
991     accessibilityChildrenFromAttribute(aria_describedbyAttr, describedby);
992 }
993
994 void AXRenderObject::ariaLabelledbyElements(AccessibilityChildrenVector& labelledby) const
995 {
996     accessibilityChildrenFromAttribute(aria_labelledbyAttr, labelledby);
997 }
998
999 void AXRenderObject::ariaOwnsElements(AccessibilityChildrenVector& owns) const
1000 {
1001     accessibilityChildrenFromAttribute(aria_ownsAttr, owns);
1002 }
1003
1004 bool AXRenderObject::ariaHasPopup() const
1005 {
1006     return elementAttributeValue(aria_haspopupAttr);
1007 }
1008
1009 bool AXRenderObject::ariaRoleHasPresentationalChildren() const
1010 {
1011     switch (m_ariaRole) {
1012     case ButtonRole:
1013     case SliderRole:
1014     case ImageRole:
1015     case ProgressIndicatorRole:
1016     case SpinButtonRole:
1017     // case SeparatorRole:
1018         return true;
1019     default:
1020         return false;
1021     }
1022 }
1023
1024 bool AXRenderObject::isPresentationalChildOfAriaRole() const
1025 {
1026     // Walk the parent chain looking for a parent that has presentational children
1027     AXObject* parent;
1028     for (parent = parentObject(); parent && !parent->ariaRoleHasPresentationalChildren(); parent = parent->parentObject())
1029     { }
1030
1031     return parent;
1032 }
1033
1034 bool AXRenderObject::shouldFocusActiveDescendant() const
1035 {
1036     switch (ariaRoleAttribute()) {
1037     case ComboBoxRole:
1038     case GridRole:
1039     case GroupRole:
1040     case ListBoxRole:
1041     case MenuRole:
1042     case MenuBarRole:
1043     case OutlineRole:
1044     case PopUpButtonRole:
1045     case ProgressIndicatorRole:
1046     case RadioGroupRole:
1047     case RowRole:
1048     case TabListRole:
1049     case ToolbarRole:
1050     case TreeRole:
1051     case TreeGridRole:
1052         return true;
1053     default:
1054         return false;
1055     }
1056 }
1057
1058 bool AXRenderObject::supportsARIADragging() const
1059 {
1060     const AtomicString& grabbed = getAttribute(aria_grabbedAttr);
1061     return equalIgnoringCase(grabbed, "true") || equalIgnoringCase(grabbed, "false");
1062 }
1063
1064 bool AXRenderObject::supportsARIADropping() const
1065 {
1066     const AtomicString& dropEffect = getAttribute(aria_dropeffectAttr);
1067     return !dropEffect.isEmpty();
1068 }
1069
1070 bool AXRenderObject::supportsARIAFlowTo() const
1071 {
1072     return !getAttribute(aria_flowtoAttr).isEmpty();
1073 }
1074
1075 bool AXRenderObject::supportsARIAOwns() const
1076 {
1077     if (!m_renderer)
1078         return false;
1079     const AtomicString& ariaOwns = getAttribute(aria_ownsAttr);
1080
1081     return !ariaOwns.isEmpty();
1082 }
1083
1084 //
1085 // ARIA live-region features.
1086 //
1087
1088 const AtomicString& AXRenderObject::ariaLiveRegionStatus() const
1089 {
1090     DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusAssertive, ("assertive", AtomicString::ConstructFromLiteral));
1091     DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusPolite, ("polite", AtomicString::ConstructFromLiteral));
1092     DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusOff, ("off", AtomicString::ConstructFromLiteral));
1093
1094     const AtomicString& liveRegionStatus = getAttribute(aria_liveAttr);
1095     // These roles have implicit live region status.
1096     if (liveRegionStatus.isEmpty()) {
1097         switch (roleValue()) {
1098         case AlertDialogRole:
1099         case AlertRole:
1100             return liveRegionStatusAssertive;
1101         case LogRole:
1102         case StatusRole:
1103             return liveRegionStatusPolite;
1104         case TimerRole:
1105         case MarqueeRole:
1106             return liveRegionStatusOff;
1107         default:
1108             break;
1109         }
1110     }
1111
1112     return liveRegionStatus;
1113 }
1114
1115 const AtomicString& AXRenderObject::ariaLiveRegionRelevant() const
1116 {
1117     DEFINE_STATIC_LOCAL(const AtomicString, defaultLiveRegionRelevant, ("additions text", AtomicString::ConstructFromLiteral));
1118     const AtomicString& relevant = getAttribute(aria_relevantAttr);
1119
1120     // Default aria-relevant = "additions text".
1121     if (relevant.isEmpty())
1122         return defaultLiveRegionRelevant;
1123
1124     return relevant;
1125 }
1126
1127 bool AXRenderObject::ariaLiveRegionAtomic() const
1128 {
1129     return elementAttributeValue(aria_atomicAttr);
1130 }
1131
1132 bool AXRenderObject::ariaLiveRegionBusy() const
1133 {
1134     return elementAttributeValue(aria_busyAttr);
1135 }
1136
1137 //
1138 // Accessibility Text.
1139 //
1140
1141 String AXRenderObject::textUnderElement() const
1142 {
1143     if (!m_renderer)
1144         return String();
1145
1146     if (m_renderer->isFileUploadControl())
1147         return toRenderFileUploadControl(m_renderer)->buttonValue();
1148
1149     if (m_renderer->isText())
1150         return toRenderText(m_renderer)->plainText();
1151
1152     return AXNodeObject::textUnderElement();
1153 }
1154
1155 //
1156 // Accessibility Text - (To be deprecated).
1157 //
1158
1159 String AXRenderObject::helpText() const
1160 {
1161     if (!m_renderer)
1162         return String();
1163
1164     const AtomicString& ariaHelp = getAttribute(aria_helpAttr);
1165     if (!ariaHelp.isEmpty())
1166         return ariaHelp;
1167
1168     String describedBy = ariaDescribedByAttribute();
1169     if (!describedBy.isEmpty())
1170         return describedBy;
1171
1172     String description = accessibilityDescription();
1173     for (RenderObject* curr = m_renderer; curr; curr = curr->parent()) {
1174         if (curr->node() && curr->node()->isHTMLElement()) {
1175             const AtomicString& summary = toElement(curr->node())->getAttribute(summaryAttr);
1176             if (!summary.isEmpty())
1177                 return summary;
1178
1179             // The title attribute should be used as help text unless it is already being used as descriptive text.
1180             const AtomicString& title = toElement(curr->node())->getAttribute(titleAttr);
1181             if (!title.isEmpty() && description != title)
1182                 return title;
1183         }
1184
1185         // Only take help text from an ancestor element if its a group or an unknown role. If help was
1186         // added to those kinds of elements, it is likely it was meant for a child element.
1187         AXObject* axObj = axObjectCache()->getOrCreate(curr);
1188         if (axObj) {
1189             AccessibilityRole role = axObj->roleValue();
1190             if (role != GroupRole && role != UnknownRole)
1191                 break;
1192         }
1193     }
1194
1195     return String();
1196 }
1197
1198 //
1199 // Position and size.
1200 //
1201
1202 void AXRenderObject::checkCachedElementRect() const
1203 {
1204     if (m_cachedElementRectDirty)
1205         return;
1206
1207     if (!m_renderer)
1208         return;
1209
1210     if (!m_renderer->isBox())
1211         return;
1212
1213     bool dirty = false;
1214     RenderBox* box = toRenderBox(m_renderer);
1215     if (box->frameRect() != m_cachedFrameRect)
1216         dirty = true;
1217
1218     if (box->canBeScrolledAndHasScrollableArea()) {
1219         ScrollableArea* scrollableArea = box->scrollableArea();
1220         if (scrollableArea && scrollableArea->scrollPosition() != m_cachedScrollPosition)
1221             dirty = true;
1222     }
1223
1224     if (dirty)
1225         markCachedElementRectDirty();
1226 }
1227
1228 void AXRenderObject::updateCachedElementRect() const
1229 {
1230     if (!m_cachedElementRectDirty)
1231         return;
1232
1233     if (!m_renderer)
1234         return;
1235
1236     if (!m_renderer->isBox())
1237         return;
1238
1239     RenderBox* box = toRenderBox(m_renderer);
1240     m_cachedFrameRect = box->frameRect();
1241
1242     if (box->canBeScrolledAndHasScrollableArea()) {
1243         ScrollableArea* scrollableArea = box->scrollableArea();
1244         if (scrollableArea)
1245             m_cachedScrollPosition = scrollableArea->scrollPosition();
1246     }
1247
1248     m_cachedElementRect = computeElementRect();
1249     m_cachedElementRectDirty = false;
1250 }
1251
1252 void AXRenderObject::markCachedElementRectDirty() const
1253 {
1254     if (m_cachedElementRectDirty)
1255         return;
1256
1257     // Marks children recursively, if this element changed.
1258     m_cachedElementRectDirty = true;
1259     for (AXObject* child = firstChild(); child; child = child->nextSibling())
1260         child->markCachedElementRectDirty();
1261 }
1262
1263 IntPoint AXRenderObject::clickPoint()
1264 {
1265     // Headings are usually much wider than their textual content. If the mid point is used, often it can be wrong.
1266     if (isHeading() && children().size() == 1)
1267         return children()[0]->clickPoint();
1268
1269     // use the default position unless this is an editable web area, in which case we use the selection bounds.
1270     if (!isWebArea() || isReadOnly())
1271         return AXObject::clickPoint();
1272
1273     IntRect bounds = pixelSnappedIntRect(elementRect());
1274     return IntPoint(bounds.x() + (bounds.width() / 2), bounds.y() - (bounds.height() / 2));
1275 }
1276
1277 //
1278 // Hit testing.
1279 //
1280
1281 AXObject* AXRenderObject::accessibilityHitTest(const IntPoint& point) const
1282 {
1283     if (!m_renderer || !m_renderer->hasLayer())
1284         return 0;
1285
1286     RenderLayer* layer = toRenderBox(m_renderer)->layer();
1287
1288     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
1289     HitTestResult hitTestResult = HitTestResult(point);
1290     layer->hitTest(request, hitTestResult);
1291     if (!hitTestResult.innerNode())
1292         return 0;
1293
1294     Node* node = hitTestResult.innerNode();
1295     if (node->isInShadowTree())
1296         node = node->shadowHost();
1297
1298     if (isHTMLAreaElement(node))
1299         return accessibilityImageMapHitTest(toHTMLAreaElement(node), point);
1300
1301     if (isHTMLOptionElement(node))
1302         node = toHTMLOptionElement(*node).ownerSelectElement();
1303
1304     RenderObject* obj = node->renderer();
1305     if (!obj)
1306         return 0;
1307
1308     AXObject* result = obj->document().axObjectCache()->getOrCreate(obj);
1309     result->updateChildrenIfNecessary();
1310
1311     // Allow the element to perform any hit-testing it might need to do to reach non-render children.
1312     result = result->elementAccessibilityHitTest(point);
1313
1314     if (result && result->accessibilityIsIgnored()) {
1315         // If this element is the label of a control, a hit test should return the control.
1316         if (result->isAXRenderObject()) {
1317             AXObject* controlObject = toAXRenderObject(result)->correspondingControlForLabelElement();
1318             if (controlObject && !controlObject->exposesTitleUIElement())
1319                 return controlObject;
1320         }
1321
1322         result = result->parentObjectUnignored();
1323     }
1324
1325     return result;
1326 }
1327
1328 AXObject* AXRenderObject::elementAccessibilityHitTest(const IntPoint& point) const
1329 {
1330     if (isSVGImage())
1331         return remoteSVGElementHitTest(point);
1332
1333     return AXObject::elementAccessibilityHitTest(point);
1334 }
1335
1336 //
1337 // High-level accessibility tree access.
1338 //
1339
1340 AXObject* AXRenderObject::parentObject() const
1341 {
1342     if (!m_renderer)
1343         return 0;
1344
1345     if (ariaRoleAttribute() == MenuBarRole)
1346         return axObjectCache()->getOrCreate(m_renderer->parent());
1347
1348     // menuButton and its corresponding menu are DOM siblings, but Accessibility needs them to be parent/child
1349     if (ariaRoleAttribute() == MenuRole) {
1350         AXObject* parent = menuButtonForMenu();
1351         if (parent)
1352             return parent;
1353     }
1354
1355     RenderObject* parentObj = renderParentObject();
1356     if (parentObj)
1357         return axObjectCache()->getOrCreate(parentObj);
1358
1359     // WebArea's parent should be the scroll view containing it.
1360     if (isWebArea())
1361         return axObjectCache()->getOrCreate(m_renderer->frame()->view());
1362
1363     return 0;
1364 }
1365
1366 AXObject* AXRenderObject::parentObjectIfExists() const
1367 {
1368     // WebArea's parent should be the scroll view containing it.
1369     if (isWebArea())
1370         return axObjectCache()->get(m_renderer->frame()->view());
1371
1372     return axObjectCache()->get(renderParentObject());
1373 }
1374
1375 //
1376 // Low-level accessibility tree exploration, only for use within the accessibility module.
1377 //
1378
1379 AXObject* AXRenderObject::firstChild() const
1380 {
1381     if (!m_renderer)
1382         return 0;
1383
1384     RenderObject* firstChild = firstChildConsideringContinuation(m_renderer);
1385
1386     if (!firstChild)
1387         return 0;
1388
1389     return axObjectCache()->getOrCreate(firstChild);
1390 }
1391
1392 AXObject* AXRenderObject::nextSibling() const
1393 {
1394     if (!m_renderer)
1395         return 0;
1396
1397     RenderObject* nextSibling = 0;
1398
1399     RenderInline* inlineContinuation = m_renderer->isRenderBlock() ? toRenderBlock(m_renderer)->inlineElementContinuation() : 0;
1400     if (inlineContinuation) {
1401         // Case 1: node is a block and has an inline continuation. Next sibling is the inline continuation's first child.
1402         nextSibling = firstChildConsideringContinuation(inlineContinuation);
1403     } else if (m_renderer->isAnonymousBlock() && lastChildHasContinuation(m_renderer)) {
1404         // Case 2: Anonymous block parent of the start of a continuation - skip all the way to
1405         // after the parent of the end, since everything in between will be linked up via the continuation.
1406         RenderObject* lastParent = endOfContinuations(toRenderBlock(m_renderer)->lastChild())->parent();
1407         while (lastChildHasContinuation(lastParent))
1408             lastParent = endOfContinuations(lastParent->slowLastChild())->parent();
1409         nextSibling = lastParent->nextSibling();
1410     } else if (RenderObject* ns = m_renderer->nextSibling()) {
1411         // Case 3: node has an actual next sibling
1412         nextSibling = ns;
1413     } else if (isInlineWithContinuation(m_renderer)) {
1414         // Case 4: node is an inline with a continuation. Next sibling is the next sibling of the end
1415         // of the continuation chain.
1416         nextSibling = endOfContinuations(m_renderer)->nextSibling();
1417     } else if (isInlineWithContinuation(m_renderer->parent())) {
1418         // Case 5: node has no next sibling, and its parent is an inline with a continuation.
1419         RenderObject* continuation = toRenderInline(m_renderer->parent())->continuation();
1420
1421         if (continuation->isRenderBlock()) {
1422             // Case 5a: continuation is a block - in this case the block itself is the next sibling.
1423             nextSibling = continuation;
1424         } else {
1425             // Case 5b: continuation is an inline - in this case the inline's first child is the next sibling.
1426             nextSibling = firstChildConsideringContinuation(continuation);
1427         }
1428     }
1429
1430     if (!nextSibling)
1431         return 0;
1432
1433     return axObjectCache()->getOrCreate(nextSibling);
1434 }
1435
1436 void AXRenderObject::addChildren()
1437 {
1438     // If the need to add more children in addition to existing children arises,
1439     // childrenChanged should have been called, leaving the object with no children.
1440     ASSERT(!m_haveChildren);
1441
1442     m_haveChildren = true;
1443
1444     if (!canHaveChildren())
1445         return;
1446
1447     for (RefPtr<AXObject> obj = firstChild(); obj; obj = obj->nextSibling())
1448         addChild(obj.get());
1449
1450     addHiddenChildren();
1451     addAttachmentChildren();
1452     addPopupChildren();
1453     addImageMapChildren();
1454     addTextFieldChildren();
1455     addCanvasChildren();
1456     addRemoteSVGChildren();
1457     addInlineTextBoxChildren();
1458 }
1459
1460 bool AXRenderObject::canHaveChildren() const
1461 {
1462     if (!m_renderer)
1463         return false;
1464
1465     return AXNodeObject::canHaveChildren();
1466 }
1467
1468 void AXRenderObject::updateChildrenIfNecessary()
1469 {
1470     if (needsToUpdateChildren())
1471         clearChildren();
1472
1473     AXObject::updateChildrenIfNecessary();
1474 }
1475
1476 void AXRenderObject::clearChildren()
1477 {
1478     AXObject::clearChildren();
1479     m_childrenDirty = false;
1480 }
1481
1482 AXObject* AXRenderObject::observableObject() const
1483 {
1484     // Find the object going up the parent chain that is used in accessibility to monitor certain notifications.
1485     for (RenderObject* renderer = m_renderer; renderer && renderer->node(); renderer = renderer->parent()) {
1486         if (renderObjectIsObservable(renderer))
1487             return axObjectCache()->getOrCreate(renderer);
1488     }
1489
1490     return 0;
1491 }
1492
1493 //
1494 // Properties of the object's owning document or page.
1495 //
1496
1497 double AXRenderObject::estimatedLoadingProgress() const
1498 {
1499     if (!m_renderer)
1500         return 0;
1501
1502     if (isLoaded())
1503         return 1.0;
1504
1505     if (LocalFrame* frame = m_renderer->document().frame())
1506         return frame->loader().progress().estimatedProgress();
1507     return 0;
1508 }
1509
1510 //
1511 // DOM and Render tree access.
1512 //
1513
1514 Node* AXRenderObject::node() const
1515 {
1516     return m_renderer ? m_renderer->node() : 0;
1517 }
1518
1519 Document* AXRenderObject::document() const
1520 {
1521     if (!m_renderer)
1522         return 0;
1523     return &m_renderer->document();
1524 }
1525
1526 FrameView* AXRenderObject::documentFrameView() const
1527 {
1528     if (!m_renderer)
1529         return 0;
1530
1531     // this is the RenderObject's Document's LocalFrame's FrameView
1532     return m_renderer->document().view();
1533 }
1534
1535 Element* AXRenderObject::anchorElement() const
1536 {
1537     if (!m_renderer)
1538         return 0;
1539
1540     AXObjectCache* cache = axObjectCache();
1541     RenderObject* currRenderer;
1542
1543     // Search up the render tree for a RenderObject with a DOM node. Defer to an earlier continuation, though.
1544     for (currRenderer = m_renderer; currRenderer && !currRenderer->node(); currRenderer = currRenderer->parent()) {
1545         if (currRenderer->isAnonymousBlock()) {
1546             RenderObject* continuation = toRenderBlock(currRenderer)->continuation();
1547             if (continuation)
1548                 return cache->getOrCreate(continuation)->anchorElement();
1549         }
1550     }
1551
1552     // bail if none found
1553     if (!currRenderer)
1554         return 0;
1555
1556     // search up the DOM tree for an anchor element
1557     // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
1558     Node* node = currRenderer->node();
1559     for ( ; node; node = node->parentNode()) {
1560         if (isHTMLAnchorElement(*node) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
1561             return toElement(node);
1562     }
1563
1564     return 0;
1565 }
1566
1567 Widget* AXRenderObject::widgetForAttachmentView() const
1568 {
1569     if (!isAttachment())
1570         return 0;
1571     return toRenderWidget(m_renderer)->widget();
1572 }
1573
1574 //
1575 // Selected text.
1576 //
1577
1578 AXObject::PlainTextRange AXRenderObject::selectedTextRange() const
1579 {
1580     if (!isTextControl())
1581         return PlainTextRange();
1582
1583     if (isPasswordField())
1584         return PlainTextRange();
1585
1586     AccessibilityRole ariaRole = ariaRoleAttribute();
1587     if (isNativeTextControl() && ariaRole == UnknownRole && m_renderer->isTextControl()) {
1588         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
1589         return PlainTextRange(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart());
1590     }
1591
1592     if (ariaRole == UnknownRole)
1593         return PlainTextRange();
1594
1595     return ariaSelectedTextRange();
1596 }
1597
1598 VisibleSelection AXRenderObject::selection() const
1599 {
1600     return m_renderer->frame()->selection().selection();
1601 }
1602
1603 //
1604 // Modify or take an action on an object.
1605 //
1606
1607 void AXRenderObject::setSelectedTextRange(const PlainTextRange& range)
1608 {
1609     if (isNativeTextControl() && m_renderer->isTextControl()) {
1610         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
1611         textControl->setSelectionRange(range.start, range.start + range.length);
1612         return;
1613     }
1614
1615     Document& document = m_renderer->document();
1616     LocalFrame* frame = document.frame();
1617     if (!frame)
1618         return;
1619     Node* node = m_renderer->node();
1620     frame->selection().setSelection(VisibleSelection(Position(node, range.start, Position::PositionIsOffsetInAnchor),
1621         Position(node, range.start + range.length, Position::PositionIsOffsetInAnchor), DOWNSTREAM));
1622 }
1623
1624 void AXRenderObject::setValue(const String& string)
1625 {
1626     if (!node() || !node()->isElementNode())
1627         return;
1628     if (!m_renderer || !m_renderer->isBoxModelObject())
1629         return;
1630
1631     RenderBoxModelObject* renderer = toRenderBoxModelObject(m_renderer);
1632     if (renderer->isTextField() && isHTMLInputElement(*node()))
1633         toHTMLInputElement(*node()).setValue(string);
1634     else if (renderer->isTextArea() && isHTMLTextAreaElement(*node()))
1635         toHTMLTextAreaElement(*node()).setValue(string);
1636 }
1637
1638 // FIXME: This function should use an IntSize to avoid the conversion below.
1639 void AXRenderObject::scrollTo(const IntPoint& point) const
1640 {
1641     if (!m_renderer || !m_renderer->isBox())
1642         return;
1643
1644     RenderBox* box = toRenderBox(m_renderer);
1645     if (!box->canBeScrolledAndHasScrollableArea())
1646         return;
1647
1648     box->scrollToOffset(IntSize(point.x(), point.y()));
1649 }
1650
1651 //
1652 // Notifications that this object may have changed.
1653 //
1654
1655 void AXRenderObject::handleActiveDescendantChanged()
1656 {
1657     Element* element = toElement(renderer()->node());
1658     if (!element)
1659         return;
1660     Document& doc = renderer()->document();
1661     if (!doc.frame()->selection().isFocusedAndActive() || doc.focusedElement() != element)
1662         return;
1663     AXRenderObject* activedescendant = toAXRenderObject(activeDescendant());
1664
1665     if (activedescendant && shouldNotifyActiveDescendant())
1666         doc.axObjectCache()->postNotification(m_renderer, AXObjectCache::AXActiveDescendantChanged, true);
1667 }
1668
1669 void AXRenderObject::handleAriaExpandedChanged()
1670 {
1671     // Find if a parent of this object should handle aria-expanded changes.
1672     AXObject* containerParent = this->parentObject();
1673     while (containerParent) {
1674         bool foundParent = false;
1675
1676         switch (containerParent->roleValue()) {
1677         case TreeRole:
1678         case TreeGridRole:
1679         case GridRole:
1680         case TableRole:
1681         case BrowserRole:
1682             foundParent = true;
1683             break;
1684         default:
1685             break;
1686         }
1687
1688         if (foundParent)
1689             break;
1690
1691         containerParent = containerParent->parentObject();
1692     }
1693
1694     // Post that the row count changed.
1695     if (containerParent)
1696         axObjectCache()->postNotification(containerParent, document(), AXObjectCache::AXRowCountChanged, true);
1697
1698     // Post that the specific row either collapsed or expanded.
1699     if (roleValue() == RowRole || roleValue() == TreeItemRole)
1700         axObjectCache()->postNotification(this, document(), isExpanded() ? AXObjectCache::AXRowExpanded : AXObjectCache::AXRowCollapsed, true);
1701 }
1702
1703 void AXRenderObject::textChanged()
1704 {
1705     if (!m_renderer)
1706         return;
1707
1708     Settings* settings = document()->settings();
1709     if (settings && settings->inlineTextBoxAccessibilityEnabled() && roleValue() == StaticTextRole)
1710         childrenChanged();
1711
1712     // Do this last - AXNodeObject::textChanged posts live region announcements,
1713     // and we should update the inline text boxes first.
1714     AXNodeObject::textChanged();
1715 }
1716
1717 //
1718 // Text metrics. Most of these should be deprecated, needs major cleanup.
1719 //
1720
1721 // NOTE: Consider providing this utility method as AX API
1722 int AXRenderObject::index(const VisiblePosition& position) const
1723 {
1724     if (position.isNull() || !isTextControl())
1725         return -1;
1726
1727     if (renderObjectContainsPosition(m_renderer, position.deepEquivalent()))
1728         return indexForVisiblePosition(position);
1729
1730     return -1;
1731 }
1732
1733 VisiblePosition AXRenderObject::visiblePositionForIndex(int index) const
1734 {
1735     if (!m_renderer)
1736         return VisiblePosition();
1737
1738     if (isNativeTextControl() && m_renderer->isTextControl())
1739         return toRenderTextControl(m_renderer)->textFormControlElement()->visiblePositionForIndex(index);
1740
1741     if (!allowsTextRanges() && !m_renderer->isText())
1742         return VisiblePosition();
1743
1744     Node* node = m_renderer->node();
1745     if (!node)
1746         return VisiblePosition();
1747
1748     if (index <= 0)
1749         return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
1750
1751     Position start, end;
1752     bool selected = Range::selectNodeContents(node, start, end);
1753     if (!selected)
1754         return VisiblePosition();
1755
1756     CharacterIterator it(start, end);
1757     it.advance(index - 1);
1758     return VisiblePosition(Position(it.endContainer(), it.endOffset(), Position::PositionIsOffsetInAnchor), UPSTREAM);
1759 }
1760
1761 int AXRenderObject::indexForVisiblePosition(const VisiblePosition& pos) const
1762 {
1763     if (isNativeTextControl() && m_renderer->isTextControl()) {
1764         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
1765         return textControl->indexForVisiblePosition(pos);
1766     }
1767
1768     if (!isTextControl())
1769         return 0;
1770
1771     Node* node = m_renderer->node();
1772     if (!node)
1773         return 0;
1774
1775     Position indexPosition = pos.deepEquivalent();
1776     if (indexPosition.isNull() || highestEditableRoot(indexPosition, HasEditableAXRole) != node)
1777         return 0;
1778
1779     RefPtrWillBeRawPtr<Range> range = Range::create(m_renderer->document());
1780     range->setStart(node, 0, IGNORE_EXCEPTION);
1781     range->setEnd(indexPosition, IGNORE_EXCEPTION);
1782
1783     return TextIterator::rangeLength(range.get());
1784 }
1785
1786 void AXRenderObject::addInlineTextBoxChildren()
1787 {
1788     Settings* settings = document()->settings();
1789     if (!settings || !settings->inlineTextBoxAccessibilityEnabled())
1790         return;
1791
1792     if (!renderer() || !renderer()->isText())
1793         return;
1794
1795     if (renderer()->needsLayout()) {
1796         // If a RenderText needs layout, its inline text boxes are either
1797         // nonexistent or invalid, so defer until the layout happens and
1798         // the renderer calls AXObjectCache::inlineTextBoxesUpdated.
1799         return;
1800     }
1801
1802     RenderText* renderText = toRenderText(renderer());
1803     for (RefPtr<AbstractInlineTextBox> box = renderText->firstAbstractInlineTextBox(); box.get(); box = box->nextInlineTextBox()) {
1804         AXObject* axObject = axObjectCache()->getOrCreate(box.get());
1805         if (!axObject->accessibilityIsIgnored())
1806             m_children.append(axObject);
1807     }
1808 }
1809
1810 void AXRenderObject::lineBreaks(Vector<int>& lineBreaks) const
1811 {
1812     if (!isTextControl())
1813         return;
1814
1815     VisiblePosition visiblePos = visiblePositionForIndex(0);
1816     VisiblePosition savedVisiblePos = visiblePos;
1817     visiblePos = nextLinePosition(visiblePos, 0);
1818     while (!visiblePos.isNull() && visiblePos != savedVisiblePos) {
1819         lineBreaks.append(indexForVisiblePosition(visiblePos));
1820         savedVisiblePos = visiblePos;
1821         visiblePos = nextLinePosition(visiblePos, 0);
1822     }
1823 }
1824
1825 //
1826 // Private.
1827 //
1828
1829 bool AXRenderObject::isAllowedChildOfTree() const
1830 {
1831     // Determine if this is in a tree. If so, we apply special behavior to make it work like an AXOutline.
1832     AXObject* axObj = parentObject();
1833     bool isInTree = false;
1834     while (axObj) {
1835         if (axObj->isTree()) {
1836             isInTree = true;
1837             break;
1838         }
1839         axObj = axObj->parentObject();
1840     }
1841
1842     // If the object is in a tree, only tree items should be exposed (and the children of tree items).
1843     if (isInTree) {
1844         AccessibilityRole role = roleValue();
1845         if (role != TreeItemRole && role != StaticTextRole)
1846             return false;
1847     }
1848     return true;
1849 }
1850
1851 void AXRenderObject::ariaListboxSelectedChildren(AccessibilityChildrenVector& result)
1852 {
1853     bool isMulti = isMultiSelectable();
1854
1855     AccessibilityChildrenVector childObjects = children();
1856     unsigned childrenSize = childObjects.size();
1857     for (unsigned k = 0; k < childrenSize; ++k) {
1858         // Every child should have aria-role option, and if so, check for selected attribute/state.
1859         AXObject* child = childObjects[k].get();
1860         if (child->isSelected() && child->ariaRoleAttribute() == ListBoxOptionRole) {
1861             result.append(child);
1862             if (!isMulti)
1863                 return;
1864         }
1865     }
1866 }
1867
1868 AXObject::PlainTextRange AXRenderObject::ariaSelectedTextRange() const
1869 {
1870     Node* node = m_renderer->node();
1871     if (!node)
1872         return PlainTextRange();
1873
1874     VisibleSelection visibleSelection = selection();
1875     RefPtrWillBeRawPtr<Range> currentSelectionRange = visibleSelection.toNormalizedRange();
1876     if (!currentSelectionRange || !currentSelectionRange->intersectsNode(node, IGNORE_EXCEPTION))
1877         return PlainTextRange();
1878
1879     int start = indexForVisiblePosition(visibleSelection.visibleStart());
1880     int end = indexForVisiblePosition(visibleSelection.visibleEnd());
1881
1882     return PlainTextRange(start, end - start);
1883 }
1884
1885 bool AXRenderObject::nodeIsTextControl(const Node* node) const
1886 {
1887     if (!node)
1888         return false;
1889
1890     const AXObject* axObjectForNode = axObjectCache()->getOrCreate(const_cast<Node*>(node));
1891     if (!axObjectForNode)
1892         return false;
1893
1894     return axObjectForNode->isTextControl();
1895 }
1896
1897 bool AXRenderObject::isTabItemSelected() const
1898 {
1899     if (!isTabItem() || !m_renderer)
1900         return false;
1901
1902     Node* node = m_renderer->node();
1903     if (!node || !node->isElementNode())
1904         return false;
1905
1906     // The ARIA spec says a tab item can also be selected if it is aria-labeled by a tabpanel
1907     // that has keyboard focus inside of it, or if a tabpanel in its aria-controls list has KB
1908     // focus inside of it.
1909     AXObject* focusedElement = focusedUIElement();
1910     if (!focusedElement)
1911         return false;
1912
1913     WillBeHeapVector<RawPtrWillBeMember<Element> > elements;
1914     elementsFromAttribute(elements, aria_controlsAttr);
1915
1916     unsigned count = elements.size();
1917     for (unsigned k = 0; k < count; ++k) {
1918         Element* element = elements[k];
1919         AXObject* tabPanel = axObjectCache()->getOrCreate(element);
1920
1921         // A tab item should only control tab panels.
1922         if (!tabPanel || tabPanel->roleValue() != TabPanelRole)
1923             continue;
1924
1925         AXObject* checkFocusElement = focusedElement;
1926         // Check if the focused element is a descendant of the element controlled by the tab item.
1927         while (checkFocusElement) {
1928             if (tabPanel == checkFocusElement)
1929                 return true;
1930             checkFocusElement = checkFocusElement->parentObject();
1931         }
1932     }
1933
1934     return false;
1935 }
1936
1937 AXObject* AXRenderObject::accessibilityImageMapHitTest(HTMLAreaElement* area, const IntPoint& point) const
1938 {
1939     if (!area)
1940         return 0;
1941
1942     AXObject* parent = axObjectCache()->getOrCreate(area->imageElement());
1943     if (!parent)
1944         return 0;
1945
1946     AXObject::AccessibilityChildrenVector children = parent->children();
1947     unsigned count = children.size();
1948     for (unsigned k = 0; k < count; ++k) {
1949         if (children[k]->elementRect().contains(point))
1950             return children[k].get();
1951     }
1952
1953     return 0;
1954 }
1955
1956 bool AXRenderObject::renderObjectIsObservable(RenderObject* renderer) const
1957 {
1958     // AX clients will listen for AXValueChange on a text control.
1959     if (renderer->isTextControl())
1960         return true;
1961
1962     // AX clients will listen for AXSelectedChildrenChanged on listboxes.
1963     Node* node = renderer->node();
1964     if (nodeHasRole(node, "listbox") || (renderer->isBoxModelObject() && toRenderBoxModelObject(renderer)->isListBox()))
1965         return true;
1966
1967     // Textboxes should send out notifications.
1968     if (nodeHasRole(node, "textbox"))
1969         return true;
1970
1971     return false;
1972 }
1973
1974 RenderObject* AXRenderObject::renderParentObject() const
1975 {
1976     if (!m_renderer)
1977         return 0;
1978
1979     RenderObject* startOfConts = m_renderer->isRenderBlock() ? startOfContinuations(m_renderer) : 0;
1980     if (startOfConts) {
1981         // Case 1: node is a block and is an inline's continuation. Parent
1982         // is the start of the continuation chain.
1983         return startOfConts;
1984     }
1985
1986     RenderObject* parent = m_renderer->parent();
1987     startOfConts = parent && parent->isRenderInline() ? startOfContinuations(parent) : 0;
1988     if (startOfConts) {
1989         // Case 2: node's parent is an inline which is some node's continuation; parent is
1990         // the earliest node in the continuation chain.
1991         return startOfConts;
1992     }
1993
1994     RenderObject* firstChild = parent ? parent->slowFirstChild() : 0;
1995     if (firstChild && firstChild->node()) {
1996         // Case 3: The first sibling is the beginning of a continuation chain. Find the origin of that continuation.
1997         // Get the node's renderer and follow that continuation chain until the first child is found.
1998         for (RenderObject* nodeRenderFirstChild = firstChild->node()->renderer(); nodeRenderFirstChild != firstChild; nodeRenderFirstChild = firstChild->node()->renderer()) {
1999             for (RenderObject* contsTest = nodeRenderFirstChild; contsTest; contsTest = nextContinuation(contsTest)) {
2000                 if (contsTest == firstChild) {
2001                     parent = nodeRenderFirstChild->parent();
2002                     break;
2003                 }
2004             }
2005             RenderObject* newFirstChild = parent->slowFirstChild();
2006             if (firstChild == newFirstChild)
2007                 break;
2008             firstChild = newFirstChild;
2009             if (!firstChild->node())
2010                 break;
2011         }
2012     }
2013
2014     return parent;
2015 }
2016
2017 bool AXRenderObject::isDescendantOfElementType(const HTMLQualifiedName& tagName) const
2018 {
2019     for (RenderObject* parent = m_renderer->parent(); parent; parent = parent->parent()) {
2020         if (parent->node() && parent->node()->hasTagName(tagName))
2021             return true;
2022     }
2023     return false;
2024 }
2025
2026 bool AXRenderObject::isSVGImage() const
2027 {
2028     return remoteSVGRootElement();
2029 }
2030
2031 void AXRenderObject::detachRemoteSVGRoot()
2032 {
2033     if (AXSVGRoot* root = remoteSVGRootElement())
2034         root->setParent(0);
2035 }
2036
2037 AXSVGRoot* AXRenderObject::remoteSVGRootElement() const
2038 {
2039     if (!m_renderer || !m_renderer->isRenderImage())
2040         return 0;
2041
2042     ImageResource* cachedImage = toRenderImage(m_renderer)->cachedImage();
2043     if (!cachedImage)
2044         return 0;
2045
2046     Image* image = cachedImage->image();
2047     if (!image || !image->isSVGImage())
2048         return 0;
2049
2050     FrameView* frameView = toSVGImage(image)->frameView();
2051     if (!frameView)
2052         return 0;
2053     Document* doc = frameView->frame().document();
2054     if (!doc || !doc->isSVGDocument())
2055         return 0;
2056
2057     Settings* settings = doc->settings();
2058     if (settings && !settings->accessibilityEnabled())
2059         settings->setAccessibilityEnabled(true);
2060
2061     SVGSVGElement* rootElement = doc->accessSVGExtensions().rootElement();
2062     if (!rootElement)
2063         return 0;
2064     RenderObject* rendererRoot = rootElement->renderer();
2065     if (!rendererRoot)
2066         return 0;
2067
2068     AXObject* rootSVGObject = doc->axObjectCache()->getOrCreate(rendererRoot);
2069
2070     // In order to connect the AX hierarchy from the SVG root element from the loaded resource
2071     // the parent must be set, because there's no other way to get back to who created the image.
2072     ASSERT(rootSVGObject && rootSVGObject->isAXSVGRoot());
2073     if (!rootSVGObject->isAXSVGRoot())
2074         return 0;
2075
2076     return toAXSVGRoot(rootSVGObject);
2077 }
2078
2079 AXObject* AXRenderObject::remoteSVGElementHitTest(const IntPoint& point) const
2080 {
2081     AXObject* remote = remoteSVGRootElement();
2082     if (!remote)
2083         return 0;
2084
2085     IntSize offset = point - roundedIntPoint(elementRect().location());
2086     return remote->accessibilityHitTest(IntPoint(offset));
2087 }
2088
2089 // The boundingBox for elements within the remote SVG element needs to be offset by its position
2090 // within the parent page, otherwise they are in relative coordinates only.
2091 void AXRenderObject::offsetBoundingBoxForRemoteSVGElement(LayoutRect& rect) const
2092 {
2093     for (AXObject* parent = parentObject(); parent; parent = parent->parentObject()) {
2094         if (parent->isAXSVGRoot()) {
2095             rect.moveBy(parent->parentObject()->elementRect().location());
2096             break;
2097         }
2098     }
2099 }
2100
2101 // Hidden children are those that are not rendered or visible, but are specifically marked as aria-hidden=false,
2102 // meaning that they should be exposed to the AX hierarchy.
2103 void AXRenderObject::addHiddenChildren()
2104 {
2105     Node* node = this->node();
2106     if (!node)
2107         return;
2108
2109     // First do a quick run through to determine if we have any hidden nodes (most often we will not).
2110     // If we do have hidden nodes, we need to determine where to insert them so they match DOM order as close as possible.
2111     bool shouldInsertHiddenNodes = false;
2112     for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
2113         if (!child->renderer() && isNodeAriaVisible(child)) {
2114             shouldInsertHiddenNodes = true;
2115             break;
2116         }
2117     }
2118
2119     if (!shouldInsertHiddenNodes)
2120         return;
2121
2122     // Iterate through all of the children, including those that may have already been added, and
2123     // try to insert hidden nodes in the correct place in the DOM order.
2124     unsigned insertionIndex = 0;
2125     for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
2126         if (child->renderer()) {
2127             // Find out where the last render sibling is located within m_children.
2128             AXObject* childObject = axObjectCache()->get(child->renderer());
2129             if (childObject && childObject->accessibilityIsIgnored()) {
2130                 AccessibilityChildrenVector children = childObject->children();
2131                 if (children.size())
2132                     childObject = children.last().get();
2133                 else
2134                     childObject = 0;
2135             }
2136
2137             if (childObject)
2138                 insertionIndex = m_children.find(childObject) + 1;
2139             continue;
2140         }
2141
2142         if (!isNodeAriaVisible(child))
2143             continue;
2144
2145         unsigned previousSize = m_children.size();
2146         if (insertionIndex > previousSize)
2147             insertionIndex = previousSize;
2148
2149         insertChild(axObjectCache()->getOrCreate(child), insertionIndex);
2150         insertionIndex += (m_children.size() - previousSize);
2151     }
2152 }
2153
2154 void AXRenderObject::addTextFieldChildren()
2155 {
2156     Node* node = this->node();
2157     if (!isHTMLInputElement(node))
2158         return;
2159
2160     HTMLInputElement& input = toHTMLInputElement(*node);
2161     Element* spinButtonElement = input.userAgentShadowRoot()->getElementById(ShadowElementNames::spinButton());
2162     if (!spinButtonElement || !spinButtonElement->isSpinButtonElement())
2163         return;
2164
2165     AXSpinButton* axSpinButton = toAXSpinButton(axObjectCache()->getOrCreate(SpinButtonRole));
2166     axSpinButton->setSpinButtonElement(toSpinButtonElement(spinButtonElement));
2167     axSpinButton->setParent(this);
2168     m_children.append(axSpinButton);
2169 }
2170
2171 void AXRenderObject::addImageMapChildren()
2172 {
2173     RenderBoxModelObject* cssBox = renderBoxModelObject();
2174     if (!cssBox || !cssBox->isRenderImage())
2175         return;
2176
2177     HTMLMapElement* map = toRenderImage(cssBox)->imageMap();
2178     if (!map)
2179         return;
2180
2181     for (HTMLAreaElement* area = Traversal<HTMLAreaElement>::firstWithin(*map); area; area = Traversal<HTMLAreaElement>::next(*area, map)) {
2182         // add an <area> element for this child if it has a link
2183         if (area->isLink()) {
2184             AXImageMapLink* areaObject = toAXImageMapLink(axObjectCache()->getOrCreate(ImageMapLinkRole));
2185             areaObject->setHTMLAreaElement(area);
2186             areaObject->setHTMLMapElement(map);
2187             areaObject->setParent(this);
2188             if (!areaObject->accessibilityIsIgnored())
2189                 m_children.append(areaObject);
2190             else
2191                 axObjectCache()->remove(areaObject->axObjectID());
2192         }
2193     }
2194 }
2195
2196 void AXRenderObject::addCanvasChildren()
2197 {
2198     if (!isHTMLCanvasElement(node()))
2199         return;
2200
2201     // If it's a canvas, it won't have rendered children, but it might have accessible fallback content.
2202     // Clear m_haveChildren because AXNodeObject::addChildren will expect it to be false.
2203     ASSERT(!m_children.size());
2204     m_haveChildren = false;
2205     AXNodeObject::addChildren();
2206 }
2207
2208 void AXRenderObject::addAttachmentChildren()
2209 {
2210     if (!isAttachment())
2211         return;
2212
2213     // FrameView's need to be inserted into the AX hierarchy when encountered.
2214     Widget* widget = widgetForAttachmentView();
2215     if (!widget || !widget->isFrameView())
2216         return;
2217
2218     AXObject* axWidget = axObjectCache()->getOrCreate(widget);
2219     if (!axWidget->accessibilityIsIgnored())
2220         m_children.append(axWidget);
2221 }
2222
2223 void AXRenderObject::addPopupChildren()
2224 {
2225     if (!isHTMLInputElement(node()))
2226         return;
2227     if (AXObject* axPopup = toHTMLInputElement(node())->popupRootAXObject())
2228         m_children.append(axPopup);
2229 }
2230
2231 void AXRenderObject::addRemoteSVGChildren()
2232 {
2233     AXSVGRoot* root = remoteSVGRootElement();
2234     if (!root)
2235         return;
2236
2237     root->setParent(this);
2238
2239     if (root->accessibilityIsIgnored()) {
2240         AccessibilityChildrenVector children = root->children();
2241         unsigned length = children.size();
2242         for (unsigned i = 0; i < length; ++i)
2243             m_children.append(children[i]);
2244     } else {
2245         m_children.append(root);
2246     }
2247 }
2248
2249 void AXRenderObject::ariaSelectedRows(AccessibilityChildrenVector& result)
2250 {
2251     // Get all the rows.
2252     AccessibilityChildrenVector allRows;
2253     if (isTree())
2254         ariaTreeRows(allRows);
2255     else if (isAXTable() && toAXTable(this)->supportsSelectedRows())
2256         allRows = toAXTable(this)->rows();
2257
2258     // Determine which rows are selected.
2259     bool isMulti = isMultiSelectable();
2260
2261     // Prefer active descendant over aria-selected.
2262     AXObject* activeDesc = activeDescendant();
2263     if (activeDesc && (activeDesc->isTreeItem() || activeDesc->isTableRow())) {
2264         result.append(activeDesc);
2265         if (!isMulti)
2266             return;
2267     }
2268
2269     unsigned count = allRows.size();
2270     for (unsigned k = 0; k < count; ++k) {
2271         if (allRows[k]->isSelected()) {
2272             result.append(allRows[k]);
2273             if (!isMulti)
2274                 break;
2275         }
2276     }
2277 }
2278
2279 bool AXRenderObject::elementAttributeValue(const QualifiedName& attributeName) const
2280 {
2281     if (!m_renderer)
2282         return false;
2283
2284     return equalIgnoringCase(getAttribute(attributeName), "true");
2285 }
2286
2287 bool AXRenderObject::inheritsPresentationalRole() const
2288 {
2289     // ARIA states if an item can get focus, it should not be presentational.
2290     if (canSetFocusAttribute())
2291         return false;
2292
2293     // ARIA spec says that when a parent object is presentational, and it has required child elements,
2294     // those child elements are also presentational. For example, <li> becomes presentational from <ul>.
2295     // http://www.w3.org/WAI/PF/aria/complete#presentation
2296     if (roleValue() != ListItemRole && roleValue() != ListMarkerRole)
2297         return false;
2298
2299     AXObject* parent = parentObject();
2300     if (!parent->isAXRenderObject())
2301         return false;
2302
2303     Node* elementNode = toAXRenderObject(parent)->node();
2304     if (!elementNode || !elementNode->isElementNode())
2305         return false;
2306
2307     QualifiedName tagName = toElement(elementNode)->tagQName();
2308     if (tagName == ulTag || tagName == olTag || tagName == dlTag)
2309         return (parent->roleValue() == NoneRole || parent->roleValue() == PresentationalRole);
2310
2311     return false;
2312 }
2313
2314 LayoutRect AXRenderObject::computeElementRect() const
2315 {
2316     RenderObject* obj = m_renderer;
2317
2318     if (!obj)
2319         return LayoutRect();
2320
2321     if (obj->node()) // If we are a continuation, we want to make sure to use the primary renderer.
2322         obj = obj->node()->renderer();
2323
2324     // absoluteFocusRingQuads will query the hierarchy below this element, which for large webpages can be very slow.
2325     // For a web area, which will have the most elements of any element, absoluteQuads should be used.
2326     // We should also use absoluteQuads for SVG elements, otherwise transforms won't be applied.
2327     Vector<FloatQuad> quads;
2328
2329     if (obj->isText())
2330         toRenderText(obj)->absoluteQuads(quads, 0, RenderText::ClipToEllipsis);
2331     else if (isWebArea() || obj->isSVGRoot())
2332         obj->absoluteQuads(quads);
2333     else
2334         obj->absoluteFocusRingQuads(quads);
2335
2336     LayoutRect result = boundingBoxForQuads(obj, quads);
2337
2338     Document* document = this->document();
2339     if (document && document->isSVGDocument())
2340         offsetBoundingBoxForRemoteSVGElement(result);
2341     if (document && document->frame() && document->frame()->pagePopupOwner()) {
2342         IntPoint popupOrigin = document->view()->contentsToScreen(IntRect()).location();
2343         IntPoint mainOrigin = axObjectCache()->rootObject()->documentFrameView()->contentsToScreen(IntRect()).location();
2344         result.moveBy(IntPoint(popupOrigin - mainOrigin));
2345     }
2346
2347     // The size of the web area should be the content size, not the clipped size.
2348     if (isWebArea() && obj->frame()->view())
2349         result.setSize(obj->frame()->view()->contentsSize());
2350
2351     // Checkboxes and radio buttons include their label as part of their rect.
2352     if (isCheckboxOrRadio()) {
2353         HTMLLabelElement* label = labelForElement(toElement(m_renderer->node()));
2354         if (label && label->renderer()) {
2355             LayoutRect labelRect = axObjectCache()->getOrCreate(label)->elementRect();
2356             result.unite(labelRect);
2357         }
2358     }
2359
2360     return result;
2361 }
2362
2363 } // namespace blink