initial import
[vuplus_webkit] / Source / WebCore / accessibility / AccessibilityRenderObject.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 "AccessibilityRenderObject.h"
31
32 #include "AXObjectCache.h"
33 #include "AccessibilityImageMapLink.h"
34 #include "AccessibilityListBox.h"
35 #include "EventNames.h"
36 #include "FloatRect.h"
37 #include "Frame.h"
38 #include "FrameLoader.h"
39 #include "FrameSelection.h"
40 #include "HTMLAreaElement.h"
41 #include "HTMLFormElement.h"
42 #include "HTMLFrameElementBase.h"
43 #include "HTMLImageElement.h"
44 #include "HTMLInputElement.h"
45 #include "HTMLLabelElement.h"
46 #include "HTMLMapElement.h"
47 #include "HTMLNames.h"
48 #include "HTMLOptGroupElement.h"
49 #include "HTMLOptionElement.h"
50 #include "HTMLOptionsCollection.h"
51 #include "HTMLSelectElement.h"
52 #include "HTMLTextAreaElement.h"
53 #include "HitTestRequest.h"
54 #include "HitTestResult.h"
55 #include "LocalizedStrings.h"
56 #include "MathMLNames.h"
57 #include "NodeList.h"
58 #include "Page.h"
59 #include "ProgressTracker.h"
60 #include "RenderButton.h"
61 #include "RenderFieldset.h"
62 #include "RenderFileUploadControl.h"
63 #include "RenderHTMLCanvas.h"
64 #include "RenderImage.h"
65 #include "RenderInline.h"
66 #include "RenderLayer.h"
67 #include "RenderListBox.h"
68 #include "RenderListMarker.h"
69 #include "RenderMenuList.h"
70 #include "RenderText.h"
71 #include "RenderTextControl.h"
72 #include "RenderTextFragment.h"
73 #include "RenderTheme.h"
74 #include "RenderView.h"
75 #include "RenderWidget.h"
76 #include "RenderedPosition.h"
77 #include "SelectElement.h"
78 #include "Text.h"
79 #include "TextIterator.h"
80 #include "htmlediting.h"
81 #include "visible_units.h"
82 #include <wtf/StdLibExtras.h>
83 #include <wtf/text/StringBuilder.h>
84 #include <wtf/unicode/CharacterNames.h>
85
86 using namespace std;
87
88 namespace WebCore {
89
90 using namespace HTMLNames;
91
92 AccessibilityRenderObject::AccessibilityRenderObject(RenderObject* renderer)
93     : AccessibilityObject()
94     , m_renderer(renderer)
95     , m_ariaRole(UnknownRole)
96     , m_childrenDirty(false)
97     , m_roleForMSAA(UnknownRole)
98 {
99     m_role = determineAccessibilityRole();
100
101 #ifndef NDEBUG
102     m_renderer->setHasAXObject(true);
103 #endif
104 }
105
106 AccessibilityRenderObject::~AccessibilityRenderObject()
107 {
108     ASSERT(isDetached());
109 }
110
111 PassRefPtr<AccessibilityRenderObject> AccessibilityRenderObject::create(RenderObject* renderer)
112 {
113     return adoptRef(new AccessibilityRenderObject(renderer));
114 }
115
116 void AccessibilityRenderObject::detach()
117 {
118     clearChildren();
119     AccessibilityObject::detach();
120     
121 #ifndef NDEBUG
122     if (m_renderer)
123         m_renderer->setHasAXObject(false);
124 #endif
125     m_renderer = 0;    
126 }
127
128 RenderBoxModelObject* AccessibilityRenderObject::renderBoxModelObject() const
129 {
130     if (!m_renderer || !m_renderer->isBoxModelObject())
131         return 0;
132     return toRenderBoxModelObject(m_renderer);
133 }
134
135 static inline bool isInlineWithContinuation(RenderObject* object)
136 {
137     if (!object->isBoxModelObject())
138         return false;
139
140     RenderBoxModelObject* renderer = toRenderBoxModelObject(object);
141     if (!renderer->isRenderInline())
142         return false;
143
144     return toRenderInline(renderer)->continuation();
145 }
146
147 static inline RenderObject* firstChildInContinuation(RenderObject* renderer)
148 {
149     RenderObject* r = toRenderInline(renderer)->continuation();
150
151     while (r) {
152         if (r->isRenderBlock())
153             return r;
154         if (RenderObject* child = r->firstChild())
155             return child;
156         r = toRenderInline(r)->continuation(); 
157     }
158
159     return 0;
160 }
161
162 static inline RenderObject* firstChildConsideringContinuation(RenderObject* renderer)
163 {
164     RenderObject* firstChild = renderer->firstChild();
165
166     if (!firstChild && isInlineWithContinuation(renderer))
167         firstChild = firstChildInContinuation(renderer);
168
169     return firstChild;
170 }
171
172
173 static inline RenderObject* lastChildConsideringContinuation(RenderObject* renderer)
174 {
175     RenderObject* lastChild = renderer->lastChild();
176     RenderObject* prev;
177     RenderObject* cur = renderer;
178
179     if (!cur->isRenderInline() && !cur->isRenderBlock())
180         return renderer;
181
182     while (cur) {
183         prev = cur;
184
185         if (RenderObject* lc = cur->lastChild())
186             lastChild = lc;
187
188         if (cur->isRenderInline()) {
189             cur = toRenderInline(cur)->inlineElementContinuation();
190             ASSERT_UNUSED(prev, cur || !toRenderInline(prev)->continuation());
191         } else
192             cur = toRenderBlock(cur)->inlineElementContinuation();
193     }
194
195     return lastChild;
196 }
197
198 AccessibilityObject* AccessibilityRenderObject::firstChild() const
199 {
200     if (!m_renderer)
201         return 0;
202     
203     RenderObject* firstChild = firstChildConsideringContinuation(m_renderer);
204
205     if (!firstChild)
206         return 0;
207     
208     return axObjectCache()->getOrCreate(firstChild);
209 }
210
211 AccessibilityObject* AccessibilityRenderObject::lastChild() const
212 {
213     if (!m_renderer)
214         return 0;
215
216     RenderObject* lastChild = lastChildConsideringContinuation(m_renderer);
217
218     if (!lastChild)
219         return 0;
220     
221     return axObjectCache()->getOrCreate(lastChild);
222 }
223
224 static inline RenderInline* startOfContinuations(RenderObject* r)
225 {
226     if (r->isInlineElementContinuation())
227         return toRenderInline(r->node()->renderer());
228
229     // Blocks with a previous continuation always have a next continuation
230     if (r->isRenderBlock() && toRenderBlock(r)->inlineElementContinuation())
231         return toRenderInline(toRenderBlock(r)->inlineElementContinuation()->node()->renderer());
232
233     return 0;
234 }
235
236 static inline RenderObject* endOfContinuations(RenderObject* renderer)
237 {
238     RenderObject* prev = renderer;
239     RenderObject* cur = renderer;
240
241     if (!cur->isRenderInline() && !cur->isRenderBlock())
242         return renderer;
243
244     while (cur) {
245         prev = cur;
246         if (cur->isRenderInline()) {
247             cur = toRenderInline(cur)->inlineElementContinuation();
248             ASSERT(cur || !toRenderInline(prev)->continuation());
249         } else 
250             cur = toRenderBlock(cur)->inlineElementContinuation();
251     }
252
253     return prev;
254 }
255
256
257 static inline RenderObject* childBeforeConsideringContinuations(RenderInline* r, RenderObject* child)
258 {
259     RenderBoxModelObject* curContainer = r;
260     RenderObject* cur = 0;
261     RenderObject* prev = 0;
262
263     while (curContainer) {
264         if (curContainer->isRenderInline()) {
265             cur = curContainer->firstChild();
266             while (cur) {
267                 if (cur == child)
268                     return prev;
269                 prev = cur;
270                 cur = cur->nextSibling();
271             }
272
273             curContainer = toRenderInline(curContainer)->continuation();
274         } else if (curContainer->isRenderBlock()) {
275             if (curContainer == child)
276                 return prev;
277
278             prev = curContainer;
279             curContainer = toRenderBlock(curContainer)->inlineElementContinuation();
280         }
281     }
282
283     ASSERT_NOT_REACHED();
284
285     return 0;
286 }
287
288 static inline bool firstChildIsInlineContinuation(RenderObject* renderer)
289 {
290     return renderer->firstChild() && renderer->firstChild()->isInlineElementContinuation();
291 }
292
293 AccessibilityObject* AccessibilityRenderObject::previousSibling() const
294 {
295     if (!m_renderer)
296         return 0;
297
298     RenderObject* previousSibling = 0;
299
300     // Case 1: The node is a block and is an inline's continuation. In that case, the inline's
301     // last child is our previous sibling (or further back in the continuation chain)
302     RenderInline* startOfConts;
303     if (m_renderer->isRenderBlock() && (startOfConts = startOfContinuations(m_renderer)))
304         previousSibling = childBeforeConsideringContinuations(startOfConts, m_renderer);
305
306     // Case 2: Anonymous block parent of the end of a continuation - skip all the way to before
307     // the parent of the start, since everything in between will be linked up via the continuation.
308     else if (m_renderer->isAnonymousBlock() && firstChildIsInlineContinuation(m_renderer)) {
309         RenderObject* firstParent = startOfContinuations(m_renderer->firstChild())->parent();
310         while (firstChildIsInlineContinuation(firstParent))
311             firstParent = startOfContinuations(firstParent->firstChild())->parent();
312         previousSibling = firstParent->previousSibling();
313     }
314
315     // Case 3: The node has an actual previous sibling
316     else if (RenderObject* ps = m_renderer->previousSibling())
317         previousSibling = ps;
318
319     // Case 4: This node has no previous siblings, but its parent is an inline,
320     // and is another node's inline continutation. Follow the continuation chain.
321     else if (m_renderer->parent()->isRenderInline() && (startOfConts = startOfContinuations(m_renderer->parent())))
322         previousSibling = childBeforeConsideringContinuations(startOfConts, m_renderer->parent()->firstChild());
323
324     if (!previousSibling)
325         return 0;
326     
327     return axObjectCache()->getOrCreate(previousSibling);
328 }
329
330 static inline bool lastChildHasContinuation(RenderObject* renderer)
331 {
332     return renderer->lastChild() && isInlineWithContinuation(renderer->lastChild());
333 }
334
335 AccessibilityObject* AccessibilityRenderObject::nextSibling() const
336 {
337     if (!m_renderer)
338         return 0;
339
340     RenderObject* nextSibling = 0;
341
342     // Case 1: node is a block and has an inline continuation. Next sibling is the inline continuation's
343     // first child.
344     RenderInline* inlineContinuation;
345     if (m_renderer->isRenderBlock() && (inlineContinuation = toRenderBlock(m_renderer)->inlineElementContinuation()))
346         nextSibling = firstChildConsideringContinuation(inlineContinuation);
347
348     // Case 2: Anonymous block parent of the start of a continuation - skip all the way to
349     // after the parent of the end, since everything in between will be linked up via the continuation.
350     else if (m_renderer->isAnonymousBlock() && lastChildHasContinuation(m_renderer)) {
351         RenderObject* lastParent = endOfContinuations(m_renderer->lastChild())->parent();
352         while (lastChildHasContinuation(lastParent))
353             lastParent = endOfContinuations(lastParent->lastChild())->parent();
354         nextSibling = lastParent->nextSibling();
355     }
356
357     // Case 3: node has an actual next sibling
358     else if (RenderObject* ns = m_renderer->nextSibling())
359         nextSibling = ns;
360
361     // Case 4: node is an inline with a continuation. Next sibling is the next sibling of the end 
362     // of the continuation chain.
363     else if (isInlineWithContinuation(m_renderer))
364         nextSibling = endOfContinuations(m_renderer)->nextSibling();
365
366     // Case 5: node has no next sibling, and its parent is an inline with a continuation.
367     else if (isInlineWithContinuation(m_renderer->parent())) {
368         RenderObject* continuation = toRenderInline(m_renderer->parent())->continuation();
369         
370         // Case 5a: continuation is a block - in this case the block itself is the next sibling.
371         if (continuation->isRenderBlock())
372             nextSibling = continuation;
373         // Case 5b: continuation is an inline - in this case the inline's first child is the next sibling
374         else
375             nextSibling = firstChildConsideringContinuation(continuation);
376     }
377
378     if (!nextSibling)
379         return 0;
380     
381     return axObjectCache()->getOrCreate(nextSibling);
382 }
383
384 static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
385 {
386     ASSERT(renderer);
387     if (renderer->isRenderInline() && !renderer->isReplaced())
388         return toRenderInline(renderer)->continuation();
389     if (renderer->isRenderBlock())
390         return toRenderBlock(renderer)->inlineElementContinuation();
391     return 0;
392 }
393     
394 RenderObject* AccessibilityRenderObject::renderParentObject() const
395 {
396     if (!m_renderer)
397         return 0;
398
399     RenderObject* parent = m_renderer->parent();
400
401     // Case 1: node is a block and is an inline's continuation. Parent
402     // is the start of the continuation chain.
403     RenderObject* startOfConts = 0;
404     RenderObject* firstChild = 0;
405     if (m_renderer->isRenderBlock() && (startOfConts = startOfContinuations(m_renderer)))
406         parent = startOfConts;
407
408     // Case 2: node's parent is an inline which is some node's continuation; parent is 
409     // the earliest node in the continuation chain.
410     else if (parent && parent->isRenderInline() && (startOfConts = startOfContinuations(parent)))
411         parent = startOfConts;
412     
413     // Case 3: The first sibling is the beginning of a continuation chain. Find the origin of that continuation.
414     else if (parent && (firstChild = parent->firstChild()) && firstChild->node()) {
415         // Get the node's renderer and follow that continuation chain until the first child is found
416         RenderObject* nodeRenderFirstChild = firstChild->node()->renderer();
417         while (nodeRenderFirstChild != firstChild) {
418             for (RenderObject* contsTest = nodeRenderFirstChild; contsTest; contsTest = nextContinuation(contsTest)) {
419                 if (contsTest == firstChild) {
420                     parent = nodeRenderFirstChild->parent();
421                     break;
422                 }
423             }
424             if (firstChild == parent->firstChild())
425                 break;
426             firstChild = parent->firstChild();
427             nodeRenderFirstChild = firstChild->node()->renderer();
428         }
429     }
430         
431     return parent;
432 }
433     
434 AccessibilityObject* AccessibilityRenderObject::parentObjectIfExists() const
435 {
436     return axObjectCache()->get(renderParentObject());
437 }
438     
439 AccessibilityObject* AccessibilityRenderObject::parentObject() const
440 {
441     if (!m_renderer)
442         return 0;
443     
444     if (ariaRoleAttribute() == MenuBarRole)
445         return axObjectCache()->getOrCreate(m_renderer->parent());
446
447     // menuButton and its corresponding menu are DOM siblings, but Accessibility needs them to be parent/child
448     if (ariaRoleAttribute() == MenuRole) {
449         AccessibilityObject* parent = menuButtonForMenu();
450         if (parent)
451             return parent;
452     }
453     
454     RenderObject* parentObj = renderParentObject();
455     if (parentObj)
456         return axObjectCache()->getOrCreate(parentObj);
457     
458     // WebArea's parent should be the scroll view containing it.
459     if (isWebArea())
460         return axObjectCache()->getOrCreate(m_renderer->frame()->view());
461     
462     return 0;
463 }
464
465 bool AccessibilityRenderObject::isWebArea() const
466 {
467     return roleValue() == WebAreaRole;
468 }
469
470 bool AccessibilityRenderObject::isImageButton() const
471 {
472     return isNativeImage() && roleValue() == ButtonRole;
473 }
474
475 bool AccessibilityRenderObject::isAnchor() const
476 {
477     return !isNativeImage() && isLink();
478 }
479
480 bool AccessibilityRenderObject::isNativeTextControl() const
481 {
482     return m_renderer->isTextControl();
483 }
484     
485 bool AccessibilityRenderObject::isNativeImage() const
486 {
487     return m_renderer->isBoxModelObject() && toRenderBoxModelObject(m_renderer)->isImage();
488 }    
489     
490 bool AccessibilityRenderObject::isImage() const
491 {
492     return roleValue() == ImageRole;
493 }
494
495 bool AccessibilityRenderObject::isAttachment() const
496 {
497     RenderBoxModelObject* renderer = renderBoxModelObject();
498     if (!renderer)
499         return false;
500     // Widgets are the replaced elements that we represent to AX as attachments
501     bool isWidget = renderer->isWidget();
502     ASSERT(!isWidget || (renderer->isReplaced() && !isImage()));
503     return isWidget && ariaRoleAttribute() == UnknownRole;
504 }
505
506 bool AccessibilityRenderObject::isPasswordField() const
507 {
508     ASSERT(m_renderer);
509     if (!m_renderer->node() || !m_renderer->node()->isHTMLElement())
510         return false;
511     if (ariaRoleAttribute() != UnknownRole)
512         return false;
513
514     HTMLInputElement* inputElement = m_renderer->node()->toInputElement();
515     if (!inputElement)
516         return false;
517
518     return inputElement->isPasswordField();
519 }
520     
521 bool AccessibilityRenderObject::isFileUploadButton() const
522 {
523     if (m_renderer && m_renderer->node() && m_renderer->node()->hasTagName(inputTag)) {
524         HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->node());
525         return input->isFileUpload();
526     }
527     
528     return false;
529 }
530     
531 bool AccessibilityRenderObject::isInputImage() const
532 {
533     Node* elementNode = node();
534     if (roleValue() == ButtonRole && elementNode && elementNode->hasTagName(inputTag)) {
535         HTMLInputElement* input = static_cast<HTMLInputElement*>(elementNode);
536         return input->isImageButton();
537     }
538     
539     return false;
540 }
541
542 bool AccessibilityRenderObject::isProgressIndicator() const
543 {
544     return roleValue() == ProgressIndicatorRole;
545 }
546
547 bool AccessibilityRenderObject::isSlider() const
548 {
549     return roleValue() == SliderRole;
550 }
551
552 bool AccessibilityRenderObject::isMenuRelated() const
553 {
554     AccessibilityRole role = roleValue();
555     return role == MenuRole 
556         || role == MenuBarRole
557         || role == MenuButtonRole
558         || role == MenuItemRole;
559 }    
560
561 bool AccessibilityRenderObject::isMenu() const
562 {
563     return roleValue() == MenuRole;
564 }
565
566 bool AccessibilityRenderObject::isMenuBar() const
567 {
568     return roleValue() == MenuBarRole;
569 }
570
571 bool AccessibilityRenderObject::isMenuButton() const
572 {
573     return roleValue() == MenuButtonRole;
574 }
575
576 bool AccessibilityRenderObject::isMenuItem() const
577 {
578     return roleValue() == MenuItemRole;
579 }
580      
581 bool AccessibilityRenderObject::isPressed() const
582 {
583     ASSERT(m_renderer);
584     if (roleValue() != ButtonRole)
585         return false;
586
587     Node* node = m_renderer->node();
588     if (!node)
589         return false;
590
591     // If this is an ARIA button, check the aria-pressed attribute rather than node()->active()
592     if (ariaRoleAttribute() == ButtonRole) {
593         if (equalIgnoringCase(getAttribute(aria_pressedAttr), "true"))
594             return true;
595         return false;
596     }
597
598     return node->active();
599 }
600
601 bool AccessibilityRenderObject::isIndeterminate() const
602 {
603     ASSERT(m_renderer);
604     if (!m_renderer->node())
605         return false;
606
607     HTMLInputElement* inputElement = m_renderer->node()->toInputElement();
608     if (!inputElement)
609         return false;
610
611     return inputElement->isIndeterminate();
612 }
613
614 bool AccessibilityRenderObject::isNativeCheckboxOrRadio() const
615 {
616     Node* elementNode = node();
617     if (elementNode) {
618         HTMLInputElement* input = elementNode->toInputElement();
619         if (input)
620             return input->isCheckbox() || input->isRadioButton();
621     }
622     
623     return false;
624 }
625     
626 bool AccessibilityRenderObject::isChecked() const
627 {
628     ASSERT(m_renderer);
629     if (!m_renderer->node())
630         return false;
631
632     // First test for native checkedness semantics
633     HTMLInputElement* inputElement = m_renderer->node()->toInputElement();
634     if (inputElement)
635         return inputElement->shouldAppearChecked();
636
637     // Else, if this is an ARIA checkbox or radio, respect the aria-checked attribute
638     AccessibilityRole ariaRole = ariaRoleAttribute();
639     if (ariaRole == RadioButtonRole || ariaRole == CheckBoxRole) {
640         if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true"))
641             return true;
642         return false;
643     }
644
645     // Otherwise it's not checked
646     return false;
647 }
648
649 bool AccessibilityRenderObject::isHovered() const
650 {
651     ASSERT(m_renderer);
652     return m_renderer->node() && m_renderer->node()->hovered();
653 }
654
655 bool AccessibilityRenderObject::isMultiSelectable() const
656 {
657     ASSERT(m_renderer);
658     
659     const AtomicString& ariaMultiSelectable = getAttribute(aria_multiselectableAttr);
660     if (equalIgnoringCase(ariaMultiSelectable, "true"))
661         return true;
662     if (equalIgnoringCase(ariaMultiSelectable, "false"))
663         return false;
664     
665     if (!m_renderer->isBoxModelObject() || !toRenderBoxModelObject(m_renderer)->isListBox())
666         return false;
667     return m_renderer->node() && static_cast<HTMLSelectElement*>(m_renderer->node())->multiple();
668 }
669
670 bool AccessibilityRenderObject::isReadOnly() const
671 {
672     ASSERT(m_renderer);
673     
674     if (isWebArea()) {
675         Document* document = m_renderer->document();
676         if (!document)
677             return true;
678         
679         HTMLElement* body = document->body();
680         if (body && body->isContentEditable())
681             return false;
682
683         return !document->rendererIsEditable();
684     }
685
686     if (m_renderer->isBoxModelObject()) {
687         RenderBoxModelObject* box = toRenderBoxModelObject(m_renderer);
688         if (box->isTextField())
689             return static_cast<HTMLInputElement*>(box->node())->readOnly();
690         if (box->isTextArea())
691             return static_cast<HTMLTextAreaElement*>(box->node())->readOnly();
692     }
693
694     return !m_renderer->node() || !m_renderer->node()->rendererIsEditable();
695 }
696
697 bool AccessibilityRenderObject::isOffScreen() const
698 {
699     ASSERT(m_renderer);
700     LayoutRect contentRect = m_renderer->absoluteClippedOverflowRect();
701     FrameView* view = m_renderer->frame()->view();
702     FloatRect viewRect = view->visibleContentRect();
703     viewRect.intersect(contentRect);
704     return viewRect.isEmpty();
705 }
706
707 int AccessibilityRenderObject::headingLevel() const
708 {
709     // headings can be in block flow and non-block flow
710     Node* element = node();
711     if (!element)
712         return 0;
713
714     if (ariaRoleAttribute() == HeadingRole)
715         return getAttribute(aria_levelAttr).toInt();
716
717     if (element->hasTagName(h1Tag))
718         return 1;
719     
720     if (element->hasTagName(h2Tag))
721         return 2;
722     
723     if (element->hasTagName(h3Tag))
724         return 3;
725     
726     if (element->hasTagName(h4Tag))
727         return 4;
728     
729     if (element->hasTagName(h5Tag))
730         return 5;
731     
732     if (element->hasTagName(h6Tag))
733         return 6;
734     
735     return 0;
736 }
737
738 bool AccessibilityRenderObject::isHeading() const
739 {
740     return roleValue() == HeadingRole;
741 }
742     
743 bool AccessibilityRenderObject::isLink() const
744 {
745     return roleValue() == WebCoreLinkRole;
746 }    
747     
748 bool AccessibilityRenderObject::isControl() const
749 {
750     if (!m_renderer)
751         return false;
752     
753     Node* node = m_renderer->node();
754     return node && ((node->isElementNode() && static_cast<Element*>(node)->isFormControlElement())
755                     || AccessibilityObject::isARIAControl(ariaRoleAttribute()));
756 }
757
758 bool AccessibilityRenderObject::isFieldset() const
759 {
760     RenderBoxModelObject* renderer = renderBoxModelObject();
761     if (!renderer)
762         return false;
763     return renderer->isFieldset();
764 }
765   
766 bool AccessibilityRenderObject::isGroup() const
767 {
768     return roleValue() == GroupRole;
769 }
770     
771 AccessibilityObject* AccessibilityRenderObject::selectedRadioButton()
772 {
773     if (!isRadioGroup())
774         return 0;
775     
776     // Find the child radio button that is selected (ie. the intValue == 1).
777     int count = m_children.size();
778     for (int i = 0; i < count; ++i) {
779         AccessibilityObject* object = m_children[i].get();
780         if (object->roleValue() == RadioButtonRole && object->checkboxOrRadioValue() == ButtonStateOn)
781             return object;
782     }
783     return 0;
784 }
785
786 AccessibilityObject* AccessibilityRenderObject::selectedTabItem()
787 {
788     if (!isTabList())
789         return 0;
790     
791     // Find the child tab item that is selected (ie. the intValue == 1).
792     AccessibilityObject::AccessibilityChildrenVector tabs;
793     tabChildren(tabs);
794     
795     int count = tabs.size();
796     for (int i = 0; i < count; ++i) {
797         AccessibilityObject* object = m_children[i].get();
798         if (object->isTabItem() && object->isChecked())
799             return object;
800     }
801     return 0;
802 }
803
804 Element* AccessibilityRenderObject::anchorElement() const
805 {
806     if (!m_renderer)
807         return 0;
808     
809     AXObjectCache* cache = axObjectCache();
810     RenderObject* currRenderer;
811     
812     // Search up the render tree for a RenderObject with a DOM node.  Defer to an earlier continuation, though.
813     for (currRenderer = m_renderer; currRenderer && !currRenderer->node(); currRenderer = currRenderer->parent()) {
814         if (currRenderer->isAnonymousBlock()) {
815             RenderObject* continuation = toRenderBlock(currRenderer)->continuation();
816             if (continuation)
817                 return cache->getOrCreate(continuation)->anchorElement();
818         }
819     }
820     
821     // bail if none found
822     if (!currRenderer)
823         return 0;
824     
825     // search up the DOM tree for an anchor element
826     // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
827     Node* node = currRenderer->node();
828     for ( ; node; node = node->parentNode()) {
829         if (node->hasTagName(aTag) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
830             return static_cast<Element*>(node);
831     }
832     
833     return 0;
834 }
835
836 Element* AccessibilityRenderObject::actionElement() const
837 {
838     if (!m_renderer)
839         return 0;
840     
841     Node* node = m_renderer->node();
842     if (node) {
843         if (node->hasTagName(inputTag)) {
844             HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
845             if (!input->disabled() && (isCheckboxOrRadio() || input->isTextButton()))
846                 return input;
847         } else if (node->hasTagName(buttonTag))
848             return static_cast<Element*>(node);
849     }
850
851     if (isFileUploadButton())
852         return static_cast<Element*>(m_renderer->node());
853             
854     if (AccessibilityObject::isARIAInput(ariaRoleAttribute()))
855         return static_cast<Element*>(m_renderer->node());
856
857     if (isImageButton())
858         return static_cast<Element*>(m_renderer->node());
859     
860     if (m_renderer->isBoxModelObject() && toRenderBoxModelObject(m_renderer)->isMenuList())
861         return static_cast<Element*>(m_renderer->node());
862
863     AccessibilityRole role = roleValue();
864     if (role == ButtonRole || role == PopUpButtonRole)
865         return static_cast<Element*>(m_renderer->node()); 
866     
867     Element* elt = anchorElement();
868     if (!elt)
869         elt = mouseButtonListener();
870     return elt;
871 }
872
873 Element* AccessibilityRenderObject::mouseButtonListener() const
874 {
875     Node* node = m_renderer->node();
876     if (!node)
877         return 0;
878     
879     // check if our parent is a mouse button listener
880     while (node && !node->isElementNode())
881         node = node->parentNode();
882
883     if (!node)
884         return 0;
885
886     // FIXME: Do the continuation search like anchorElement does
887     for (Element* element = static_cast<Element*>(node); element; element = element->parentElement()) {
888         if (element->getAttributeEventListener(eventNames().clickEvent) || element->getAttributeEventListener(eventNames().mousedownEvent) || element->getAttributeEventListener(eventNames().mouseupEvent))
889             return element;
890     }
891
892     return 0;
893 }
894
895 void AccessibilityRenderObject::alterSliderValue(bool increase)
896 {
897     if (roleValue() != SliderRole)
898         return;
899
900     if (!getAttribute(stepAttr).isEmpty())
901         changeValueByStep(increase);
902     else
903         changeValueByPercent(increase ? 5 : -5);
904 }
905     
906 void AccessibilityRenderObject::increment()
907 {
908     alterSliderValue(true);
909 }
910
911 void AccessibilityRenderObject::decrement()
912 {
913     alterSliderValue(false);
914 }
915
916 static Element* siblingWithAriaRole(String role, Node* node)
917 {
918     Node* sibling = node->parentNode()->firstChild();
919     while (sibling) {
920         if (sibling->isElementNode()) {
921             const AtomicString& siblingAriaRole = static_cast<Element*>(sibling)->getAttribute(roleAttr);
922             if (equalIgnoringCase(siblingAriaRole, role))
923                 return static_cast<Element*>(sibling);
924         }
925         sibling = sibling->nextSibling();
926     }
927     
928     return 0;
929 }
930
931 Element* AccessibilityRenderObject::menuElementForMenuButton() const
932 {
933     if (ariaRoleAttribute() != MenuButtonRole)
934         return 0;
935
936     return siblingWithAriaRole("menu", renderer()->node());
937 }
938
939 AccessibilityObject* AccessibilityRenderObject::menuForMenuButton() const
940 {
941     Element* menu = menuElementForMenuButton();
942     if (menu && menu->renderer())
943         return axObjectCache()->getOrCreate(menu->renderer());
944     return 0;
945 }
946
947 Element* AccessibilityRenderObject::menuItemElementForMenu() const
948 {
949     if (ariaRoleAttribute() != MenuRole)
950         return 0;
951     
952     return siblingWithAriaRole("menuitem", renderer()->node());    
953 }
954
955 AccessibilityObject* AccessibilityRenderObject::menuButtonForMenu() const
956 {
957     Element* menuItem = menuItemElementForMenu();
958
959     if (menuItem && menuItem->renderer()) {
960         // ARIA just has generic menu items.  AppKit needs to know if this is a top level items like MenuBarButton or MenuBarItem
961         AccessibilityObject* menuItemAX = axObjectCache()->getOrCreate(menuItem->renderer());
962         if (menuItemAX->isMenuButton())
963             return menuItemAX;
964     }
965     return 0;
966 }
967
968 String AccessibilityRenderObject::helpText() const
969 {
970     if (!m_renderer)
971         return String();
972     
973     const AtomicString& ariaHelp = getAttribute(aria_helpAttr);
974     if (!ariaHelp.isEmpty())
975         return ariaHelp;
976     
977     for (RenderObject* curr = m_renderer; curr; curr = curr->parent()) {
978         if (curr->node() && curr->node()->isHTMLElement()) {
979             const AtomicString& summary = static_cast<Element*>(curr->node())->getAttribute(summaryAttr);
980             if (!summary.isEmpty())
981                 return summary;
982             const AtomicString& title = static_cast<Element*>(curr->node())->getAttribute(titleAttr);
983             if (!title.isEmpty())
984                 return title;
985         }
986         
987         // Only take help text from an ancestor element if its a group or an unknown role. If help was 
988         // added to those kinds of elements, it is likely it was meant for a child element.
989         AccessibilityObject* axObj = axObjectCache()->getOrCreate(curr);
990         if (axObj) {
991             AccessibilityRole role = axObj->roleValue();
992             if (role != GroupRole && role != UnknownRole)
993                 break;
994         }
995     }
996     
997     return String();
998 }
999     
1000 unsigned AccessibilityRenderObject::hierarchicalLevel() const
1001 {
1002     if (!m_renderer)
1003         return 0;
1004
1005     Node* node = m_renderer->node();
1006     if (!node || !node->isElementNode())
1007         return 0;
1008     Element* element = static_cast<Element*>(node);
1009     String ariaLevel = element->getAttribute(aria_levelAttr);
1010     if (!ariaLevel.isEmpty())
1011         return ariaLevel.toInt();
1012     
1013     // Only tree item will calculate its level through the DOM currently.
1014     if (roleValue() != TreeItemRole)
1015         return 0;
1016     
1017     // Hierarchy leveling starts at 0.
1018     // We measure tree hierarchy by the number of groups that the item is within.
1019     unsigned level = 0;
1020     AccessibilityObject* parent = parentObject();
1021     while (parent) {
1022         AccessibilityRole parentRole = parent->roleValue();
1023         if (parentRole == GroupRole)
1024             level++;
1025         else if (parentRole == TreeRole)
1026             break;
1027         
1028         parent = parent->parentObject();
1029     }
1030     
1031     return level;
1032 }
1033
1034 static TextIteratorBehavior textIteratorBehaviorForTextRange()
1035 {
1036     TextIteratorBehavior behavior = TextIteratorIgnoresStyleVisibility;
1037
1038 #if PLATFORM(GTK)
1039     // We need to emit replaced elements for GTK, and present
1040     // them with the 'object replacement character' (0xFFFC).
1041     behavior = static_cast<TextIteratorBehavior>(behavior | TextIteratorEmitsObjectReplacementCharacters);
1042 #endif
1043
1044     return behavior;
1045 }
1046
1047 String AccessibilityRenderObject::textUnderElement() const
1048 {
1049     if (!m_renderer)
1050         return String();
1051     
1052     if (isFileUploadButton())
1053         return toRenderFileUploadControl(m_renderer)->buttonValue();
1054     
1055     Node* node = m_renderer->node();
1056     if (node) {
1057         if (Frame* frame = node->document()->frame()) {
1058             // catch stale WebCoreAXObject (see <rdar://problem/3960196>)
1059             if (frame->document() != node->document())
1060                 return String();
1061
1062             return plainText(rangeOfContents(node).get(), textIteratorBehaviorForTextRange());
1063         }
1064     }
1065     
1066     // Sometimes text fragments don't have Node's associated with them (like when
1067     // CSS content is used to insert text).
1068     if (m_renderer->isText()) {
1069         RenderText* renderTextObject = toRenderText(m_renderer);
1070         if (renderTextObject->isTextFragment())
1071             return String(static_cast<RenderTextFragment*>(m_renderer)->contentString());
1072     }
1073     
1074     // return the null string for anonymous text because it is non-trivial to get
1075     // the actual text and, so far, that is not needed
1076     return String();
1077 }
1078
1079 Node* AccessibilityRenderObject::node() const
1080
1081     return m_renderer ? m_renderer->node() : 0; 
1082 }    
1083     
1084 AccessibilityButtonState AccessibilityRenderObject::checkboxOrRadioValue() const
1085 {
1086     if (isNativeCheckboxOrRadio())
1087         return isChecked() ? ButtonStateOn : ButtonStateOff;
1088     
1089     return AccessibilityObject::checkboxOrRadioValue();
1090 }
1091
1092 String AccessibilityRenderObject::valueDescription() const
1093 {
1094     // Only sliders and progress bars support value descriptions currently.
1095     if (!isProgressIndicator() && !isSlider())
1096         return String();
1097     
1098     return getAttribute(aria_valuetextAttr).string();
1099 }
1100     
1101 float AccessibilityRenderObject::stepValueForRange() const
1102 {
1103     return getAttribute(stepAttr).toFloat();
1104 }
1105     
1106 float AccessibilityRenderObject::valueForRange() const
1107 {
1108     if (!isProgressIndicator() && !isSlider() && !isScrollbar())
1109         return 0.0f;
1110
1111     return getAttribute(aria_valuenowAttr).toFloat();
1112 }
1113
1114 float AccessibilityRenderObject::maxValueForRange() const
1115 {
1116     if (!isProgressIndicator() && !isSlider())
1117         return 0.0f;
1118
1119     return getAttribute(aria_valuemaxAttr).toFloat();
1120 }
1121
1122 float AccessibilityRenderObject::minValueForRange() const
1123 {
1124     if (!isProgressIndicator() && !isSlider())
1125         return 0.0f;
1126
1127     return getAttribute(aria_valueminAttr).toFloat();
1128 }
1129
1130 String AccessibilityRenderObject::stringValue() const
1131 {
1132     if (!m_renderer || isPasswordField())
1133         return String();
1134
1135     RenderBoxModelObject* cssBox = renderBoxModelObject();
1136
1137     if (ariaRoleAttribute() == StaticTextRole) {
1138         String staticText = text();
1139         if (!staticText.length())
1140             staticText = textUnderElement();
1141         return staticText;
1142     }
1143         
1144     if (m_renderer->isText())
1145         return textUnderElement();
1146     
1147     if (cssBox && cssBox->isMenuList()) {
1148         // RenderMenuList will go straight to the text() of its selected item.
1149         // This has to be overriden in the case where the selected item has an aria label
1150         SelectElement* selectNode = toSelectElement(static_cast<Element*>(m_renderer->node()));
1151         int selectedIndex = selectNode->selectedIndex();
1152         const Vector<Element*> listItems = selectNode->listItems();
1153         
1154         Element* selectedOption = 0;
1155         if (selectedIndex >= 0 && selectedIndex < (int)listItems.size()) 
1156             selectedOption = listItems[selectedIndex];
1157         if (selectedOption) {
1158             String overridenDescription = selectedOption->getAttribute(aria_labelAttr);
1159             if (!overridenDescription.isNull())
1160                 return overridenDescription;
1161         }
1162         
1163         return toRenderMenuList(m_renderer)->text();
1164     }
1165     
1166     if (m_renderer->isListMarker())
1167         return toRenderListMarker(m_renderer)->text();
1168     
1169     if (cssBox && cssBox->isRenderButton())
1170         return toRenderButton(m_renderer)->text();
1171
1172     if (isWebArea()) {
1173         // FIXME: Why would a renderer exist when the Document isn't attached to a frame?
1174         if (m_renderer->frame())
1175             return String();
1176
1177         ASSERT_NOT_REACHED();
1178     }
1179     
1180     if (isTextControl())
1181         return text();
1182     
1183     if (isFileUploadButton())
1184         return toRenderFileUploadControl(m_renderer)->fileTextValue();
1185     
1186     // FIXME: We might need to implement a value here for more types
1187     // FIXME: It would be better not to advertise a value at all for the types for which we don't implement one;
1188     // this would require subclassing or making accessibilityAttributeNames do something other than return a
1189     // single static array.
1190     return String();
1191 }
1192
1193 // This function implements the ARIA accessible name as described by the Mozilla
1194 // ARIA Implementer's Guide.
1195 static String accessibleNameForNode(Node* node)
1196 {
1197     if (node->isTextNode())
1198         return static_cast<Text*>(node)->data();
1199
1200     if (node->hasTagName(inputTag))
1201         return static_cast<HTMLInputElement*>(node)->value();
1202
1203     if (node->isHTMLElement()) {
1204         const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr);
1205         if (!alt.isEmpty())
1206             return alt;
1207     }
1208
1209     return String();
1210 }
1211
1212 String AccessibilityRenderObject::accessibilityDescriptionForElements(Vector<Element*> &elements) const
1213 {
1214     StringBuilder builder;
1215     unsigned size = elements.size();
1216     for (unsigned i = 0; i < size; ++i) {
1217         Element* idElement = elements[i];
1218
1219         builder.append(accessibleNameForNode(idElement));
1220         for (Node* n = idElement->firstChild(); n; n = n->traverseNextNode(idElement))
1221             builder.append(accessibleNameForNode(n));
1222
1223         if (i != size - 1)
1224             builder.append(' ');
1225     }
1226     return builder.toString();
1227 }
1228
1229 void AccessibilityRenderObject::elementsFromAttribute(Vector<Element*>& elements, const QualifiedName& attribute) const
1230 {
1231     Node* node = m_renderer->node();
1232     if (!node || !node->isElementNode())
1233         return;
1234
1235     TreeScope* scope = node->treeScope();
1236     if (!scope)
1237         return;
1238     
1239     String idList = getAttribute(attribute).string();
1240     if (idList.isEmpty())
1241         return;
1242     
1243     idList.replace('\n', ' ');
1244     Vector<String> idVector;
1245     idList.split(' ', idVector);
1246     
1247     unsigned size = idVector.size();
1248     for (unsigned i = 0; i < size; ++i) {
1249         AtomicString idName(idVector[i]);
1250         Element* idElement = scope->getElementById(idName);
1251         if (idElement)
1252             elements.append(idElement);
1253     }
1254 }
1255     
1256 void AccessibilityRenderObject::ariaLabeledByElements(Vector<Element*>& elements) const
1257 {
1258     elementsFromAttribute(elements, aria_labeledbyAttr);
1259     if (!elements.size())
1260         elementsFromAttribute(elements, aria_labelledbyAttr);
1261 }
1262    
1263 String AccessibilityRenderObject::ariaLabeledByAttribute() const
1264 {
1265     Vector<Element*> elements;
1266     ariaLabeledByElements(elements);
1267     
1268     return accessibilityDescriptionForElements(elements);
1269 }
1270
1271 static HTMLLabelElement* labelForElement(Element* element)
1272 {
1273     RefPtr<NodeList> list = element->document()->getElementsByTagName("label");
1274     unsigned len = list->length();
1275     for (unsigned i = 0; i < len; i++) {
1276         if (list->item(i)->hasTagName(labelTag)) {
1277             HTMLLabelElement* label = static_cast<HTMLLabelElement*>(list->item(i));
1278             if (label->control() == element)
1279                 return label;
1280         }
1281     }
1282     
1283     return 0;
1284 }
1285     
1286 HTMLLabelElement* AccessibilityRenderObject::labelElementContainer() const
1287 {
1288     if (!m_renderer)
1289         return 0;
1290
1291     // the control element should not be considered part of the label
1292     if (isControl())
1293         return 0;
1294     
1295     // find if this has a parent that is a label
1296     for (Node* parentNode = m_renderer->node(); parentNode; parentNode = parentNode->parentNode()) {
1297         if (parentNode->hasTagName(labelTag))
1298             return static_cast<HTMLLabelElement*>(parentNode);
1299     }
1300     
1301     return 0;
1302 }
1303
1304 String AccessibilityRenderObject::title() const
1305 {
1306     AccessibilityRole ariaRole = ariaRoleAttribute();
1307     
1308     if (!m_renderer)
1309         return String();
1310
1311     Node* node = m_renderer->node();
1312     if (!node)
1313         return String();
1314     
1315     const AtomicString& title = getAttribute(titleAttr);
1316     if (!title.isEmpty())
1317         return title;
1318     
1319     bool isInputTag = node->hasTagName(inputTag);
1320     if (isInputTag) {
1321         HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
1322         if (input->isTextButton())
1323             return input->value();
1324     }
1325     
1326     if (isInputTag || AccessibilityObject::isARIAInput(ariaRole) || isControl()) {
1327         HTMLLabelElement* label = labelForElement(static_cast<Element*>(node));
1328         if (label && !titleUIElement())
1329             return label->innerText();
1330     }
1331     
1332     if (roleValue() == ButtonRole
1333         || ariaRole == ListBoxOptionRole
1334         || ariaRole == MenuItemRole
1335         || ariaRole == MenuButtonRole
1336         || ariaRole == RadioButtonRole
1337         || ariaRole == CheckBoxRole
1338         || ariaRole == TabRole
1339         || ariaRole == PopUpButtonRole
1340         || isHeading()
1341         || isLink())
1342         return textUnderElement();
1343     
1344     return String();
1345 }
1346
1347 String AccessibilityRenderObject::ariaDescribedByAttribute() const
1348 {
1349     Vector<Element*> elements;
1350     elementsFromAttribute(elements, aria_describedbyAttr);
1351     
1352     return accessibilityDescriptionForElements(elements);
1353 }
1354     
1355 String AccessibilityRenderObject::ariaAccessibilityDescription() const
1356 {
1357     String ariaLabeledBy = ariaLabeledByAttribute();
1358     if (!ariaLabeledBy.isEmpty())
1359         return ariaLabeledBy;
1360
1361     const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
1362     if (!ariaLabel.isEmpty())
1363         return ariaLabel;
1364     
1365     String ariaDescription = ariaDescribedByAttribute();
1366     if (!ariaDescription.isEmpty())
1367         return ariaDescription;
1368     
1369     return String();
1370 }
1371
1372 String AccessibilityRenderObject::accessibilityDescription() const
1373 {
1374     if (!m_renderer)
1375         return String();
1376
1377     // Static text should not have a description, it should only have a stringValue.
1378     if (roleValue() == StaticTextRole)
1379         return String();
1380     
1381     String ariaDescription = ariaAccessibilityDescription();
1382     if (!ariaDescription.isEmpty())
1383         return ariaDescription;
1384     
1385     Node* node = m_renderer->node();
1386     if (isImage() || isInputImage() || isNativeImage()) {
1387         if (node && node->isHTMLElement()) {
1388             const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr);
1389             if (alt.isEmpty())
1390                 return String();
1391             return alt;
1392         }
1393     }
1394     
1395 #if ENABLE(MATHML)
1396     if (node && node->isElementNode() && static_cast<Element*>(node)->isMathMLElement())
1397         return getAttribute(MathMLNames::alttextAttr);
1398 #endif
1399     
1400     if (isWebArea()) {
1401         Document* document = m_renderer->document();
1402         
1403         // Check if the HTML element has an aria-label for the webpage.
1404         Element* documentElement = document->documentElement();
1405         if (documentElement) {
1406             const AtomicString& ariaLabel = documentElement->getAttribute(aria_labelAttr);
1407             if (!ariaLabel.isEmpty())
1408                 return ariaLabel;
1409         }
1410         
1411         Node* owner = document->ownerElement();
1412         if (owner) {
1413             if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) {
1414                 const AtomicString& title = static_cast<HTMLFrameElementBase*>(owner)->getAttribute(titleAttr);
1415                 if (!title.isEmpty())
1416                     return title;
1417                 return static_cast<HTMLFrameElementBase*>(owner)->getAttribute(nameAttr);
1418             }
1419             if (owner->isHTMLElement())
1420                 return toHTMLElement(owner)->getAttribute(nameAttr);
1421         }
1422         owner = document->body();
1423         if (owner && owner->isHTMLElement())
1424             return toHTMLElement(owner)->getAttribute(nameAttr);
1425     }
1426
1427     return String();
1428 }
1429
1430 LayoutRect AccessibilityRenderObject::boundingBoxRect() const
1431 {
1432     RenderObject* obj = m_renderer;
1433     
1434     if (!obj)
1435         return LayoutRect();
1436     
1437     if (obj->node()) // If we are a continuation, we want to make sure to use the primary renderer.
1438         obj = obj->node()->renderer();
1439     
1440     // absoluteFocusRingQuads will query the hierarchy below this element, which for large webpages can be very slow.
1441     // For a web area, which will have the most elements of any element, absoluteQuads should be used.
1442     Vector<FloatQuad> quads;
1443     if (obj->isText())
1444         toRenderText(obj)->absoluteQuads(quads, 0, RenderText::ClipToEllipsis);
1445     else if (isWebArea())
1446         obj->absoluteQuads(quads);
1447     else
1448         obj->absoluteFocusRingQuads(quads);
1449     const size_t n = quads.size();
1450     if (!n)
1451         return LayoutRect();
1452
1453     LayoutRect result;
1454     for (size_t i = 0; i < n; ++i) {
1455         LayoutRect r = quads[i].enclosingBoundingBox();
1456         if (!r.isEmpty()) {
1457             if (obj->style()->hasAppearance())
1458                 obj->theme()->adjustRepaintRect(obj, r);
1459             result.unite(r);
1460         }
1461     }
1462
1463     // The size of the web area should be the content size, not the clipped size.
1464     if (isWebArea() && obj->frame()->view())
1465         result.setSize(obj->frame()->view()->contentsSize());
1466     
1467     return result;
1468 }
1469     
1470 LayoutRect AccessibilityRenderObject::checkboxOrRadioRect() const
1471 {
1472     if (!m_renderer)
1473         return LayoutRect();
1474     
1475     HTMLLabelElement* label = labelForElement(static_cast<Element*>(m_renderer->node()));
1476     if (!label || !label->renderer())
1477         return boundingBoxRect();
1478     
1479     LayoutRect labelRect = axObjectCache()->getOrCreate(label->renderer())->elementRect();
1480     labelRect.unite(boundingBoxRect());
1481     return labelRect;
1482 }
1483
1484 LayoutRect AccessibilityRenderObject::elementRect() const
1485 {
1486     // a checkbox or radio button should encompass its label
1487     if (isCheckboxOrRadio())
1488         return checkboxOrRadioRect();
1489     
1490     return boundingBoxRect();
1491 }
1492
1493 LayoutSize AccessibilityRenderObject::size() const
1494 {
1495     LayoutRect rect = elementRect();
1496     return rect.size();
1497 }
1498
1499 LayoutPoint AccessibilityRenderObject::clickPoint() const
1500 {
1501     // use the default position unless this is an editable web area, in which case we use the selection bounds.
1502     if (!isWebArea() || isReadOnly())
1503         return AccessibilityObject::clickPoint();
1504     
1505     VisibleSelection visSelection = selection();
1506     VisiblePositionRange range = VisiblePositionRange(visSelection.visibleStart(), visSelection.visibleEnd());
1507     LayoutRect bounds = boundsForVisiblePositionRange(range);
1508 #if PLATFORM(MAC)
1509     bounds.setLocation(m_renderer->document()->view()->screenToContents(bounds.location()));
1510 #endif        
1511     return LayoutPoint(bounds.x() + (bounds.width() / 2), bounds.y() - (bounds.height() / 2));
1512 }
1513     
1514 AccessibilityObject* AccessibilityRenderObject::internalLinkElement() const
1515 {
1516     Element* element = anchorElement();
1517     if (!element)
1518         return 0;
1519     
1520     // Right now, we do not support ARIA links as internal link elements
1521     if (!element->hasTagName(aTag))
1522         return 0;
1523     HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(element);
1524     
1525     KURL linkURL = anchor->href();
1526     String fragmentIdentifier = linkURL.fragmentIdentifier();
1527     if (fragmentIdentifier.isEmpty())
1528         return 0;
1529     
1530     // check if URL is the same as current URL
1531     KURL documentURL = m_renderer->document()->url();
1532     if (!equalIgnoringFragmentIdentifier(documentURL, linkURL))
1533         return 0;
1534     
1535     Node* linkedNode = m_renderer->document()->findAnchor(fragmentIdentifier);
1536     if (!linkedNode)
1537         return 0;
1538     
1539     // The element we find may not be accessible, so find the first accessible object.
1540     return firstAccessibleObjectFromNode(linkedNode);
1541 }
1542
1543 ESpeak AccessibilityRenderObject::speakProperty() const
1544 {
1545     if (!m_renderer)
1546         return AccessibilityObject::speakProperty();
1547     
1548     return m_renderer->style()->speak();
1549 }
1550     
1551 void AccessibilityRenderObject::addRadioButtonGroupMembers(AccessibilityChildrenVector& linkedUIElements) const
1552 {
1553     if (!m_renderer || roleValue() != RadioButtonRole)
1554         return;
1555     
1556     Node* node = m_renderer->node();
1557     if (!node || !node->hasTagName(inputTag))
1558         return;
1559     
1560     HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
1561     // if there's a form, then this is easy
1562     if (input->form()) {
1563         Vector<RefPtr<Node> > formElements;
1564         input->form()->getNamedElements(input->name(), formElements);
1565         
1566         unsigned len = formElements.size();
1567         for (unsigned i = 0; i < len; ++i) {
1568             Node* associateElement = formElements[i].get();
1569             if (AccessibilityObject* object = axObjectCache()->getOrCreate(associateElement->renderer()))
1570                 linkedUIElements.append(object);        
1571         } 
1572     } else {
1573         RefPtr<NodeList> list = node->document()->getElementsByTagName("input");
1574         unsigned len = list->length();
1575         for (unsigned i = 0; i < len; ++i) {
1576             if (list->item(i)->hasTagName(inputTag)) {
1577                 HTMLInputElement* associateElement = static_cast<HTMLInputElement*>(list->item(i));
1578                 if (associateElement->isRadioButton() && associateElement->name() == input->name()) {
1579                     if (AccessibilityObject* object = axObjectCache()->getOrCreate(associateElement->renderer()))
1580                         linkedUIElements.append(object);
1581                 }
1582             }
1583         }
1584     }
1585 }
1586     
1587 // linked ui elements could be all the related radio buttons in a group
1588 // or an internal anchor connection
1589 void AccessibilityRenderObject::linkedUIElements(AccessibilityChildrenVector& linkedUIElements) const
1590 {
1591     ariaFlowToElements(linkedUIElements);
1592
1593     if (isAnchor()) {
1594         AccessibilityObject* linkedAXElement = internalLinkElement();
1595         if (linkedAXElement)
1596             linkedUIElements.append(linkedAXElement);
1597     }
1598
1599     if (roleValue() == RadioButtonRole)
1600         addRadioButtonGroupMembers(linkedUIElements);
1601 }
1602
1603 bool AccessibilityRenderObject::hasTextAlternative() const
1604 {
1605     // ARIA: section 2A, bullet #3 says if aria-labeledby or aria-label appears, it should
1606     // override the "label" element association.
1607     if (!ariaLabeledByAttribute().isEmpty() || !getAttribute(aria_labelAttr).isEmpty())
1608         return true;
1609         
1610     return false;   
1611 }
1612     
1613 bool AccessibilityRenderObject::ariaHasPopup() const
1614 {
1615     return elementAttributeValue(aria_haspopupAttr);
1616 }
1617     
1618 bool AccessibilityRenderObject::supportsARIAFlowTo() const
1619 {
1620     return !getAttribute(aria_flowtoAttr).isEmpty();
1621 }
1622     
1623 void AccessibilityRenderObject::ariaFlowToElements(AccessibilityChildrenVector& flowTo) const
1624 {
1625     Vector<Element*> elements;
1626     elementsFromAttribute(elements, aria_flowtoAttr);
1627     
1628     AXObjectCache* cache = axObjectCache();
1629     unsigned count = elements.size();
1630     for (unsigned k = 0; k < count; ++k) {
1631         Element* element = elements[k];
1632         AccessibilityObject* flowToElement = cache->getOrCreate(element->renderer());
1633         if (flowToElement)
1634             flowTo.append(flowToElement);
1635     }
1636         
1637 }
1638     
1639 bool AccessibilityRenderObject::supportsARIADropping() const 
1640 {
1641     const AtomicString& dropEffect = getAttribute(aria_dropeffectAttr);
1642     return !dropEffect.isEmpty();
1643 }
1644
1645 bool AccessibilityRenderObject::supportsARIADragging() const
1646 {
1647     const AtomicString& grabbed = getAttribute(aria_grabbedAttr);
1648     return equalIgnoringCase(grabbed, "true") || equalIgnoringCase(grabbed, "false");   
1649 }
1650
1651 bool AccessibilityRenderObject::isARIAGrabbed()
1652 {
1653     return elementAttributeValue(aria_grabbedAttr);
1654 }
1655
1656 void AccessibilityRenderObject::determineARIADropEffects(Vector<String>& effects)
1657 {
1658     const AtomicString& dropEffects = getAttribute(aria_dropeffectAttr);
1659     if (dropEffects.isEmpty()) {
1660         effects.clear();
1661         return;
1662     }
1663     
1664     String dropEffectsString = dropEffects.string();
1665     dropEffectsString.replace('\n', ' ');
1666     dropEffectsString.split(' ', effects);
1667 }
1668     
1669 bool AccessibilityRenderObject::exposesTitleUIElement() const
1670 {
1671     if (!isControl())
1672         return false;
1673
1674     // If this control is ignored (because it's invisible), 
1675     // then the label needs to be exposed so it can be visible to accessibility.
1676     if (accessibilityIsIgnored())
1677         return true;
1678     
1679     // checkbox or radio buttons don't expose the title ui element unless it has a title already
1680     if (isCheckboxOrRadio() && getAttribute(titleAttr).isEmpty())
1681         return false;
1682     
1683     if (hasTextAlternative())
1684         return false;
1685     
1686     return true;
1687 }
1688     
1689 AccessibilityObject* AccessibilityRenderObject::titleUIElement() const
1690 {
1691     if (!m_renderer)
1692         return 0;
1693     
1694     // if isFieldset is true, the renderer is guaranteed to be a RenderFieldset
1695     if (isFieldset())
1696         return axObjectCache()->getOrCreate(toRenderFieldset(m_renderer)->findLegend());
1697     
1698     if (!exposesTitleUIElement())
1699         return 0;
1700     
1701     Node* element = m_renderer->node();
1702     HTMLLabelElement* label = labelForElement(static_cast<Element*>(element));
1703     if (label && label->renderer())
1704         return axObjectCache()->getOrCreate(label->renderer());
1705
1706     return 0;   
1707 }
1708     
1709 bool AccessibilityRenderObject::ariaIsHidden() const
1710 {
1711     if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "true"))
1712         return true;
1713     
1714     // aria-hidden hides this object and any children
1715     AccessibilityObject* object = parentObject();
1716     while (object) {
1717         if (equalIgnoringCase(object->getAttribute(aria_hiddenAttr), "true"))
1718             return true;
1719         object = object->parentObject();
1720     }
1721
1722     return false;
1723 }
1724
1725 bool AccessibilityRenderObject::isDescendantOfBarrenParent() const
1726 {
1727     for (AccessibilityObject* object = parentObject(); object; object = object->parentObject()) {
1728         if (!object->canHaveChildren())
1729             return true;
1730     }
1731     
1732     return false;
1733 }
1734     
1735 bool AccessibilityRenderObject::isAllowedChildOfTree() const
1736 {
1737     // Determine if this is in a tree. If so, we apply special behavior to make it work like an AXOutline.
1738     AccessibilityObject* axObj = parentObject();
1739     bool isInTree = false;
1740     while (axObj) {
1741         if (axObj->isTree()) {
1742             isInTree = true;
1743             break;
1744         }
1745         axObj = axObj->parentObject();
1746     }
1747     
1748     // If the object is in a tree, only tree items should be exposed (and the children of tree items).
1749     if (isInTree) {
1750         AccessibilityRole role = roleValue();
1751         if (role != TreeItemRole && role != StaticTextRole)
1752             return false;
1753     }
1754     return true;
1755 }
1756     
1757 AccessibilityObjectInclusion AccessibilityRenderObject::accessibilityIsIgnoredBase() const
1758 {
1759     // The following cases can apply to any element that's a subclass of AccessibilityRenderObject.
1760     
1761     // Ignore invisible elements.
1762     if (!m_renderer || m_renderer->style()->visibility() != VISIBLE)
1763         return IgnoreObject;
1764
1765     // Anything marked as aria-hidden or a child of something aria-hidden must be hidden.
1766     if (ariaIsHidden())
1767         return IgnoreObject;
1768     
1769     // Anything that is a presentational role must be hidden.
1770     if (isPresentationalChildOfAriaRole())
1771         return IgnoreObject;
1772
1773     // Allow the platform to make a decision.
1774     AccessibilityObjectInclusion decision = accessibilityPlatformIncludesObject();
1775     if (decision == IncludeObject)
1776         return IncludeObject;
1777     if (decision == IgnoreObject)
1778         return IgnoreObject;
1779         
1780     return DefaultBehavior;
1781 }  
1782  
1783 bool AccessibilityRenderObject::accessibilityIsIgnored() const
1784 {
1785     // Check first if any of the common reasons cause this element to be ignored.
1786     // Then process other use cases that need to be applied to all the various roles
1787     // that AccessibilityRenderObjects take on.
1788     AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
1789     if (decision == IncludeObject)
1790         return false;
1791     if (decision == IgnoreObject)
1792         return true;
1793     
1794     // If this element is within a parent that cannot have children, it should not be exposed.
1795     if (isDescendantOfBarrenParent())
1796         return true;    
1797     
1798     if (roleValue() == IgnoredRole)
1799         return true;
1800     
1801     if (roleValue() == PresentationalRole || inheritsPresentationalRole())
1802         return true;
1803     
1804     // An ARIA tree can only have tree items and static text as children.
1805     if (!isAllowedChildOfTree())
1806         return true;
1807
1808     // Allow the platform to decide if the attachment is ignored or not.
1809     if (isAttachment())
1810         return accessibilityIgnoreAttachment();
1811     
1812     // ignore popup menu items because AppKit does
1813     for (RenderObject* parent = m_renderer->parent(); parent; parent = parent->parent()) {
1814         if (parent->isBoxModelObject() && toRenderBoxModelObject(parent)->isMenuList())
1815             return true;
1816     }
1817
1818     // find out if this element is inside of a label element.
1819     // if so, it may be ignored because it's the label for a checkbox or radio button
1820     AccessibilityObject* controlObject = correspondingControlForLabelElement();
1821     if (controlObject && !controlObject->exposesTitleUIElement() && controlObject->isCheckboxOrRadio())
1822         return true;
1823         
1824     // NOTE: BRs always have text boxes now, so the text box check here can be removed
1825     if (m_renderer->isText()) {
1826         // static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level
1827         if (parentObjectUnignored()->ariaRoleAttribute() == MenuItemRole
1828             || parentObjectUnignored()->ariaRoleAttribute() == MenuButtonRole)
1829             return true;
1830         RenderText* renderText = toRenderText(m_renderer);
1831         if (m_renderer->isBR() || !renderText->firstTextBox())
1832             return true;
1833
1834         // static text beneath TextControls is reported along with the text control text so it's ignored.
1835         for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) { 
1836             if (parent->roleValue() == TextFieldRole)
1837                 return true;
1838         }
1839
1840         // text elements that are just empty whitespace should not be returned
1841         return renderText->text()->containsOnlyWhitespace();
1842     }
1843     
1844     if (isHeading())
1845         return false;
1846     
1847     if (isLink())
1848         return false;
1849     
1850     // all controls are accessible
1851     if (isControl())
1852         return false;
1853     
1854     if (ariaRoleAttribute() != UnknownRole)
1855         return false;
1856
1857     // don't ignore labels, because they serve as TitleUIElements
1858     Node* node = m_renderer->node();
1859     if (node && node->hasTagName(labelTag))
1860         return false;
1861     
1862     // Anything that is content editable should not be ignored.
1863     // However, one cannot just call node->rendererIsEditable() since that will ask if its parents
1864     // are also editable. Only the top level content editable region should be exposed.
1865     if (node && node->isElementNode()) {
1866         Element* element = static_cast<Element*>(node);
1867         const AtomicString& contentEditable = element->getAttribute(contenteditableAttr);
1868         if (equalIgnoringCase(contentEditable, "true"))
1869             return false;
1870     }
1871     
1872     // List items play an important role in defining the structure of lists. They should not be ignored.
1873     if (roleValue() == ListItemRole)
1874         return false;
1875     
1876     // if this element has aria attributes on it, it should not be ignored.
1877     if (supportsARIAAttributes())
1878         return false;
1879     
1880     if (m_renderer->isBlockFlow() && m_renderer->childrenInline())
1881         return !toRenderBlock(m_renderer)->firstLineBox() && !mouseButtonListener();
1882     
1883     // ignore images seemingly used as spacers
1884     if (isImage()) {
1885         if (node && node->isElementNode()) {
1886             Element* elt = static_cast<Element*>(node);
1887             const AtomicString& alt = elt->getAttribute(altAttr);
1888             // don't ignore an image that has an alt tag
1889             if (!alt.isEmpty())
1890                 return false;
1891             // informal standard is to ignore images with zero-length alt strings
1892             if (!alt.isNull())
1893                 return true;
1894         }
1895         
1896         if (node && node->hasTagName(canvasTag)) {
1897             RenderHTMLCanvas* canvas = toRenderHTMLCanvas(m_renderer);
1898             if (canvas->height() <= 1 || canvas->width() <= 1)
1899                 return true;
1900             return false;
1901         }
1902         
1903         if (isNativeImage()) {
1904             // check for one-dimensional image
1905             RenderImage* image = toRenderImage(m_renderer);
1906             if (image->height() <= 1 || image->width() <= 1)
1907                 return true;
1908             
1909             // check whether rendered image was stretched from one-dimensional file image
1910             if (image->cachedImage()) {
1911                 LayoutSize imageSize = image->cachedImage()->imageSize(image->view()->zoomFactor());
1912                 return imageSize.height() <= 1 || imageSize.width() <= 1;
1913             }
1914         }
1915         return false;
1916     }
1917     
1918     if (isWebArea() || m_renderer->isListMarker())
1919         return false;
1920     
1921     // Using the help text to decide an element's visibility is not as definitive
1922     // as previous checks, so this should remain as one of the last.
1923     if (!helpText().isEmpty())
1924         return false;
1925     
1926     // By default, objects should be ignored so that the AX hierarchy is not 
1927     // filled with unnecessary items.
1928     return true;
1929 }
1930
1931 bool AccessibilityRenderObject::isLoaded() const
1932 {
1933     return !m_renderer->document()->parser();
1934 }
1935
1936 double AccessibilityRenderObject::estimatedLoadingProgress() const
1937 {
1938     if (!m_renderer)
1939         return 0;
1940     
1941     if (isLoaded())
1942         return 1.0;
1943     
1944     Page* page = m_renderer->document()->page();
1945     if (!page)
1946         return 0;
1947     
1948     return page->progress()->estimatedProgress();
1949 }
1950     
1951 int AccessibilityRenderObject::layoutCount() const
1952 {
1953     if (!m_renderer->isRenderView())
1954         return 0;
1955     return toRenderView(m_renderer)->frameView()->layoutCount();
1956 }
1957
1958 String AccessibilityRenderObject::text() const
1959 {
1960     // If this is a user defined static text, use the accessible name computation.
1961     if (ariaRoleAttribute() == StaticTextRole)
1962         return ariaAccessibilityDescription();
1963     
1964     if (!isTextControl() || isPasswordField())
1965         return String();
1966
1967     Node* node = m_renderer->node();
1968     if (!node)
1969         return String();
1970
1971     if (isNativeTextControl())
1972         return toRenderTextControl(m_renderer)->textFormControlElement()->value();
1973
1974     if (!node->isElementNode())
1975         return String();
1976     
1977     return static_cast<Element*>(node)->innerText();
1978 }
1979     
1980 int AccessibilityRenderObject::textLength() const
1981 {
1982     ASSERT(isTextControl());
1983     
1984     if (isPasswordField())
1985         return -1; // need to return something distinct from 0
1986     
1987     return text().length();
1988 }
1989
1990 PlainTextRange AccessibilityRenderObject::ariaSelectedTextRange() const
1991 {
1992     Node* node = m_renderer->node();
1993     if (!node)
1994         return PlainTextRange();
1995     
1996     ExceptionCode ec = 0;
1997     VisibleSelection visibleSelection = selection();
1998     RefPtr<Range> currentSelectionRange = visibleSelection.toNormalizedRange();
1999     if (!currentSelectionRange || !currentSelectionRange->intersectsNode(node, ec))
2000         return PlainTextRange();
2001     
2002     int start = indexForVisiblePosition(visibleSelection.start());
2003     int end = indexForVisiblePosition(visibleSelection.end());
2004     
2005     return PlainTextRange(start, end - start);
2006 }
2007
2008 String AccessibilityRenderObject::selectedText() const
2009 {
2010     ASSERT(isTextControl());
2011     
2012     if (isPasswordField())
2013         return String(); // need to return something distinct from empty string
2014     
2015     if (isNativeTextControl()) {
2016         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
2017         return textControl->selectedText();
2018     }
2019     
2020     if (ariaRoleAttribute() == UnknownRole)
2021         return String();
2022     
2023     return doAXStringForRange(ariaSelectedTextRange());
2024 }
2025
2026 const AtomicString& AccessibilityRenderObject::accessKey() const
2027 {
2028     Node* node = m_renderer->node();
2029     if (!node)
2030         return nullAtom;
2031     if (!node->isElementNode())
2032         return nullAtom;
2033     return static_cast<Element*>(node)->getAttribute(accesskeyAttr);
2034 }
2035
2036 VisibleSelection AccessibilityRenderObject::selection() const
2037 {
2038     return m_renderer->frame()->selection()->selection();
2039 }
2040
2041 PlainTextRange AccessibilityRenderObject::selectedTextRange() const
2042 {
2043     ASSERT(isTextControl());
2044     
2045     if (isPasswordField())
2046         return PlainTextRange();
2047     
2048     AccessibilityRole ariaRole = ariaRoleAttribute();
2049     if (isNativeTextControl() && ariaRole == UnknownRole) {
2050         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
2051         return PlainTextRange(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart());
2052     }
2053     
2054     if (ariaRole == UnknownRole)
2055         return PlainTextRange();
2056     
2057     return ariaSelectedTextRange();
2058 }
2059
2060 void AccessibilityRenderObject::setSelectedTextRange(const PlainTextRange& range)
2061 {
2062     if (isNativeTextControl()) {
2063         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
2064         textControl->setSelectionRange(range.start, range.start + range.length);
2065         return;
2066     }
2067
2068     Document* document = m_renderer->document();
2069     if (!document)
2070         return;
2071     Frame* frame = document->frame();
2072     if (!frame)
2073         return;
2074     Node* node = m_renderer->node();
2075     frame->selection()->setSelection(VisibleSelection(Position(node, range.start, Position::PositionIsOffsetInAnchor),
2076         Position(node, range.start + range.length, Position::PositionIsOffsetInAnchor), DOWNSTREAM));
2077 }
2078
2079 KURL AccessibilityRenderObject::url() const
2080 {
2081     if (isAnchor() && m_renderer->node()->hasTagName(aTag)) {
2082         if (HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(anchorElement()))
2083             return anchor->href();
2084     }
2085     
2086     if (isWebArea())
2087         return m_renderer->document()->url();
2088     
2089     if (isImage() && m_renderer->node() && m_renderer->node()->hasTagName(imgTag))
2090         return static_cast<HTMLImageElement*>(m_renderer->node())->src();
2091     
2092     if (isInputImage())
2093         return static_cast<HTMLInputElement*>(m_renderer->node())->src();
2094     
2095     return KURL();
2096 }
2097
2098 bool AccessibilityRenderObject::isUnvisited() const
2099 {
2100     // FIXME: Is it a privacy violation to expose unvisited information to accessibility APIs?
2101     return m_renderer->style()->isLink() && m_renderer->style()->insideLink() == InsideUnvisitedLink;
2102 }
2103
2104 bool AccessibilityRenderObject::isVisited() const
2105 {
2106     // FIXME: Is it a privacy violation to expose visited information to accessibility APIs?
2107     return m_renderer->style()->isLink() && m_renderer->style()->insideLink() == InsideVisitedLink;
2108 }
2109
2110 void AccessibilityRenderObject::setElementAttributeValue(const QualifiedName& attributeName, bool value)
2111 {
2112     if (!m_renderer)
2113         return;
2114     
2115     Node* node = m_renderer->node();
2116     if (!node || !node->isElementNode())
2117         return;
2118     
2119     Element* element = static_cast<Element*>(node);
2120     element->setAttribute(attributeName, (value) ? "true" : "false");        
2121 }
2122     
2123 bool AccessibilityRenderObject::elementAttributeValue(const QualifiedName& attributeName) const
2124 {
2125     if (!m_renderer)
2126         return false;
2127     
2128     return equalIgnoringCase(getAttribute(attributeName), "true");
2129 }
2130     
2131 bool AccessibilityRenderObject::isRequired() const
2132 {
2133     if (equalIgnoringCase(getAttribute(aria_requiredAttr), "true"))
2134         return true;
2135     
2136     Node* n = node();
2137     if (n && (n->isElementNode() && static_cast<Element*>(n)->isFormControlElement()))
2138         return static_cast<HTMLFormControlElement*>(n)->required();
2139     
2140     return false;
2141 }
2142
2143 bool AccessibilityRenderObject::isSelected() const
2144 {
2145     if (!m_renderer)
2146         return false;
2147     
2148     Node* node = m_renderer->node();
2149     if (!node)
2150         return false;
2151     
2152     const AtomicString& ariaSelected = getAttribute(aria_selectedAttr);
2153     if (equalIgnoringCase(ariaSelected, "true"))
2154         return true;    
2155     
2156     if (isTabItem() && isTabItemSelected())
2157         return true;
2158
2159     return false;
2160 }
2161
2162 bool AccessibilityRenderObject::isTabItemSelected() const
2163 {
2164     if (!isTabItem() || !m_renderer)
2165         return false;
2166     
2167     Node* node = m_renderer->node();
2168     if (!node || !node->isElementNode())
2169         return false;
2170     
2171     // The ARIA spec says a tab item can also be selected if it is aria-labeled by a tabpanel
2172     // that has keyboard focus inside of it, or if a tabpanel in its aria-controls list has KB
2173     // focus inside of it.
2174     AccessibilityObject* focusedElement = focusedUIElement();
2175     if (!focusedElement)
2176         return false;
2177     
2178     Vector<Element*> elements;
2179     elementsFromAttribute(elements, aria_controlsAttr);
2180     
2181     unsigned count = elements.size();
2182     for (unsigned k = 0; k < count; ++k) {
2183         Element* element = elements[k];
2184         AccessibilityObject* tabPanel = axObjectCache()->getOrCreate(element->renderer());
2185
2186         // A tab item should only control tab panels.
2187         if (!tabPanel || tabPanel->roleValue() != TabPanelRole)
2188             continue;
2189         
2190         AccessibilityObject* checkFocusElement = focusedElement;
2191         // Check if the focused element is a descendant of the element controlled by the tab item.
2192         while (checkFocusElement) {
2193             if (tabPanel == checkFocusElement)
2194                 return true;
2195             checkFocusElement = checkFocusElement->parentObject();
2196         }
2197     }
2198     
2199     return false;
2200 }
2201     
2202 bool AccessibilityRenderObject::isFocused() const
2203 {
2204     if (!m_renderer)
2205         return false;
2206     
2207     Document* document = m_renderer->document();
2208     if (!document)
2209         return false;
2210     
2211     Node* focusedNode = document->focusedNode();
2212     if (!focusedNode)
2213         return false;
2214     
2215     // A web area is represented by the Document node in the DOM tree, which isn't focusable.
2216     // Check instead if the frame's selection controller is focused
2217     if (focusedNode == m_renderer->node()
2218         || (roleValue() == WebAreaRole && document->frame()->selection()->isFocusedAndActive()))
2219         return true;
2220     
2221     return false;
2222 }
2223
2224 void AccessibilityRenderObject::setFocused(bool on)
2225 {
2226     if (!canSetFocusAttribute())
2227         return;
2228     
2229     if (!on)
2230         m_renderer->document()->setFocusedNode(0);
2231     else {
2232         if (m_renderer->node()->isElementNode())
2233             static_cast<Element*>(m_renderer->node())->focus();
2234         else
2235             m_renderer->document()->setFocusedNode(m_renderer->node());
2236     }
2237 }
2238
2239 void AccessibilityRenderObject::changeValueByStep(bool increase)
2240 {
2241     float step = stepValueForRange();
2242     float value = valueForRange();
2243     
2244     value += increase ? step : -step;
2245
2246     setValue(String::number(value));
2247     
2248     axObjectCache()->postNotification(m_renderer, AXObjectCache::AXValueChanged, true);
2249 }
2250     
2251 void AccessibilityRenderObject::changeValueByPercent(float percentChange)
2252 {
2253     float range = maxValueForRange() - minValueForRange();
2254     float value = valueForRange();
2255     
2256     value += range * (percentChange / 100);
2257     setValue(String::number(value));
2258     
2259     axObjectCache()->postNotification(m_renderer, AXObjectCache::AXValueChanged, true);
2260 }
2261
2262 void AccessibilityRenderObject::setSelectedRows(AccessibilityChildrenVector& selectedRows)
2263 {
2264     // Setting selected only makes sense in trees and tables (and tree-tables).
2265     AccessibilityRole role = roleValue();
2266     if (role != TreeRole && role != TreeGridRole && role != TableRole)
2267         return;
2268     
2269     bool isMulti = isMultiSelectable();
2270     unsigned count = selectedRows.size();
2271     if (count > 1 && !isMulti)
2272         count = 1;
2273     
2274     for (unsigned k = 0; k < count; ++k)
2275         selectedRows[k]->setSelected(true);
2276 }
2277     
2278 void AccessibilityRenderObject::setValue(const String& string)
2279 {
2280     if (!m_renderer || !m_renderer->node() || !m_renderer->node()->isElementNode())
2281         return;
2282     Element* element = static_cast<Element*>(m_renderer->node());
2283
2284     if (!m_renderer->isBoxModelObject())
2285         return;
2286     RenderBoxModelObject* renderer = toRenderBoxModelObject(m_renderer);
2287
2288     // FIXME: Do we want to do anything here for ARIA textboxes?
2289     if (renderer->isTextField()) {
2290         // FIXME: This is not safe!  Other elements could have a TextField renderer.
2291         static_cast<HTMLInputElement*>(element)->setValue(string);
2292     } else if (renderer->isTextArea()) {
2293         // FIXME: This is not safe!  Other elements could have a TextArea renderer.
2294         static_cast<HTMLTextAreaElement*>(element)->setValue(string);
2295     }
2296 }
2297
2298 void AccessibilityRenderObject::ariaOwnsElements(AccessibilityChildrenVector& axObjects) const
2299 {
2300     Vector<Element*> elements;
2301     elementsFromAttribute(elements, aria_ownsAttr);
2302     
2303     unsigned count = elements.size();
2304     for (unsigned k = 0; k < count; ++k) {
2305         RenderObject* render = elements[k]->renderer();
2306         AccessibilityObject* obj = axObjectCache()->getOrCreate(render);
2307         if (obj)
2308             axObjects.append(obj);
2309     }
2310 }
2311
2312 bool AccessibilityRenderObject::supportsARIAOwns() const
2313 {
2314     if (!m_renderer)
2315         return false;
2316     const AtomicString& ariaOwns = getAttribute(aria_ownsAttr);
2317
2318     return !ariaOwns.isEmpty();
2319 }
2320     
2321 bool AccessibilityRenderObject::isEnabled() const
2322 {
2323     ASSERT(m_renderer);
2324     
2325     if (equalIgnoringCase(getAttribute(aria_disabledAttr), "true"))
2326         return false;
2327     
2328     Node* node = m_renderer->node();
2329     if (!node || !node->isElementNode())
2330         return true;
2331
2332     return static_cast<Element*>(node)->isEnabledFormControl();
2333 }
2334
2335 RenderView* AccessibilityRenderObject::topRenderer() const
2336 {
2337     Document* topDoc = topDocument();
2338     if (!topDoc)
2339         return 0;
2340     
2341     return topDoc->renderView();
2342 }
2343
2344 Document* AccessibilityRenderObject::document() const
2345 {
2346     if (!m_renderer)
2347         return 0;
2348     return m_renderer->document();
2349 }
2350
2351 Document* AccessibilityRenderObject::topDocument() const
2352 {
2353     if (!document())
2354         return 0;
2355     return document()->topDocument();
2356 }
2357     
2358 FrameView* AccessibilityRenderObject::topDocumentFrameView() const
2359 {
2360     RenderView* renderView = topRenderer();
2361     if (!renderView || !renderView->view())
2362         return 0;
2363     return renderView->view()->frameView();
2364 }
2365
2366 Widget* AccessibilityRenderObject::widget() const
2367 {
2368     if (!m_renderer->isBoxModelObject() || !toRenderBoxModelObject(m_renderer)->isWidget())
2369         return 0;
2370     return toRenderWidget(m_renderer)->widget();
2371 }
2372
2373 AccessibilityObject* AccessibilityRenderObject::accessibilityParentForImageMap(HTMLMapElement* map) const
2374 {
2375     // find an image that is using this map
2376     if (!map)
2377         return 0;
2378
2379     HTMLImageElement* imageElement = map->imageElement();
2380     if (!imageElement)
2381         return 0;
2382     
2383     return axObjectCache()->getOrCreate(imageElement->renderer());
2384 }
2385     
2386 void AccessibilityRenderObject::getDocumentLinks(AccessibilityChildrenVector& result)
2387 {
2388     Document* document = m_renderer->document();
2389     RefPtr<HTMLCollection> coll = document->links();
2390     Node* curr = coll->firstItem();
2391     while (curr) {
2392         RenderObject* obj = curr->renderer();
2393         if (obj) {
2394             RefPtr<AccessibilityObject> axobj = document->axObjectCache()->getOrCreate(obj);
2395             ASSERT(axobj);
2396             if (!axobj->accessibilityIsIgnored() && axobj->isLink())
2397                 result.append(axobj);
2398         } else {
2399             Node* parent = curr->parentNode();
2400             if (parent && curr->hasTagName(areaTag) && parent->hasTagName(mapTag)) {
2401                 AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(axObjectCache()->getOrCreate(ImageMapLinkRole));
2402                 areaObject->setHTMLAreaElement(static_cast<HTMLAreaElement*>(curr));
2403                 areaObject->setHTMLMapElement(static_cast<HTMLMapElement*>(parent));
2404                 areaObject->setParent(accessibilityParentForImageMap(static_cast<HTMLMapElement*>(parent)));
2405
2406                 result.append(areaObject);
2407             }
2408         }
2409         curr = coll->nextItem();
2410     }
2411 }
2412
2413 FrameView* AccessibilityRenderObject::documentFrameView() const 
2414
2415     if (!m_renderer || !m_renderer->document()) 
2416         return 0; 
2417
2418     // this is the RenderObject's Document's Frame's FrameView 
2419     return m_renderer->document()->view();
2420 }
2421
2422 Widget* AccessibilityRenderObject::widgetForAttachmentView() const
2423 {
2424     if (!isAttachment())
2425         return 0;
2426     return toRenderWidget(m_renderer)->widget();
2427 }
2428
2429 FrameView* AccessibilityRenderObject::frameViewIfRenderView() const
2430 {
2431     if (!m_renderer->isRenderView())
2432         return 0;
2433     // this is the RenderObject's Document's renderer's FrameView
2434     return m_renderer->view()->frameView();
2435 }
2436
2437 // This function is like a cross-platform version of - (WebCoreTextMarkerRange*)textMarkerRange. It returns
2438 // a Range that we can convert to a WebCoreTextMarkerRange in the Obj-C file
2439 VisiblePositionRange AccessibilityRenderObject::visiblePositionRange() const
2440 {
2441     if (!m_renderer)
2442         return VisiblePositionRange();
2443     
2444     // construct VisiblePositions for start and end
2445     Node* node = m_renderer->node();
2446     if (!node)
2447         return VisiblePositionRange();
2448
2449     VisiblePosition startPos = firstPositionInOrBeforeNode(node);
2450     VisiblePosition endPos = lastPositionInOrAfterNode(node);
2451
2452     // the VisiblePositions are equal for nodes like buttons, so adjust for that
2453     // FIXME: Really?  [button, 0] and [button, 1] are distinct (before and after the button)
2454     // I expect this code is only hit for things like empty divs?  In which case I don't think
2455     // the behavior is correct here -- eseidel
2456     if (startPos == endPos) {
2457         endPos = endPos.next();
2458         if (endPos.isNull())
2459             endPos = startPos;
2460     }
2461
2462     return VisiblePositionRange(startPos, endPos);
2463 }
2464
2465 VisiblePositionRange AccessibilityRenderObject::visiblePositionRangeForLine(unsigned lineCount) const
2466 {
2467     if (!lineCount || !m_renderer)
2468         return VisiblePositionRange();
2469     
2470     // iterate over the lines
2471     // FIXME: this is wrong when lineNumber is lineCount+1,  because nextLinePosition takes you to the
2472     // last offset of the last line
2473     VisiblePosition visiblePos = m_renderer->document()->renderer()->positionForPoint(IntPoint());
2474     VisiblePosition savedVisiblePos;
2475     while (--lineCount) {
2476         savedVisiblePos = visiblePos;
2477         visiblePos = nextLinePosition(visiblePos, 0);
2478         if (visiblePos.isNull() || visiblePos == savedVisiblePos)
2479             return VisiblePositionRange();
2480     }
2481     
2482     // make a caret selection for the marker position, then extend it to the line
2483     // NOTE: ignores results of sel.modify because it returns false when
2484     // starting at an empty line.  The resulting selection in that case
2485     // will be a caret at visiblePos.
2486     FrameSelection selection;
2487     selection.setSelection(VisibleSelection(visiblePos));
2488     selection.modify(FrameSelection::AlterationExtend, DirectionRight, LineBoundary);
2489     
2490     return VisiblePositionRange(selection.selection().visibleStart(), selection.selection().visibleEnd());
2491 }
2492     
2493 VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(int index) const
2494 {
2495     if (!m_renderer)
2496         return VisiblePosition();
2497     
2498     if (isNativeTextControl())
2499         return toRenderTextControl(m_renderer)->visiblePositionForIndex(index);
2500
2501     if (!allowsTextRanges() && !m_renderer->isText())
2502         return VisiblePosition();
2503     
2504     Node* node = m_renderer->node();
2505     if (!node)
2506         return VisiblePosition();
2507     
2508     if (index <= 0)
2509         return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
2510     
2511     ExceptionCode ec = 0;
2512     RefPtr<Range> range = Range::create(m_renderer->document());
2513     range->selectNodeContents(node, ec);
2514     CharacterIterator it(range.get());
2515     it.advance(index - 1);
2516     return VisiblePosition(Position(it.range()->endContainer(ec), it.range()->endOffset(ec), Position::PositionIsOffsetInAnchor), UPSTREAM);
2517 }
2518     
2519 int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& pos) const
2520 {
2521     if (isNativeTextControl()) {
2522         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
2523         return textControl->indexForVisiblePosition(pos);
2524     }
2525
2526     if (!isTextControl())
2527         return 0;
2528     
2529     Node* node = m_renderer->node();
2530     if (!node)
2531         return 0;
2532     
2533     Position indexPosition = pos.deepEquivalent();
2534     if (indexPosition.isNull() || rootEditableElementForPosition(indexPosition) != node)
2535         return 0;
2536     
2537     ExceptionCode ec = 0;
2538     RefPtr<Range> range = Range::create(m_renderer->document());
2539     range->setStart(node, 0, ec);
2540     range->setEnd(indexPosition, ec);
2541
2542 #if PLATFORM(GTK)
2543     // We need to consider replaced elements for GTK, as they will be
2544     // presented with the 'object replacement character' (0xFFFC).
2545     return TextIterator::rangeLength(range.get(), true);
2546 #else
2547     return TextIterator::rangeLength(range.get());
2548 #endif
2549 }
2550
2551 Element* AccessibilityRenderObject::rootEditableElementForPosition(const Position& position) const
2552 {
2553     // Find the root editable or pseudo-editable (i.e. having an editable ARIA role) element.
2554     Element* result = 0;
2555     
2556     Element* rootEditableElement = position.rootEditableElement();
2557
2558     for (Element* e = position.element(); e && e != rootEditableElement; e = e->parentElement()) {
2559         if (nodeIsTextControl(e))
2560             result = e;
2561         if (e->hasTagName(bodyTag))
2562             break;
2563     }
2564
2565     if (result)
2566         return result;
2567
2568     return rootEditableElement;
2569 }
2570
2571 bool AccessibilityRenderObject::nodeIsTextControl(const Node* node) const
2572 {
2573     if (!node)
2574         return false;
2575
2576     const AccessibilityObject* axObjectForNode = axObjectCache()->getOrCreate(node->renderer());
2577     if (!axObjectForNode)
2578         return false;
2579
2580     return axObjectForNode->isTextControl();
2581 }
2582
2583 LayoutRect AccessibilityRenderObject::boundsForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
2584 {
2585     if (visiblePositionRange.isNull())
2586         return LayoutRect();
2587     
2588     // Create a mutable VisiblePositionRange.
2589     VisiblePositionRange range(visiblePositionRange);
2590     LayoutRect rect1 = range.start.absoluteCaretBounds();
2591     LayoutRect rect2 = range.end.absoluteCaretBounds();
2592     
2593     // readjust for position at the edge of a line.  This is to exclude line rect that doesn't need to be accounted in the range bounds
2594     if (rect2.y() != rect1.y()) {
2595         VisiblePosition endOfFirstLine = endOfLine(range.start);
2596         if (range.start == endOfFirstLine) {
2597             range.start.setAffinity(DOWNSTREAM);
2598             rect1 = range.start.absoluteCaretBounds();
2599         }
2600         if (range.end == endOfFirstLine) {
2601             range.end.setAffinity(UPSTREAM);
2602             rect2 = range.end.absoluteCaretBounds();
2603         }
2604     }
2605     
2606     LayoutRect ourrect = rect1;
2607     ourrect.unite(rect2);
2608     
2609     // if the rectangle spans lines and contains multiple text chars, use the range's bounding box intead
2610     if (rect1.maxY() != rect2.maxY()) {
2611         RefPtr<Range> dataRange = makeRange(range.start, range.end);
2612         LayoutRect boundingBox = dataRange->boundingBox();
2613         String rangeString = plainText(dataRange.get());
2614         if (rangeString.length() > 1 && !boundingBox.isEmpty())
2615             ourrect = boundingBox;
2616     }
2617     
2618 #if PLATFORM(MAC)
2619     return m_renderer->document()->view()->contentsToScreen(ourrect);
2620 #else
2621     return ourrect;
2622 #endif
2623 }
2624     
2625 void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePositionRange& range) const
2626 {
2627     if (range.start.isNull() || range.end.isNull())
2628         return;
2629     
2630     // make selection and tell the document to use it. if it's zero length, then move to that position
2631     if (range.start == range.end)
2632         m_renderer->frame()->selection()->moveTo(range.start, UserTriggered);
2633     else {
2634         VisibleSelection newSelection = VisibleSelection(range.start, range.end);
2635         m_renderer->frame()->selection()->setSelection(newSelection);
2636     }    
2637 }
2638
2639 VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const LayoutPoint& point) const
2640 {
2641     if (!m_renderer)
2642         return VisiblePosition();
2643     
2644     // convert absolute point to view coordinates
2645     Document* topDoc = topDocument();
2646     if (!topDoc || !topDoc->renderer() || !topDoc->renderer()->view())
2647         return VisiblePosition();
2648     
2649     FrameView* frameView = topDoc->renderer()->view()->frameView();
2650     if (!frameView)
2651         return VisiblePosition();
2652     
2653     RenderView* renderView = topRenderer();
2654     if (!renderView)
2655         return VisiblePosition();
2656     
2657     Node* innerNode = 0;
2658     
2659     // locate the node containing the point
2660     LayoutPoint pointResult;
2661     while (1) {
2662         LayoutPoint ourpoint;
2663 #if PLATFORM(MAC)
2664         ourpoint = frameView->screenToContents(point);
2665 #else
2666         ourpoint = point;
2667 #endif
2668         HitTestRequest request(HitTestRequest::ReadOnly |
2669                                HitTestRequest::Active);
2670         HitTestResult result(ourpoint);
2671         renderView->layer()->hitTest(request, result);
2672         innerNode = result.innerNode();
2673         if (!innerNode)
2674             return VisiblePosition();
2675         
2676         RenderObject* renderer = innerNode->renderer();
2677         if (!renderer)
2678             return VisiblePosition();
2679         
2680         pointResult = result.localPoint();
2681
2682         // done if hit something other than a widget
2683         if (!renderer->isWidget())
2684             break;
2685
2686         // descend into widget (FRAME, IFRAME, OBJECT...)
2687         Widget* widget = toRenderWidget(renderer)->widget();
2688         if (!widget || !widget->isFrameView())
2689             break;
2690         Frame* frame = static_cast<FrameView*>(widget)->frame();
2691         if (!frame)
2692             break;
2693         renderView = frame->document()->renderView();
2694         frameView = static_cast<FrameView*>(widget);
2695     }
2696     
2697     return innerNode->renderer()->positionForPoint(pointResult);
2698 }
2699
2700 // NOTE: Consider providing this utility method as AX API
2701 VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const
2702 {
2703     if (!isTextControl())
2704         return VisiblePosition();
2705     
2706     // lastIndexOK specifies whether the position after the last character is acceptable
2707     if (indexValue >= text().length()) {
2708         if (!lastIndexOK || indexValue > text().length())
2709             return VisiblePosition();
2710     }
2711     VisiblePosition position = visiblePositionForIndex(indexValue);
2712     position.setAffinity(DOWNSTREAM);
2713     return position;
2714 }
2715
2716 // NOTE: Consider providing this utility method as AX API
2717 int AccessibilityRenderObject::index(const VisiblePosition& position) const
2718 {
2719     if (!isTextControl())
2720         return -1;
2721
2722     if (renderObjectContainsPosition(m_renderer, position.deepEquivalent()))
2723         return indexForVisiblePosition(position);
2724     
2725     return -1;
2726 }
2727
2728 // Given a line number, the range of characters of the text associated with this accessibility
2729 // object that contains the line number.
2730 PlainTextRange AccessibilityRenderObject::doAXRangeForLine(unsigned lineNumber) const
2731 {
2732     if (!isTextControl())
2733         return PlainTextRange();
2734     
2735     // iterate to the specified line
2736     VisiblePosition visiblePos = visiblePositionForIndex(0);
2737     VisiblePosition savedVisiblePos;
2738     for (unsigned lineCount = lineNumber; lineCount; lineCount -= 1) {
2739         savedVisiblePos = visiblePos;
2740         visiblePos = nextLinePosition(visiblePos, 0);
2741         if (visiblePos.isNull() || visiblePos == savedVisiblePos)
2742             return PlainTextRange();
2743     }
2744
2745     // Get the end of the line based on the starting position.
2746     VisiblePosition endPosition = endOfLine(visiblePos);
2747
2748     int index1 = indexForVisiblePosition(visiblePos);
2749     int index2 = indexForVisiblePosition(endPosition);
2750     
2751     // add one to the end index for a line break not caused by soft line wrap (to match AppKit)
2752     if (endPosition.affinity() == DOWNSTREAM && endPosition.next().isNotNull())
2753         index2 += 1;
2754     
2755     // return nil rather than an zero-length range (to match AppKit)
2756     if (index1 == index2)
2757         return PlainTextRange();
2758     
2759     return PlainTextRange(index1, index2 - index1);
2760 }
2761
2762 // The composed character range in the text associated with this accessibility object that
2763 // is specified by the given index value. This parameterized attribute returns the complete
2764 // range of characters (including surrogate pairs of multi-byte glyphs) at the given index.
2765 PlainTextRange AccessibilityRenderObject::doAXRangeForIndex(unsigned index) const
2766 {
2767     if (!isTextControl())
2768         return PlainTextRange();
2769     
2770     String elementText = text();
2771     if (!elementText.length() || index > elementText.length() - 1)
2772         return PlainTextRange();
2773     
2774     return PlainTextRange(index, 1);
2775 }
2776
2777 // A substring of the text associated with this accessibility object that is
2778 // specified by the given character range.
2779 String AccessibilityRenderObject::doAXStringForRange(const PlainTextRange& range) const
2780 {
2781     if (isPasswordField())
2782         return String();
2783     
2784     if (!range.length)
2785         return String();
2786     
2787     if (!isTextControl())
2788         return String();
2789     
2790     String elementText = text();
2791     if (range.start + range.length > elementText.length())
2792         return String();
2793     
2794     return elementText.substring(range.start, range.length);
2795 }
2796
2797 // The bounding rectangle of the text associated with this accessibility object that is
2798 // specified by the given range. This is the bounding rectangle a sighted user would see
2799 // on the display screen, in pixels.
2800 LayoutRect AccessibilityRenderObject::doAXBoundsForRange(const PlainTextRange& range) const
2801 {
2802     if (allowsTextRanges())
2803         return boundsForVisiblePositionRange(visiblePositionRangeForRange(range));
2804     return LayoutRect();
2805 }
2806
2807 AccessibilityObject* AccessibilityRenderObject::accessibilityImageMapHitTest(HTMLAreaElement* area, const IntPoint& point) const
2808 {
2809     if (!area)
2810         return 0;
2811     
2812     HTMLMapElement* map = static_cast<HTMLMapElement*>(area->parentNode());
2813     AccessibilityObject* parent = accessibilityParentForImageMap(map);
2814     if (!parent)
2815         return 0;
2816     
2817     AccessibilityObject::AccessibilityChildrenVector children = parent->children();
2818     
2819     unsigned count = children.size();
2820     for (unsigned k = 0; k < count; ++k) {
2821         if (children[k]->elementRect().contains(point))
2822             return children[k].get();
2823     }
2824     
2825     return 0;
2826 }
2827     
2828 AccessibilityObject* AccessibilityRenderObject::accessibilityHitTest(const IntPoint& point) const
2829 {
2830     if (!m_renderer || !m_renderer->hasLayer())
2831         return 0;
2832     
2833     RenderLayer* layer = toRenderBox(m_renderer)->layer();
2834      
2835     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
2836     HitTestResult hitTestResult = HitTestResult(point);
2837     layer->hitTest(request, hitTestResult);
2838     if (!hitTestResult.innerNode())
2839         return 0;
2840     Node* node = hitTestResult.innerNode()->shadowAncestorNode();
2841
2842     if (node->hasTagName(areaTag)) 
2843         return accessibilityImageMapHitTest(static_cast<HTMLAreaElement*>(node), point);
2844     
2845     if (node->hasTagName(optionTag))
2846         node = static_cast<HTMLOptionElement*>(node)->ownerSelectElement();
2847     
2848     RenderObject* obj = node->renderer();
2849     if (!obj)
2850         return 0;
2851     
2852     AccessibilityObject* result = obj->document()->axObjectCache()->getOrCreate(obj);
2853     result->updateChildrenIfNecessary();
2854
2855     // Allow the element to perform any hit-testing it might need to do to reach non-render children.
2856     result = result->elementAccessibilityHitTest(point);
2857     
2858     if (result && result->accessibilityIsIgnored()) {
2859         // If this element is the label of a control, a hit test should return the control.
2860         AccessibilityObject* controlObject = result->correspondingControlForLabelElement();
2861         if (controlObject && !controlObject->exposesTitleUIElement())
2862             return controlObject;
2863
2864         result = result->parentObjectUnignored();
2865     }
2866
2867     return result;
2868 }
2869
2870 bool AccessibilityRenderObject::shouldFocusActiveDescendant() const
2871 {
2872     switch (ariaRoleAttribute()) {
2873     case GroupRole:
2874     case ComboBoxRole:
2875     case ListBoxRole:
2876     case MenuRole:
2877     case MenuBarRole:
2878     case RadioGroupRole:
2879     case RowRole:
2880     case PopUpButtonRole:
2881     case ProgressIndicatorRole:
2882     case ToolbarRole:
2883     case OutlineRole:
2884     case TreeRole:
2885     case GridRole:
2886     /* FIXME: replace these with actual roles when they are added to AccessibilityRole
2887     composite
2888     alert
2889     alertdialog
2890     status
2891     timer
2892     */
2893         return true;
2894     default:
2895         return false;
2896     }
2897 }
2898
2899 AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
2900 {
2901     if (!m_renderer)
2902         return 0;
2903     
2904     if (m_renderer->node() && !m_renderer->node()->isElementNode())
2905         return 0;
2906     Element* element = static_cast<Element*>(m_renderer->node());
2907         
2908     const AtomicString& activeDescendantAttrStr = element->getAttribute(aria_activedescendantAttr);
2909     if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
2910         return 0;
2911     
2912     Element* target = element->treeScope()->getElementById(activeDescendantAttrStr);
2913     if (!target)
2914         return 0;
2915     
2916     AccessibilityObject* obj = axObjectCache()->getOrCreate(target->renderer());
2917     if (obj && obj->isAccessibilityRenderObject())
2918     // an activedescendant is only useful if it has a renderer, because that's what's needed to post the notification
2919         return obj;
2920     return 0;
2921 }
2922
2923 void AccessibilityRenderObject::handleAriaExpandedChanged()
2924 {
2925     // Find if a parent of this object should handle aria-expanded changes.
2926     AccessibilityObject* containerParent = this->parentObject();
2927     while (containerParent) {
2928         bool foundParent = false;
2929         
2930         switch (containerParent->roleValue()) {
2931         case TreeRole:
2932         case TreeGridRole:
2933         case GridRole:
2934         case TableRole:
2935         case BrowserRole:
2936             foundParent = true;
2937             break;
2938         default:
2939             break;
2940         }
2941         
2942         if (foundParent)
2943             break;
2944         
2945         containerParent = containerParent->parentObject();
2946     }
2947     
2948     // Post that the row count changed.
2949     if (containerParent)
2950         axObjectCache()->postNotification(containerParent, document(), AXObjectCache::AXRowCountChanged, true);
2951
2952     // Post that the specific row either collapsed or expanded.
2953     if (roleValue() == RowRole || roleValue() == TreeItemRole)
2954         axObjectCache()->postNotification(this, document(), isExpanded() ? AXObjectCache::AXRowExpanded : AXObjectCache::AXRowCollapsed, true);
2955 }
2956
2957 void AccessibilityRenderObject::handleActiveDescendantChanged()
2958 {
2959     Element* element = static_cast<Element*>(renderer()->node());
2960     if (!element)
2961         return;
2962     Document* doc = renderer()->document();
2963     if (!doc->frame()->selection()->isFocusedAndActive() || doc->focusedNode() != element)
2964         return; 
2965     AccessibilityRenderObject* activedescendant = static_cast<AccessibilityRenderObject*>(activeDescendant());
2966     
2967     if (activedescendant && shouldFocusActiveDescendant())
2968         doc->axObjectCache()->postNotification(m_renderer, AXObjectCache::AXActiveDescendantChanged, true);
2969 }
2970
2971 AccessibilityObject* AccessibilityRenderObject::correspondingControlForLabelElement() const
2972 {
2973     HTMLLabelElement* labelElement = labelElementContainer();
2974     if (!labelElement)
2975         return 0;
2976     
2977     HTMLElement* correspondingControl = labelElement->control();
2978     if (!correspondingControl)
2979         return 0;
2980     
2981     return axObjectCache()->getOrCreate(correspondingControl->renderer());     
2982 }
2983
2984 AccessibilityObject* AccessibilityRenderObject::correspondingLabelForControlElement() const
2985 {
2986     if (!m_renderer)
2987         return 0;
2988
2989     Node* node = m_renderer->node();
2990     if (node && node->isHTMLElement()) {
2991         HTMLLabelElement* label = labelForElement(static_cast<Element*>(node));
2992         if (label)
2993             return axObjectCache()->getOrCreate(label->renderer());
2994     }
2995
2996     return 0;
2997 }
2998
2999 bool AccessibilityRenderObject::renderObjectIsObservable(RenderObject* renderer) const
3000 {
3001     // AX clients will listen for AXValueChange on a text control.
3002     if (renderer->isTextControl())
3003         return true;
3004     
3005     // AX clients will listen for AXSelectedChildrenChanged on listboxes.
3006     Node* node = renderer->node();
3007     if (nodeHasRole(node, "listbox") || (renderer->isBoxModelObject() && toRenderBoxModelObject(renderer)->isListBox()))
3008         return true;
3009
3010     // Textboxes should send out notifications.
3011     if (nodeHasRole(node, "textbox"))
3012         return true;
3013     
3014     return false;
3015 }
3016     
3017 AccessibilityObject* AccessibilityRenderObject::observableObject() const
3018 {
3019     // Find the object going up the parent chain that is used in accessibility to monitor certain notifications.
3020     for (RenderObject* renderer = m_renderer; renderer && renderer->node(); renderer = renderer->parent()) {
3021         if (renderObjectIsObservable(renderer))
3022             return axObjectCache()->getOrCreate(renderer);
3023     }
3024     
3025     return 0;
3026 }
3027
3028 AccessibilityRole AccessibilityRenderObject::remapAriaRoleDueToParent(AccessibilityRole role) const
3029 {
3030     // Some objects change their role based on their parent.
3031     // However, asking for the unignoredParent calls accessibilityIsIgnored(), which can trigger a loop. 
3032     // While inside the call stack of creating an element, we need to avoid accessibilityIsIgnored().
3033     // https://bugs.webkit.org/show_bug.cgi?id=65174
3034
3035     if (role != ListBoxOptionRole && role != MenuItemRole)
3036         return role;
3037     
3038     for (AccessibilityObject* parent = parentObject(); parent && !parent->accessibilityIsIgnored(); parent = parent->parentObject()) {
3039         AccessibilityRole parentAriaRole = parent->ariaRoleAttribute();
3040
3041         // Selects and listboxes both have options as child roles, but they map to different roles within WebCore.
3042         if (role == ListBoxOptionRole && parentAriaRole == MenuRole)
3043             return MenuItemRole;
3044         // An aria "menuitem" may map to MenuButton or MenuItem depending on its parent.
3045         if (role == MenuItemRole && parentAriaRole == GroupRole)
3046             return MenuButtonRole;
3047         
3048         // If the parent had a different role, then we don't need to continue searching up the chain.
3049         if (parentAriaRole)
3050             break;
3051     }
3052     
3053     return role;
3054 }
3055     
3056 AccessibilityRole AccessibilityRenderObject::determineAriaRoleAttribute() const
3057 {
3058     const AtomicString& ariaRole = getAttribute(roleAttr);
3059     if (ariaRole.isNull() || ariaRole.isEmpty())
3060         return UnknownRole;
3061     
3062     AccessibilityRole role = ariaRoleToWebCoreRole(ariaRole);
3063
3064     if (role == ButtonRole && ariaHasPopup())
3065         role = PopUpButtonRole;
3066
3067     if (role == TextAreaRole && !ariaIsMultiline())
3068         role = TextFieldRole;
3069
3070     role = remapAriaRoleDueToParent(role);
3071     
3072     if (role)
3073         return role;
3074
3075     return UnknownRole;
3076 }
3077
3078 AccessibilityRole AccessibilityRenderObject::ariaRoleAttribute() const
3079 {
3080     return m_ariaRole;
3081 }
3082     
3083 void AccessibilityRenderObject::updateAccessibilityRole()
3084 {
3085     bool ignoredStatus = accessibilityIsIgnored();
3086     m_role = determineAccessibilityRole();
3087     
3088     // The AX hierarchy only needs to be updated if the ignored status of an element has changed.
3089     if (ignoredStatus != accessibilityIsIgnored())
3090         childrenChanged();
3091 }
3092     
3093 AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole()
3094 {
3095     if (!m_renderer)
3096         return UnknownRole;
3097
3098     m_ariaRole = determineAriaRoleAttribute();
3099     
3100     Node* node = m_renderer->node();
3101     AccessibilityRole ariaRole = ariaRoleAttribute();
3102     if (ariaRole != UnknownRole)
3103         return ariaRole;
3104
3105     RenderBoxModelObject* cssBox = renderBoxModelObject();
3106
3107     if (node && node->isLink()) {
3108         if (cssBox && cssBox->isImage())
3109             return ImageMapRole;
3110         return WebCoreLinkRole;
3111     }
3112     if (cssBox && cssBox->isListItem())
3113         return ListItemRole;
3114     if (m_renderer->isListMarker())
3115         return ListMarkerRole;
3116     if (node && node->hasTagName(buttonTag))
3117         return ButtonRole;
3118     if (m_renderer->isText())
3119         return StaticTextRole;
3120     if (cssBox && cssBox->isImage()) {
3121         if (node && node->hasTagName(inputTag))
3122             return ButtonRole;
3123         return ImageRole;
3124     }
3125     if (node && node->hasTagName(canvasTag))
3126         return ImageRole;
3127
3128     if (cssBox && cssBox->isRenderView())
3129         return WebAreaRole;
3130     
3131     if (cssBox && cssBox->isTextField())
3132         return TextFieldRole;
3133     
3134     if (cssBox && cssBox->isTextArea())
3135         return TextAreaRole;
3136
3137     if (node && node->hasTagName(inputTag)) {
3138         HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
3139         if (input->isCheckbox())
3140             return CheckBoxRole;
3141         if (input->isRadioButton())
3142             return RadioButtonRole;
3143         if (input->isTextButton())
3144             return ButtonRole;
3145     }
3146
3147     if (node && node->hasTagName(buttonTag))
3148         return ButtonRole;
3149
3150     if (isFileUploadButton())
3151         return ButtonRole;
3152     
3153     if (cssBox && cssBox->isMenuList())
3154         return PopUpButtonRole;
3155     
3156     if (headingLevel())
3157         return HeadingRole;
3158     
3159 #if ENABLE(MATHML)
3160     if (node && node->hasTagName(MathMLNames::mathTag))
3161         return DocumentMathRole;
3162 #endif
3163     
3164     if (node && node->hasTagName(ddTag))
3165         return DefinitionListDefinitionRole;
3166     
3167     if (node && node->hasTagName(dtTag))
3168         return DefinitionListTermRole;
3169
3170     if (node && (node->hasTagName(rpTag) || node->hasTagName(rtTag)))
3171         return AnnotationRole;
3172
3173 #if PLATFORM(GTK)
3174     // Gtk ATs expect all tables, data and layout, to be exposed as tables.
3175     if (node && (node->hasTagName(tdTag) || node->hasTagName(thTag)))
3176         return CellRole;
3177
3178     if (node && node->hasTagName(trTag))
3179         return RowRole;
3180
3181     if (node && node->hasTagName(tableTag))
3182         return TableRole;
3183 #endif
3184
3185     // Table sections should be ignored.
3186     if (m_renderer->isTableSection())
3187         return IgnoredRole;
3188     
3189 #if PLATFORM(GTK)
3190     if (m_renderer->isHR())
3191         return SplitterRole;
3192
3193     if (node && node->hasTagName(pTag))
3194         return ParagraphRole;
3195
3196     if (node && node->hasTagName(labelTag))
3197         return LabelRole;
3198
3199     if (node && node->hasTagName(divTag))
3200         return DivRole;
3201
3202     if (node && node->hasTagName(formTag))
3203         return FormRole;
3204 #else
3205     if (node && node->hasTagName(labelTag))
3206         return GroupRole;
3207 #endif
3208
3209     if (m_renderer->isBlockFlow())
3210         return GroupRole;
3211     
3212     // If the element does not have role, but it has ARIA attributes, accessibility should fallback to exposing it as a group.
3213     if (supportsARIAAttributes())
3214         return GroupRole;
3215     
3216     return UnknownRole;
3217 }
3218
3219 AccessibilityOrientation AccessibilityRenderObject::orientation() const
3220 {
3221     const AtomicString& ariaOrientation = getAttribute(aria_orientationAttr);
3222     if (equalIgnoringCase(ariaOrientation, "horizontal"))
3223         return AccessibilityOrientationHorizontal;
3224     if (equalIgnoringCase(ariaOrientation, "vertical"))
3225         return AccessibilityOrientationVertical;
3226     
3227     return AccessibilityObject::orientation();
3228 }
3229     
3230 bool AccessibilityRenderObject::inheritsPresentationalRole() const
3231 {
3232     // ARIA spec says that when a parent object is presentational, and it has required child elements,
3233     // those child elements are also presentational. For example, <li> becomes presentational from <ul>.
3234     // http://www.w3.org/WAI/PF/aria/complete#presentation
3235     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, listItemParents, ());
3236
3237     HashSet<QualifiedName>* possibleParentTagNames = 0;
3238     switch (roleValue()) {
3239     case ListItemRole:
3240     case ListMarkerRole:
3241         if (listItemParents.isEmpty()) {
3242             listItemParents.add(ulTag);
3243             listItemParents.add(olTag);
3244             listItemParents.add(dlTag);
3245         }
3246         possibleParentTagNames = &listItemParents;
3247         break;
3248     default:
3249         break;
3250     }
3251     
3252     // Not all elements need to check for this, only ones that are required children.
3253     if (!possibleParentTagNames)
3254         return false;
3255     
3256     for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) { 
3257         if (!parent->isAccessibilityRenderObject())
3258             continue;
3259         
3260         Node* elementNode = static_cast<AccessibilityRenderObject*>(parent)->node();
3261         if (!elementNode || !elementNode->isElementNode())
3262             continue;
3263         
3264         // If native tag of the parent element matches an acceptable name, then return
3265         // based on its presentational status.
3266         if (possibleParentTagNames->contains(static_cast<Element*>(elementNode)->tagQName()))
3267             return parent->roleValue() == PresentationalRole;
3268     }
3269     
3270     return false;
3271 }
3272     
3273 bool AccessibilityRenderObject::isPresentationalChildOfAriaRole() const
3274 {
3275     // Walk the parent chain looking for a parent that has presentational children
3276     AccessibilityObject* parent;
3277     for (parent = parentObject(); parent && !parent->ariaRoleHasPresentationalChildren(); parent = parent->parentObject())
3278     { }
3279     
3280     return parent;
3281 }
3282     
3283 bool AccessibilityRenderObject::ariaRoleHasPresentationalChildren() const
3284 {
3285     switch (m_ariaRole) {
3286     case ButtonRole:
3287     case SliderRole:
3288     case ImageRole:
3289     case ProgressIndicatorRole:
3290     // case SeparatorRole:
3291         return true;
3292     default:
3293         return false;
3294     }
3295 }
3296
3297 bool AccessibilityRenderObject::canSetFocusAttribute() const
3298 {
3299     ASSERT(m_renderer);
3300     Node* node = m_renderer->node();
3301
3302     // NOTE: It would be more accurate to ask the document whether setFocusedNode() would
3303     // do anything.  For example, setFocusedNode() will do nothing if the current focused
3304     // node will not relinquish the focus.
3305     if (!node || !node->isElementNode())
3306         return false;
3307
3308     if (!static_cast<Element*>(node)->isEnabledFormControl())
3309         return false;
3310
3311     switch (roleValue()) {
3312     case WebCoreLinkRole:
3313     case ImageMapLinkRole:
3314     case TextFieldRole:
3315     case TextAreaRole:
3316     case ButtonRole:
3317     case PopUpButtonRole:
3318     case CheckBoxRole:
3319     case RadioButtonRole:
3320     case SliderRole:
3321         return true;
3322     default:
3323         return node->supportsFocus();
3324     }
3325 }
3326     
3327 bool AccessibilityRenderObject::canSetExpandedAttribute() const
3328 {
3329     // An object can be expanded if it aria-expanded is true or false.
3330     const AtomicString& ariaExpanded = getAttribute(aria_expandedAttr);
3331     return equalIgnoringCase(ariaExpanded, "true") || equalIgnoringCase(ariaExpanded, "false");
3332 }
3333
3334 bool AccessibilityRenderObject::canSetValueAttribute() const
3335 {
3336     if (equalIgnoringCase(getAttribute(aria_readonlyAttr), "true"))
3337         return false;
3338
3339     if (isProgressIndicator() || isSlider())
3340         return true;
3341
3342     if (isTextControl() && !isNativeTextControl())
3343         return true;
3344
3345     // Any node could be contenteditable, so isReadOnly should be relied upon
3346     // for this information for all elements.
3347     return !isReadOnly();
3348 }
3349
3350 bool AccessibilityRenderObject::canSetTextRangeAttributes() const
3351 {
3352     return isTextControl();
3353 }
3354
3355 void AccessibilityRenderObject::contentChanged()
3356 {
3357     // If this element supports ARIA live regions, then notify the AT of changes.
3358     AXObjectCache* cache = axObjectCache();
3359     for (RenderObject* renderParent = m_renderer; renderParent; renderParent = renderParent->parent()) {
3360         AccessibilityObject* parent = cache->get(renderParent);
3361         if (!parent)
3362             continue;
3363         
3364         // If we find a parent that has ARIA live region on, send the notification and stop processing.
3365         // The spec does not talk about nested live regions.
3366         if (parent->supportsARIALiveRegion()) {
3367             axObjectCache()->postNotification(renderParent, AXObjectCache::AXLiveRegionChanged, true);
3368             break;
3369         }
3370     }
3371 }
3372     
3373 void AccessibilityRenderObject::childrenChanged()
3374 {
3375     // This method is meant as a quick way of marking a portion of the accessibility tree dirty.
3376     if (!m_renderer)
3377         return;
3378     
3379     bool sentChildrenChanged = false;
3380     
3381     // Go up the accessibility parent chain, but only if the element already exists. This method is
3382     // called during render layouts, minimal work should be done. 
3383     // If AX elements are created now, they could interrogate the render tree while it's in a funky state.
3384     // At the same time, process ARIA live region changes.
3385     for (AccessibilityObject* parent = this; parent; parent = parent->parentObjectIfExists()) {
3386         if (!parent->isAccessibilityRenderObject())
3387             continue;
3388         
3389         AccessibilityRenderObject* axParent = toAccessibilityRenderObject(parent);
3390         
3391         // Send the children changed notification on the first accessibility render object ancestor.
3392         if (!sentChildrenChanged) {
3393             axObjectCache()->postNotification(axParent->renderer(), AXObjectCache::AXChildrenChanged, true);
3394             sentChildrenChanged = true;
3395         }
3396         
3397         // Only do work if the children haven't been marked dirty. This has the effect of blocking
3398         // future live region change notifications until the AX tree has been accessed again. This
3399         // is a good performance win for all parties.
3400         if (!axParent->needsToUpdateChildren()) {
3401             axParent->setNeedsToUpdateChildren();
3402             
3403             // If this element supports ARIA live regions, then notify the AT of changes.
3404             if (axParent->supportsARIALiveRegion())
3405                 axObjectCache()->postNotification(axParent->renderer(), AXObjectCache::AXLiveRegionChanged, true);
3406         }
3407     }
3408 }
3409     
3410 bool AccessibilityRenderObject::canHaveChildren() const
3411 {
3412     if (!m_renderer)
3413         return false;
3414     
3415     // Elements that should not have children
3416     switch (roleValue()) {
3417     case ImageRole:
3418     case ButtonRole:
3419     case PopUpButtonRole:
3420     case CheckBoxRole:
3421     case RadioButtonRole:
3422     case TabRole:
3423     case StaticTextRole:
3424     case ListBoxOptionRole:
3425     case ScrollBarRole:
3426         return false;
3427     default:
3428         return true;
3429     }
3430 }
3431
3432 void AccessibilityRenderObject::clearChildren()
3433 {
3434     AccessibilityObject::clearChildren();
3435     m_childrenDirty = false;
3436 }
3437     
3438 void AccessibilityRenderObject::updateChildrenIfNecessary()
3439 {
3440     if (needsToUpdateChildren())
3441         clearChildren();        
3442     
3443     AccessibilityObject::updateChildrenIfNecessary();
3444 }
3445     
3446 const AccessibilityObject::AccessibilityChildrenVector& AccessibilityRenderObject::children()
3447 {
3448     updateChildrenIfNecessary();
3449     
3450     return m_children;
3451 }
3452
3453 void AccessibilityRenderObject::addChildren()
3454 {
3455     // If the need to add more children in addition to existing children arises, 
3456     // childrenChanged should have been called, leaving the object with no children.
3457     ASSERT(!m_haveChildren); 
3458     
3459     // nothing to add if there is no RenderObject
3460     if (!m_renderer)
3461         return;
3462     
3463     m_haveChildren = true;
3464     
3465     if (!canHaveChildren())
3466         return;
3467     
3468     // add all unignored acc children
3469     for (RefPtr<AccessibilityObject> obj = firstChild(); obj; obj = obj->nextSibling()) {
3470         if (obj->accessibilityIsIgnored()) {
3471
3472             // If the parent is asking for this child's children, then either it's the first time (and clearing is a no-op), 
3473             // or its visibility has changed. In the latter case, this child may have a stale child cached. 
3474             // This can prevent aria-hidden changes from working correctly. Hence, whenever a parent is getting children, ensure data is not stale.
3475             obj->clearChildren();
3476             
3477             AccessibilityChildrenVector children = obj->children();
3478             unsigned length = children.size();
3479             for (unsigned i = 0; i < length; ++i)
3480                 m_children.append(children[i]);
3481         } else {
3482             ASSERT(obj->parentObject() == this);
3483             m_children.append(obj);
3484         }
3485     }
3486     
3487     // FrameView's need to be inserted into the AX hierarchy when encountered.
3488     if (isAttachment()) {
3489         Widget* widget = widgetForAttachmentView();
3490         if (widget && widget->isFrameView())
3491             m_children.append(axObjectCache()->getOrCreate(widget));
3492     }
3493     
3494     // for a RenderImage, add the <area> elements as individual accessibility objects
3495     RenderBoxModelObject* cssBox = renderBoxModelObject();
3496     if (cssBox && cssBox->isRenderImage()) {
3497         HTMLMapElement* map = toRenderImage(cssBox)->imageMap();
3498         if (map) {
3499             for (Node* current = map->firstChild(); current; current = current->traverseNextNode(map)) {
3500
3501                 // add an <area> element for this child if it has a link
3502                 if (current->hasTagName(areaTag) && current->isLink()) {
3503                     AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(axObjectCache()->getOrCreate(ImageMapLinkRole));
3504                     areaObject->setHTMLAreaElement(static_cast<HTMLAreaElement*>(current));
3505                     areaObject->setHTMLMapElement(map);
3506                     areaObject->setParent(this);
3507
3508                     m_children.append(areaObject);
3509                 }
3510             }
3511         }
3512     }
3513 }
3514         
3515 const AtomicString& AccessibilityRenderObject::ariaLiveRegionStatus() const
3516 {
3517     DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusAssertive, ("assertive"));
3518     DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusPolite, ("polite"));
3519     DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusOff, ("off"));
3520     
3521     const AtomicString& liveRegionStatus = getAttribute(aria_liveAttr);
3522     // These roles have implicit live region status.
3523     if (liveRegionStatus.isEmpty()) {
3524         switch (roleValue()) {
3525         case ApplicationAlertDialogRole:
3526         case ApplicationAlertRole:
3527             return liveRegionStatusAssertive;
3528         case ApplicationLogRole:
3529         case ApplicationStatusRole:
3530             return liveRegionStatusPolite;
3531         case ApplicationTimerRole:
3532         case ApplicationMarqueeRole:
3533             return liveRegionStatusOff;
3534         default:
3535             break;
3536         }
3537     }
3538
3539     return liveRegionStatus;
3540 }
3541
3542 const AtomicString& AccessibilityRenderObject::ariaLiveRegionRelevant() const
3543 {
3544     DEFINE_STATIC_LOCAL(const AtomicString, defaultLiveRegionRelevant, ("additions text"));
3545     const AtomicString& relevant = getAttribute(aria_relevantAttr);
3546
3547     // Default aria-relevant = "additions text".
3548     if (relevant.isEmpty())
3549         return defaultLiveRegionRelevant;
3550     
3551     return relevant;
3552 }
3553
3554 bool AccessibilityRenderObject::ariaLiveRegionAtomic() const
3555 {
3556     return elementAttributeValue(aria_atomicAttr);    
3557 }
3558
3559 bool AccessibilityRenderObject::ariaLiveRegionBusy() const
3560 {
3561     return elementAttributeValue(aria_busyAttr);    
3562 }
3563     
3564 void AccessibilityRenderObject::ariaSelectedRows(AccessibilityChildrenVector& result)
3565 {
3566     // Get all the rows. 
3567     AccessibilityChildrenVector allRows;
3568     ariaTreeRows(allRows);
3569
3570     // Determine which rows are selected.
3571     bool isMulti = isMultiSelectable();
3572
3573     // Prefer active descendant over aria-selected.
3574     AccessibilityObject* activeDesc = activeDescendant();
3575     if (activeDesc && (activeDesc->isTreeItem() || activeDesc->isTableRow())) {
3576         result.append(activeDesc);    
3577         if (!isMulti)
3578             return;
3579     }
3580
3581     unsigned count = allRows.size();
3582     for (unsigned k = 0; k < count; ++k) {
3583         if (allRows[k]->isSelected()) {
3584             result.append(allRows[k]);
3585             if (!isMulti)
3586                 break;
3587         }
3588     }
3589 }
3590     
3591 void AccessibilityRenderObject::ariaListboxSelectedChildren(AccessibilityChildrenVector& result)
3592 {
3593     bool isMulti = isMultiSelectable();
3594
3595     AccessibilityChildrenVector childObjects = children();
3596     unsigned childrenSize = childObjects.size();
3597     for (unsigned k = 0; k < childrenSize; ++k) {
3598         // Every child should have aria-role option, and if so, check for selected attribute/state.
3599         AccessibilityObject* child = childObjects[k].get();
3600         if (child->isSelected() && child->ariaRoleAttribute() == ListBoxOptionRole) {
3601             result.append(child);
3602             if (!isMulti)
3603                 return;
3604         }
3605     }
3606 }
3607
3608 void AccessibilityRenderObject::selectedChildren(AccessibilityChildrenVector& result)
3609 {
3610     ASSERT(result.isEmpty());
3611
3612     // only listboxes should be asked for their selected children. 
3613     AccessibilityRole role = roleValue();
3614     if (role == ListBoxRole) // native list boxes would be AccessibilityListBoxes, so only check for aria list boxes
3615         ariaListboxSelectedChildren(result);
3616     else if (role == TreeRole || role == TreeGridRole || role == TableRole)
3617         ariaSelectedRows(result);
3618 }
3619
3620 void AccessibilityRenderObject::ariaListboxVisibleChildren(AccessibilityChildrenVector& result)      
3621 {
3622     if (!hasChildren())
3623         addChildren();
3624     
3625     unsigned length = m_children.size();
3626     for (unsigned i = 0; i < length; i++) {
3627         if (!m_children[i]->isOffScreen())
3628             result.append(m_children[i]);
3629     }
3630 }
3631
3632 void AccessibilityRenderObject::visibleChildren(AccessibilityChildrenVector& result)
3633 {
3634     ASSERT(result.isEmpty());
3635         
3636     // only listboxes are asked for their visible children. 
3637     if (ariaRoleAttribute() != ListBoxRole) { // native list boxes would be AccessibilityListBoxes, so only check for aria list boxes
3638         ASSERT_NOT_REACHED();
3639         return;
3640     }
3641     return ariaListboxVisibleChildren(result);
3642 }
3643  
3644 void AccessibilityRenderObject::tabChildren(AccessibilityChildrenVector& result)
3645 {
3646     ASSERT(roleValue() == TabListRole);
3647     
3648     unsigned length = m_children.size();
3649     for (unsigned i = 0; i < length; ++i) {
3650         if (m_children[i]->isTabItem())
3651             result.append(m_children[i]);
3652     }
3653 }
3654     
3655 const String& AccessibilityRenderObject::actionVerb() const
3656 {
3657     // FIXME: Need to add verbs for select elements.
3658     DEFINE_STATIC_LOCAL(const String, buttonAction, (AXButtonActionVerb()));
3659     DEFINE_STATIC_LOCAL(const String, textFieldAction, (AXTextFieldActionVerb()));
3660     DEFINE_STATIC_LOCAL(const String, radioButtonAction, (AXRadioButtonActionVerb()));
3661     DEFINE_STATIC_LOCAL(const String, checkedCheckBoxAction, (AXCheckedCheckBoxActionVerb()));
3662     DEFINE_STATIC_LOCAL(const String, uncheckedCheckBoxAction, (AXUncheckedCheckBoxActionVerb()));
3663     DEFINE_STATIC_LOCAL(const String, linkAction, (AXLinkActionVerb()));
3664     DEFINE_STATIC_LOCAL(const String, noAction, ());
3665     
3666     switch (roleValue()) {
3667     case ButtonRole:
3668         return buttonAction;
3669     case TextFieldRole:
3670     case TextAreaRole:
3671         return textFieldAction;
3672     case RadioButtonRole:
3673         return radioButtonAction;
3674     case CheckBoxRole:
3675         return isChecked() ? checkedCheckBoxAction : uncheckedCheckBoxAction;
3676     case LinkRole:
3677     case WebCoreLinkRole:
3678         return linkAction;
3679     default:
3680         return noAction;
3681     }
3682 }
3683     
3684 void AccessibilityRenderObject::setAccessibleName(const AtomicString& name)
3685 {
3686     // Setting the accessible name can store the value in the DOM
3687     if (!m_renderer)
3688         return;
3689
3690     Node* domNode = 0;
3691     // For web areas, set the aria-label on the HTML element.
3692     if (isWebArea())
3693         domNode = m_renderer->document()->documentElement();
3694     else
3695         domNode = m_renderer->node();
3696
3697     if (domNode && domNode->isElementNode())
3698         static_cast<Element*>(domNode)->setAttribute(aria_labelAttr, name);
3699 }
3700     
3701 static bool isLinkable(const AccessibilityRenderObject& object)
3702 {
3703     if (!object.renderer())
3704         return false;
3705
3706     // See https://wiki.mozilla.org/Accessibility/AT-Windows-API for the elements
3707     // Mozilla considers linkable.
3708     return object.isLink() || object.isImage() || object.renderer()->isText();
3709 }
3710
3711 String AccessibilityRenderObject::stringValueForMSAA() const
3712 {
3713     if (isLinkable(*this)) {
3714         Element* anchor = anchorElement();
3715         if (anchor && anchor->hasTagName(aTag))
3716             return static_cast<HTMLAnchorElement*>(anchor)->href();
3717     }
3718
3719     return stringValue();
3720 }
3721
3722 bool AccessibilityRenderObject::isLinked() const
3723 {
3724     if (!isLinkable(*this))
3725         return false;
3726
3727     Element* anchor = anchorElement();
3728     if (!anchor || !anchor->hasTagName(aTag))
3729         return false;
3730
3731     return !static_cast<HTMLAnchorElement*>(anchor)->href().isEmpty();
3732 }
3733
3734 bool AccessibilityRenderObject::hasBoldFont() const
3735 {
3736     if (!m_renderer)
3737         return false;
3738     
3739     return m_renderer->style()->fontDescription().weight() >= FontWeightBold;
3740 }
3741
3742 bool AccessibilityRenderObject::hasItalicFont() const
3743 {
3744     if (!m_renderer)
3745         return false;
3746     
3747     return m_renderer->style()->fontDescription().italic() == FontItalicOn;
3748 }
3749
3750 bool AccessibilityRenderObject::hasPlainText() const
3751 {
3752     if (!m_renderer)
3753         return false;
3754     
3755     RenderStyle* style = m_renderer->style();
3756     
3757     return style->fontDescription().weight() == FontWeightNormal
3758         && style->fontDescription().italic() == FontItalicOff
3759         && style->textDecorationsInEffect() == TDNONE;
3760 }
3761
3762 bool AccessibilityRenderObject::hasSameFont(RenderObject* renderer) const
3763 {
3764     if (!m_renderer || !renderer)
3765         return false;
3766     
3767     return m_renderer->style()->fontDescription().family() == renderer->style()->fontDescription().family();
3768 }
3769
3770 bool AccessibilityRenderObject::hasSameFontColor(RenderObject* renderer) const
3771 {
3772     if (!m_renderer || !renderer)
3773         return false;
3774     
3775     return m_renderer->style()->visitedDependentColor(CSSPropertyColor) == renderer->style()->visitedDependentColor(CSSPropertyColor);
3776 }
3777
3778 bool AccessibilityRenderObject::hasSameStyle(RenderObject* renderer) const
3779 {
3780     if (!m_renderer || !renderer)
3781         return false;
3782     
3783     return m_renderer->style() == renderer->style();
3784 }
3785
3786 bool AccessibilityRenderObject::hasUnderline() const
3787 {
3788     if (!m_renderer)
3789         return false;
3790     
3791     return m_renderer->style()->textDecorationsInEffect() & UNDERLINE;
3792 }
3793
3794 String AccessibilityRenderObject::nameForMSAA() const
3795 {
3796     if (m_renderer && m_renderer->isText())
3797         return textUnderElement();
3798
3799     return title();
3800 }
3801
3802 static bool shouldReturnTagNameAsRoleForMSAA(const Element& element)
3803 {
3804     // See "document structure",
3805     // https://wiki.mozilla.org/Accessibility/AT-Windows-API
3806     // FIXME: Add the other tag names that should be returned as the role.
3807     return element.hasTagName(h1Tag) || element.hasTagName(h2Tag) 
3808         || element.hasTagName(h3Tag) || element.hasTagName(h4Tag)
3809         || element.hasTagName(h5Tag) || element.hasTagName(h6Tag);
3810 }
3811
3812 String AccessibilityRenderObject::stringRoleForMSAA() const
3813 {
3814     if (!m_renderer)
3815         return String();
3816
3817     Node* node = m_renderer->node();
3818     if (!node || !node->isElementNode())
3819         return String();
3820
3821     Element* element = static_cast<Element*>(node);
3822     if (!shouldReturnTagNameAsRoleForMSAA(*element))
3823         return String();
3824
3825     return element->tagName();
3826 }
3827
3828 String AccessibilityRenderObject::positionalDescriptionForMSAA() const
3829 {
3830     // See "positional descriptions",
3831     // https://wiki.mozilla.org/Accessibility/AT-Windows-API
3832     if (isHeading())
3833         return "L" + String::number(headingLevel());
3834
3835     // FIXME: Add positional descriptions for other elements.
3836     return String();
3837 }
3838
3839 String AccessibilityRenderObject::descriptionForMSAA() const
3840 {
3841     String description = positionalDescriptionForMSAA();
3842     if (!description.isEmpty())
3843         return description;
3844
3845     description = accessibilityDescription();
3846     if (!description.isEmpty()) {
3847         // From the Mozilla MSAA implementation:
3848         // "Signal to screen readers that this description is speakable and is not
3849         // a formatted positional information description. Don't localize the
3850         // 'Description: ' part of this string, it will be parsed out by assistive
3851         // technologies."
3852         return "Description: " + description;
3853     }
3854
3855     return String();
3856 }
3857
3858 static AccessibilityRole msaaRoleForRenderer(const RenderObject* renderer)
3859 {
3860     if (!renderer)
3861         return UnknownRole;
3862
3863     if (renderer->isText())
3864         return EditableTextRole;
3865
3866     if (renderer->isBoxModelObject() && toRenderBoxModelObject(renderer)->isListItem())
3867         return ListItemRole;
3868
3869     return UnknownRole;
3870 }
3871
3872 AccessibilityRole AccessibilityRenderObject::roleValueForMSAA() const
3873 {
3874     if (m_roleForMSAA != UnknownRole)
3875         return m_roleForMSAA;
3876
3877     m_roleForMSAA = msaaRoleForRenderer(m_renderer);
3878
3879     if (m_roleForMSAA == UnknownRole)
3880         m_roleForMSAA = roleValue();
3881
3882     return m_roleForMSAA;
3883 }
3884
3885 } // namespace WebCore