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