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