7fa5d3bb6b044d3f336222451f1f5c8fe0fa0964
[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     return String();
1406 }
1407
1408 String AccessibilityRenderObject::ariaDescribedByAttribute() const
1409 {
1410     Vector<Element*> elements;
1411     elementsFromAttribute(elements, aria_describedbyAttr);
1412     
1413     return accessibilityDescriptionForElements(elements);
1414 }
1415     
1416 String AccessibilityRenderObject::ariaAccessibilityDescription() const
1417 {
1418     String ariaLabeledBy = ariaLabeledByAttribute();
1419     if (!ariaLabeledBy.isEmpty())
1420         return ariaLabeledBy;
1421
1422     const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
1423     if (!ariaLabel.isEmpty())
1424         return ariaLabel;
1425     
1426     return String();
1427 }
1428
1429 String AccessibilityRenderObject::webAreaAccessibilityDescription() const
1430 {
1431     // The WebArea description should follow this order:
1432     //     aria-label on the <html>
1433     //     title on the <html>
1434     //     <title> inside the <head> (of it was set through JS)
1435     //     name on the <html>
1436     // For iframes:
1437     //     aria-label on the <iframe>
1438     //     title on the <iframe>
1439     //     name on the <iframe>
1440     
1441     if (!m_renderer)
1442         return String();
1443     
1444     Document* document = m_renderer->document();
1445     
1446     // Check if the HTML element has an aria-label for the webpage.
1447     if (Element* documentElement = document->documentElement()) {
1448         const AtomicString& ariaLabel = documentElement->getAttribute(aria_labelAttr);
1449         if (!ariaLabel.isEmpty())
1450             return ariaLabel;
1451     }
1452     
1453     Node* owner = document->ownerElement();
1454     if (owner) {
1455         if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) {
1456             const AtomicString& title = static_cast<HTMLFrameElementBase*>(owner)->getAttribute(titleAttr);
1457             if (!title.isEmpty())
1458                 return title;
1459             return static_cast<HTMLFrameElementBase*>(owner)->getNameAttribute();
1460         }
1461         if (owner->isHTMLElement())
1462             return toHTMLElement(owner)->getNameAttribute();
1463     }
1464
1465     String documentTitle = document->title();
1466     if (!documentTitle.isEmpty())
1467         return documentTitle;
1468     
1469     owner = document->body();
1470     if (owner && owner->isHTMLElement())
1471         return toHTMLElement(owner)->getNameAttribute();
1472     
1473     return String();
1474 }
1475     
1476 String AccessibilityRenderObject::accessibilityDescription() const
1477 {
1478     if (!m_renderer)
1479         return String();
1480
1481     // Static text should not have a description, it should only have a stringValue.
1482     if (roleValue() == StaticTextRole)
1483         return String();
1484     
1485     String ariaDescription = ariaAccessibilityDescription();
1486     if (!ariaDescription.isEmpty())
1487         return ariaDescription;
1488     
1489     Node* node = m_renderer->node();
1490     if (isImage() || isInputImage() || isNativeImage()) {
1491         if (node && node->isHTMLElement()) {
1492             const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr);
1493             if (alt.isEmpty())
1494                 return String();
1495             return alt;
1496         }
1497     }
1498     
1499 #if ENABLE(MATHML)
1500     if (node && node->isElementNode() && static_cast<Element*>(node)->isMathMLElement())
1501         return getAttribute(MathMLNames::alttextAttr);
1502 #endif
1503     
1504     if (isWebArea())
1505         return webAreaAccessibilityDescription();
1506     
1507     // An element's descriptive text is comprised of title() (what's visible on the screen) and accessibilityDescription() (other descriptive text).
1508     // Both are used to generate what a screen reader speaks.
1509     // If this point is reached (i.e. there's no accessibilityDescription) and there's no title(), we should fallback to using the title attribute.
1510     // 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).
1511     if (title().isEmpty())
1512         return getAttribute(titleAttr);
1513     
1514     return String();
1515 }
1516
1517 LayoutRect AccessibilityRenderObject::boundingBoxRect() const
1518 {
1519     RenderObject* obj = m_renderer;
1520     
1521     if (!obj)
1522         return LayoutRect();
1523     
1524     if (obj->node()) // If we are a continuation, we want to make sure to use the primary renderer.
1525         obj = obj->node()->renderer();
1526     
1527     // absoluteFocusRingQuads will query the hierarchy below this element, which for large webpages can be very slow.
1528     // For a web area, which will have the most elements of any element, absoluteQuads should be used.
1529     Vector<FloatQuad> quads;
1530     if (obj->isText())
1531         toRenderText(obj)->absoluteQuads(quads, 0, RenderText::ClipToEllipsis);
1532     else if (isWebArea())
1533         obj->absoluteQuads(quads);
1534     else
1535         obj->absoluteFocusRingQuads(quads);
1536     
1537     LayoutRect result = boundingBoxForQuads(obj, quads);
1538
1539     // The size of the web area should be the content size, not the clipped size.
1540     if (isWebArea() && obj->frame()->view())
1541         result.setSize(obj->frame()->view()->contentsSize());
1542     
1543     return result;
1544 }
1545     
1546 LayoutRect AccessibilityRenderObject::checkboxOrRadioRect() const
1547 {
1548     if (!m_renderer)
1549         return LayoutRect();
1550     
1551     HTMLLabelElement* label = labelForElement(static_cast<Element*>(m_renderer->node()));
1552     if (!label || !label->renderer())
1553         return boundingBoxRect();
1554     
1555     LayoutRect labelRect = axObjectCache()->getOrCreate(label)->elementRect();
1556     labelRect.unite(boundingBoxRect());
1557     return labelRect;
1558 }
1559
1560 LayoutRect AccessibilityRenderObject::elementRect() const
1561 {
1562     // a checkbox or radio button should encompass its label
1563     if (isCheckboxOrRadio())
1564         return checkboxOrRadioRect();
1565     
1566     return boundingBoxRect();
1567 }
1568
1569 IntPoint AccessibilityRenderObject::clickPoint()
1570 {
1571     // Headings are usually much wider than their textual content. If the mid point is used, often it can be wrong.
1572     if (isHeading() && children().size() == 1)
1573         return children()[0]->clickPoint();
1574
1575     // use the default position unless this is an editable web area, in which case we use the selection bounds.
1576     if (!isWebArea() || isReadOnly())
1577         return AccessibilityObject::clickPoint();
1578     
1579     VisibleSelection visSelection = selection();
1580     VisiblePositionRange range = VisiblePositionRange(visSelection.visibleStart(), visSelection.visibleEnd());
1581     IntRect bounds = boundsForVisiblePositionRange(range);
1582 #if PLATFORM(MAC)
1583     bounds.setLocation(m_renderer->document()->view()->screenToContents(bounds.location()));
1584 #endif        
1585     return IntPoint(bounds.x() + (bounds.width() / 2), bounds.y() - (bounds.height() / 2));
1586 }
1587     
1588 AccessibilityObject* AccessibilityRenderObject::internalLinkElement() const
1589 {
1590     Element* element = anchorElement();
1591     if (!element)
1592         return 0;
1593     
1594     // Right now, we do not support ARIA links as internal link elements
1595     if (!element->hasTagName(aTag))
1596         return 0;
1597     HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(element);
1598     
1599     KURL linkURL = anchor->href();
1600     String fragmentIdentifier = linkURL.fragmentIdentifier();
1601     if (fragmentIdentifier.isEmpty())
1602         return 0;
1603     
1604     // check if URL is the same as current URL
1605     KURL documentURL = m_renderer->document()->url();
1606     if (!equalIgnoringFragmentIdentifier(documentURL, linkURL))
1607         return 0;
1608     
1609     Node* linkedNode = m_renderer->document()->findAnchor(fragmentIdentifier);
1610     if (!linkedNode)
1611         return 0;
1612     
1613     // The element we find may not be accessible, so find the first accessible object.
1614     return firstAccessibleObjectFromNode(linkedNode);
1615 }
1616
1617 ESpeak AccessibilityRenderObject::speakProperty() const
1618 {
1619     if (!m_renderer)
1620         return AccessibilityObject::speakProperty();
1621     
1622     return m_renderer->style()->speak();
1623 }
1624     
1625 void AccessibilityRenderObject::addRadioButtonGroupMembers(AccessibilityChildrenVector& linkedUIElements) const
1626 {
1627     if (!m_renderer || roleValue() != RadioButtonRole)
1628         return;
1629     
1630     Node* node = m_renderer->node();
1631     if (!node || !node->hasTagName(inputTag))
1632         return;
1633     
1634     HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
1635     // if there's a form, then this is easy
1636     if (input->form()) {
1637         Vector<RefPtr<Node> > formElements;
1638         input->form()->getNamedElements(input->name(), formElements);
1639         
1640         unsigned len = formElements.size();
1641         for (unsigned i = 0; i < len; ++i) {
1642             Node* associateElement = formElements[i].get();
1643             if (AccessibilityObject* object = axObjectCache()->getOrCreate(associateElement))
1644                 linkedUIElements.append(object);        
1645         } 
1646     } else {
1647         RefPtr<NodeList> list = node->document()->getElementsByTagName("input");
1648         unsigned len = list->length();
1649         for (unsigned i = 0; i < len; ++i) {
1650             if (list->item(i)->hasTagName(inputTag)) {
1651                 HTMLInputElement* associateElement = static_cast<HTMLInputElement*>(list->item(i));
1652                 if (associateElement->isRadioButton() && associateElement->name() == input->name()) {
1653                     if (AccessibilityObject* object = axObjectCache()->getOrCreate(associateElement))
1654                         linkedUIElements.append(object);
1655                 }
1656             }
1657         }
1658     }
1659 }
1660     
1661 // linked ui elements could be all the related radio buttons in a group
1662 // or an internal anchor connection
1663 void AccessibilityRenderObject::linkedUIElements(AccessibilityChildrenVector& linkedUIElements) const
1664 {
1665     ariaFlowToElements(linkedUIElements);
1666
1667     if (isAnchor()) {
1668         AccessibilityObject* linkedAXElement = internalLinkElement();
1669         if (linkedAXElement)
1670             linkedUIElements.append(linkedAXElement);
1671     }
1672
1673     if (roleValue() == RadioButtonRole)
1674         addRadioButtonGroupMembers(linkedUIElements);
1675 }
1676
1677 bool AccessibilityRenderObject::hasTextAlternative() const
1678 {
1679     // ARIA: section 2A, bullet #3 says if aria-labeledby or aria-label appears, it should
1680     // override the "label" element association.
1681     if (!ariaLabeledByAttribute().isEmpty() || !getAttribute(aria_labelAttr).isEmpty())
1682         return true;
1683         
1684     return false;   
1685 }
1686     
1687 bool AccessibilityRenderObject::ariaHasPopup() const
1688 {
1689     return elementAttributeValue(aria_haspopupAttr);
1690 }
1691
1692 bool AccessibilityRenderObject::supportsARIAFlowTo() const
1693 {
1694     return !getAttribute(aria_flowtoAttr).isEmpty();
1695 }
1696     
1697 void AccessibilityRenderObject::ariaFlowToElements(AccessibilityChildrenVector& flowTo) const
1698 {
1699     Vector<Element*> elements;
1700     elementsFromAttribute(elements, aria_flowtoAttr);
1701     
1702     AXObjectCache* cache = axObjectCache();
1703     unsigned count = elements.size();
1704     for (unsigned k = 0; k < count; ++k) {
1705         Element* element = elements[k];
1706         AccessibilityObject* flowToElement = cache->getOrCreate(element);
1707         if (flowToElement)
1708             flowTo.append(flowToElement);
1709     }
1710         
1711 }
1712     
1713 bool AccessibilityRenderObject::supportsARIADropping() const 
1714 {
1715     const AtomicString& dropEffect = getAttribute(aria_dropeffectAttr);
1716     return !dropEffect.isEmpty();
1717 }
1718
1719 bool AccessibilityRenderObject::supportsARIADragging() const
1720 {
1721     const AtomicString& grabbed = getAttribute(aria_grabbedAttr);
1722     return equalIgnoringCase(grabbed, "true") || equalIgnoringCase(grabbed, "false");   
1723 }
1724
1725 bool AccessibilityRenderObject::isARIAGrabbed()
1726 {
1727     return elementAttributeValue(aria_grabbedAttr);
1728 }
1729
1730 void AccessibilityRenderObject::determineARIADropEffects(Vector<String>& effects)
1731 {
1732     const AtomicString& dropEffects = getAttribute(aria_dropeffectAttr);
1733     if (dropEffects.isEmpty()) {
1734         effects.clear();
1735         return;
1736     }
1737     
1738     String dropEffectsString = dropEffects.string();
1739     dropEffectsString.replace('\n', ' ');
1740     dropEffectsString.split(' ', effects);
1741 }
1742     
1743 bool AccessibilityRenderObject::exposesTitleUIElement() const
1744 {
1745     if (!isControl())
1746         return false;
1747
1748     // If this control is ignored (because it's invisible), 
1749     // then the label needs to be exposed so it can be visible to accessibility.
1750     if (accessibilityIsIgnored())
1751         return true;
1752     
1753     // Checkboxes and radio buttons use the text of their title ui element as their own AXTitle.
1754     // This code controls whether the title ui element should appear in the AX tree (usually, no).
1755     // It should appear if the control already has a label (which will be used as the AXTitle instead).
1756     if (isCheckboxOrRadio())
1757         return hasTextAlternative();
1758
1759     // When controls have their own descriptions, the title element should be ignored.
1760     if (hasTextAlternative())
1761         return false;
1762     
1763     return true;
1764 }
1765     
1766 AccessibilityObject* AccessibilityRenderObject::titleUIElement() const
1767 {
1768     if (!m_renderer)
1769         return 0;
1770     
1771     // if isFieldset is true, the renderer is guaranteed to be a RenderFieldset
1772     if (isFieldset())
1773         return axObjectCache()->getOrCreate(toRenderFieldset(m_renderer)->findLegend());
1774     
1775     Node* element = m_renderer->node();
1776     if (!element)
1777         return 0;
1778     HTMLLabelElement* label = labelForElement(static_cast<Element*>(element));
1779     if (label && label->renderer())
1780         return axObjectCache()->getOrCreate(label);
1781
1782     return 0;   
1783 }
1784     
1785 bool AccessibilityRenderObject::ariaIsHidden() const
1786 {
1787     if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "true"))
1788         return true;
1789     
1790     // aria-hidden hides this object and any children
1791     AccessibilityObject* object = parentObject();
1792     while (object) {
1793         if (equalIgnoringCase(object->getAttribute(aria_hiddenAttr), "true"))
1794             return true;
1795         object = object->parentObject();
1796     }
1797
1798     return false;
1799 }
1800
1801 bool AccessibilityRenderObject::isDescendantOfBarrenParent() const
1802 {
1803     for (AccessibilityObject* object = parentObject(); object; object = object->parentObject()) {
1804         if (!object->canHaveChildren())
1805             return true;
1806     }
1807     
1808     return false;
1809 }
1810     
1811 bool AccessibilityRenderObject::isAllowedChildOfTree() const
1812 {
1813     // Determine if this is in a tree. If so, we apply special behavior to make it work like an AXOutline.
1814     AccessibilityObject* axObj = parentObject();
1815     bool isInTree = false;
1816     while (axObj) {
1817         if (axObj->isTree()) {
1818             isInTree = true;
1819             break;
1820         }
1821         axObj = axObj->parentObject();
1822     }
1823     
1824     // If the object is in a tree, only tree items should be exposed (and the children of tree items).
1825     if (isInTree) {
1826         AccessibilityRole role = roleValue();
1827         if (role != TreeItemRole && role != StaticTextRole)
1828             return false;
1829     }
1830     return true;
1831 }
1832     
1833 AccessibilityObjectInclusion AccessibilityRenderObject::accessibilityIsIgnoredBase() const
1834 {
1835     // The following cases can apply to any element that's a subclass of AccessibilityRenderObject.
1836     
1837     // Ignore invisible elements.
1838     if (!m_renderer || m_renderer->style()->visibility() != VISIBLE)
1839         return IgnoreObject;
1840
1841     // Anything marked as aria-hidden or a child of something aria-hidden must be hidden.
1842     if (ariaIsHidden())
1843         return IgnoreObject;
1844     
1845     // Anything that is a presentational role must be hidden.
1846     if (isPresentationalChildOfAriaRole())
1847         return IgnoreObject;
1848
1849     // Allow the platform to make a decision.
1850     AccessibilityObjectInclusion decision = accessibilityPlatformIncludesObject();
1851     if (decision == IncludeObject)
1852         return IncludeObject;
1853     if (decision == IgnoreObject)
1854         return IgnoreObject;
1855         
1856     return DefaultBehavior;
1857 }  
1858  
1859 bool AccessibilityRenderObject::accessibilityIsIgnored() const
1860 {
1861     // Check first if any of the common reasons cause this element to be ignored.
1862     // Then process other use cases that need to be applied to all the various roles
1863     // that AccessibilityRenderObjects take on.
1864     AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase();
1865     if (decision == IncludeObject)
1866         return false;
1867     if (decision == IgnoreObject)
1868         return true;
1869     
1870     // If this element is within a parent that cannot have children, it should not be exposed.
1871     if (isDescendantOfBarrenParent())
1872         return true;    
1873     
1874     if (roleValue() == IgnoredRole)
1875         return true;
1876     
1877     if (roleValue() == PresentationalRole || inheritsPresentationalRole())
1878         return true;
1879     
1880     // An ARIA tree can only have tree items and static text as children.
1881     if (!isAllowedChildOfTree())
1882         return true;
1883
1884     // Allow the platform to decide if the attachment is ignored or not.
1885     if (isAttachment())
1886         return accessibilityIgnoreAttachment();
1887     
1888     // ignore popup menu items because AppKit does
1889     for (RenderObject* parent = m_renderer->parent(); parent; parent = parent->parent()) {
1890         if (parent->isBoxModelObject() && toRenderBoxModelObject(parent)->isMenuList())
1891             return true;
1892     }
1893
1894     // find out if this element is inside of a label element.
1895     // if so, it may be ignored because it's the label for a checkbox or radio button
1896     AccessibilityObject* controlObject = correspondingControlForLabelElement();
1897     if (controlObject && !controlObject->exposesTitleUIElement() && controlObject->isCheckboxOrRadio())
1898         return true;
1899         
1900     // NOTE: BRs always have text boxes now, so the text box check here can be removed
1901     if (m_renderer->isText()) {
1902         // static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level
1903         if (parentObjectUnignored()->ariaRoleAttribute() == MenuItemRole
1904             || parentObjectUnignored()->ariaRoleAttribute() == MenuButtonRole)
1905             return true;
1906         RenderText* renderText = toRenderText(m_renderer);
1907         if (m_renderer->isBR() || !renderText->firstTextBox())
1908             return true;
1909
1910         // static text beneath TextControls is reported along with the text control text so it's ignored.
1911         for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) { 
1912             if (parent->roleValue() == TextFieldRole)
1913                 return true;
1914         }
1915
1916         // text elements that are just empty whitespace should not be returned
1917         return renderText->text()->containsOnlyWhitespace();
1918     }
1919     
1920     if (isHeading())
1921         return false;
1922     
1923     if (isLink())
1924         return false;
1925     
1926     // all controls are accessible
1927     if (isControl())
1928         return false;
1929     
1930     if (ariaRoleAttribute() != UnknownRole)
1931         return false;
1932
1933     // don't ignore labels, because they serve as TitleUIElements
1934     Node* node = m_renderer->node();
1935     if (node && node->hasTagName(labelTag))
1936         return false;
1937     
1938     // Anything that is content editable should not be ignored.
1939     // However, one cannot just call node->rendererIsEditable() since that will ask if its parents
1940     // are also editable. Only the top level content editable region should be exposed.
1941     if (node && node->isElementNode()) {
1942         Element* element = static_cast<Element*>(node);
1943         const AtomicString& contentEditable = element->getAttribute(contenteditableAttr);
1944         if (equalIgnoringCase(contentEditable, "true"))
1945             return false;
1946     }
1947     
1948     // List items play an important role in defining the structure of lists. They should not be ignored.
1949     if (roleValue() == ListItemRole)
1950         return false;
1951     
1952     // if this element has aria attributes on it, it should not be ignored.
1953     if (supportsARIAAttributes())
1954         return false;
1955     
1956     if (m_renderer->isBlockFlow() && m_renderer->childrenInline())
1957         return !toRenderBlock(m_renderer)->firstLineBox() && !mouseButtonListener();
1958     
1959     // ignore images seemingly used as spacers
1960     if (isImage()) {
1961         
1962         // If the image can take focus, it should not be ignored, lest the user not be able to interact with something important.
1963         if (canSetFocusAttribute())
1964             return false;
1965         
1966         if (node && node->isElementNode()) {
1967             Element* elt = static_cast<Element*>(node);
1968             const AtomicString& alt = elt->getAttribute(altAttr);
1969             // don't ignore an image that has an alt tag
1970             if (!alt.string().containsOnlyWhitespace())
1971                 return false;
1972             // informal standard is to ignore images with zero-length alt strings
1973             if (!alt.isNull())
1974                 return true;
1975         }
1976         
1977         if (node && node->hasTagName(canvasTag)) {
1978             RenderHTMLCanvas* canvas = toRenderHTMLCanvas(m_renderer);
1979             if (canvas->height() <= 1 || canvas->width() <= 1)
1980                 return true;
1981             return false;
1982         }
1983         
1984         if (isNativeImage()) {
1985             // check for one-dimensional image
1986             RenderImage* image = toRenderImage(m_renderer);
1987             if (image->height() <= 1 || image->width() <= 1)
1988                 return true;
1989             
1990             // check whether rendered image was stretched from one-dimensional file image
1991             if (image->cachedImage()) {
1992                 LayoutSize imageSize = image->cachedImage()->imageSizeForRenderer(m_renderer, image->view()->zoomFactor());
1993                 return imageSize.height() <= 1 || imageSize.width() <= 1;
1994             }
1995         }
1996         return false;
1997     }
1998     
1999     if (isWebArea() || m_renderer->isListMarker())
2000         return false;
2001     
2002     // Using the help text, title or accessibility description (so we
2003     // check if there's some kind of accessible name for the element)
2004     // to decide an element's visibility is not as definitive as
2005     // previous checks, so this should remain as one of the last.
2006     if (!helpText().isEmpty() || !title().isEmpty() || !accessibilityDescription().isEmpty())
2007         return false;
2008     
2009     // By default, objects should be ignored so that the AX hierarchy is not 
2010     // filled with unnecessary items.
2011     return true;
2012 }
2013
2014 bool AccessibilityRenderObject::isLoaded() const
2015 {
2016     return !m_renderer->document()->parser();
2017 }
2018
2019 double AccessibilityRenderObject::estimatedLoadingProgress() const
2020 {
2021     if (!m_renderer)
2022         return 0;
2023     
2024     if (isLoaded())
2025         return 1.0;
2026     
2027     Page* page = m_renderer->document()->page();
2028     if (!page)
2029         return 0;
2030     
2031     return page->progress()->estimatedProgress();
2032 }
2033     
2034 int AccessibilityRenderObject::layoutCount() const
2035 {
2036     if (!m_renderer->isRenderView())
2037         return 0;
2038     return toRenderView(m_renderer)->frameView()->layoutCount();
2039 }
2040
2041 String AccessibilityRenderObject::text() const
2042 {
2043     // If this is a user defined static text, use the accessible name computation.
2044     if (ariaRoleAttribute() == StaticTextRole)
2045         return ariaAccessibilityDescription();
2046     
2047     if (!isTextControl())
2048         return String();
2049
2050     if (isPasswordField())
2051         return passwordFieldValue();
2052
2053     Node* node = m_renderer->node();
2054     if (!node)
2055         return String();
2056
2057     if (isNativeTextControl())
2058         return toRenderTextControl(m_renderer)->textFormControlElement()->value();
2059
2060     if (!node->isElementNode())
2061         return String();
2062     
2063     return static_cast<Element*>(node)->innerText();
2064 }
2065     
2066 int AccessibilityRenderObject::textLength() const
2067 {
2068     ASSERT(isTextControl());
2069     
2070     if (isPasswordField())
2071 #if PLATFORM(GTK)
2072         return passwordFieldValue().length();
2073 #else
2074         return -1; // need to return something distinct from 0
2075 #endif
2076
2077     return text().length();
2078 }
2079
2080 PlainTextRange AccessibilityRenderObject::ariaSelectedTextRange() const
2081 {
2082     Node* node = m_renderer->node();
2083     if (!node)
2084         return PlainTextRange();
2085     
2086     ExceptionCode ec = 0;
2087     VisibleSelection visibleSelection = selection();
2088     RefPtr<Range> currentSelectionRange = visibleSelection.toNormalizedRange();
2089     if (!currentSelectionRange || !currentSelectionRange->intersectsNode(node, ec))
2090         return PlainTextRange();
2091     
2092     int start = indexForVisiblePosition(visibleSelection.start());
2093     int end = indexForVisiblePosition(visibleSelection.end());
2094     
2095     return PlainTextRange(start, end - start);
2096 }
2097
2098 String AccessibilityRenderObject::selectedText() const
2099 {
2100     ASSERT(isTextControl());
2101     
2102     if (isPasswordField())
2103         return String(); // need to return something distinct from empty string
2104     
2105     if (isNativeTextControl()) {
2106         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
2107         return textControl->selectedText();
2108     }
2109     
2110     if (ariaRoleAttribute() == UnknownRole)
2111         return String();
2112     
2113     return doAXStringForRange(ariaSelectedTextRange());
2114 }
2115
2116 const AtomicString& AccessibilityRenderObject::accessKey() const
2117 {
2118     Node* node = m_renderer->node();
2119     if (!node)
2120         return nullAtom;
2121     if (!node->isElementNode())
2122         return nullAtom;
2123     return static_cast<Element*>(node)->getAttribute(accesskeyAttr);
2124 }
2125
2126 VisibleSelection AccessibilityRenderObject::selection() const
2127 {
2128     return m_renderer->frame()->selection()->selection();
2129 }
2130
2131 PlainTextRange AccessibilityRenderObject::selectedTextRange() const
2132 {
2133     ASSERT(isTextControl());
2134     
2135     if (isPasswordField())
2136         return PlainTextRange();
2137     
2138     AccessibilityRole ariaRole = ariaRoleAttribute();
2139     if (isNativeTextControl() && ariaRole == UnknownRole) {
2140         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
2141         return PlainTextRange(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart());
2142     }
2143     
2144     if (ariaRole == UnknownRole)
2145         return PlainTextRange();
2146     
2147     return ariaSelectedTextRange();
2148 }
2149
2150 void AccessibilityRenderObject::setSelectedTextRange(const PlainTextRange& range)
2151 {
2152     if (isNativeTextControl()) {
2153         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
2154         textControl->setSelectionRange(range.start, range.start + range.length);
2155         return;
2156     }
2157
2158     Document* document = m_renderer->document();
2159     if (!document)
2160         return;
2161     Frame* frame = document->frame();
2162     if (!frame)
2163         return;
2164     Node* node = m_renderer->node();
2165     frame->selection()->setSelection(VisibleSelection(Position(node, range.start, Position::PositionIsOffsetInAnchor),
2166         Position(node, range.start + range.length, Position::PositionIsOffsetInAnchor), DOWNSTREAM));
2167 }
2168
2169 KURL AccessibilityRenderObject::url() const
2170 {
2171     if (isAnchor() && m_renderer->node()->hasTagName(aTag)) {
2172         if (HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(anchorElement()))
2173             return anchor->href();
2174     }
2175     
2176     if (isWebArea())
2177         return m_renderer->document()->url();
2178     
2179     if (isImage() && m_renderer->node() && m_renderer->node()->hasTagName(imgTag))
2180         return static_cast<HTMLImageElement*>(m_renderer->node())->src();
2181     
2182     if (isInputImage())
2183         return static_cast<HTMLInputElement*>(m_renderer->node())->src();
2184     
2185     return KURL();
2186 }
2187
2188 bool AccessibilityRenderObject::isUnvisited() const
2189 {
2190     // FIXME: Is it a privacy violation to expose unvisited information to accessibility APIs?
2191     return m_renderer->style()->isLink() && m_renderer->style()->insideLink() == InsideUnvisitedLink;
2192 }
2193
2194 bool AccessibilityRenderObject::isVisited() const
2195 {
2196     // FIXME: Is it a privacy violation to expose visited information to accessibility APIs?
2197     return m_renderer->style()->isLink() && m_renderer->style()->insideLink() == InsideVisitedLink;
2198 }
2199
2200 void AccessibilityRenderObject::setElementAttributeValue(const QualifiedName& attributeName, bool value)
2201 {
2202     if (!m_renderer)
2203         return;
2204     
2205     Node* node = m_renderer->node();
2206     if (!node || !node->isElementNode())
2207         return;
2208     
2209     Element* element = static_cast<Element*>(node);
2210     element->setAttribute(attributeName, (value) ? "true" : "false");        
2211 }
2212     
2213 bool AccessibilityRenderObject::elementAttributeValue(const QualifiedName& attributeName) const
2214 {
2215     if (!m_renderer)
2216         return false;
2217     
2218     return equalIgnoringCase(getAttribute(attributeName), "true");
2219 }
2220     
2221 bool AccessibilityRenderObject::isRequired() const
2222 {
2223     if (equalIgnoringCase(getAttribute(aria_requiredAttr), "true"))
2224         return true;
2225     
2226     Node* n = node();
2227     if (n && (n->isElementNode() && static_cast<Element*>(n)->isFormControlElement()))
2228         return static_cast<HTMLFormControlElement*>(n)->required();
2229     
2230     return false;
2231 }
2232
2233 bool AccessibilityRenderObject::isSelected() const
2234 {
2235     if (!m_renderer)
2236         return false;
2237     
2238     Node* node = m_renderer->node();
2239     if (!node)
2240         return false;
2241     
2242     const AtomicString& ariaSelected = getAttribute(aria_selectedAttr);
2243     if (equalIgnoringCase(ariaSelected, "true"))
2244         return true;    
2245     
2246     if (isTabItem() && isTabItemSelected())
2247         return true;
2248
2249     return false;
2250 }
2251
2252 bool AccessibilityRenderObject::isTabItemSelected() const
2253 {
2254     if (!isTabItem() || !m_renderer)
2255         return false;
2256     
2257     Node* node = m_renderer->node();
2258     if (!node || !node->isElementNode())
2259         return false;
2260     
2261     // The ARIA spec says a tab item can also be selected if it is aria-labeled by a tabpanel
2262     // that has keyboard focus inside of it, or if a tabpanel in its aria-controls list has KB
2263     // focus inside of it.
2264     AccessibilityObject* focusedElement = focusedUIElement();
2265     if (!focusedElement)
2266         return false;
2267     
2268     Vector<Element*> elements;
2269     elementsFromAttribute(elements, aria_controlsAttr);
2270     
2271     unsigned count = elements.size();
2272     for (unsigned k = 0; k < count; ++k) {
2273         Element* element = elements[k];
2274         AccessibilityObject* tabPanel = axObjectCache()->getOrCreate(element);
2275
2276         // A tab item should only control tab panels.
2277         if (!tabPanel || tabPanel->roleValue() != TabPanelRole)
2278             continue;
2279         
2280         AccessibilityObject* checkFocusElement = focusedElement;
2281         // Check if the focused element is a descendant of the element controlled by the tab item.
2282         while (checkFocusElement) {
2283             if (tabPanel == checkFocusElement)
2284                 return true;
2285             checkFocusElement = checkFocusElement->parentObject();
2286         }
2287     }
2288     
2289     return false;
2290 }
2291     
2292 bool AccessibilityRenderObject::isFocused() const
2293 {
2294     if (!m_renderer)
2295         return false;
2296     
2297     Document* document = m_renderer->document();
2298     if (!document)
2299         return false;
2300     
2301     Node* focusedNode = document->focusedNode();
2302     if (!focusedNode)
2303         return false;
2304     
2305     // A web area is represented by the Document node in the DOM tree, which isn't focusable.
2306     // Check instead if the frame's selection controller is focused
2307     if (focusedNode == m_renderer->node()
2308         || (roleValue() == WebAreaRole && document->frame()->selection()->isFocusedAndActive()))
2309         return true;
2310     
2311     return false;
2312 }
2313
2314 void AccessibilityRenderObject::setFocused(bool on)
2315 {
2316     if (!canSetFocusAttribute())
2317         return;
2318     
2319     if (!on)
2320         m_renderer->document()->setFocusedNode(0);
2321     else {
2322         if (m_renderer->node()->isElementNode())
2323             static_cast<Element*>(m_renderer->node())->focus();
2324         else
2325             m_renderer->document()->setFocusedNode(m_renderer->node());
2326     }
2327 }
2328
2329 void AccessibilityRenderObject::changeValueByStep(bool increase)
2330 {
2331     float step = stepValueForRange();
2332     float value = valueForRange();
2333     
2334     value += increase ? step : -step;
2335
2336     setValue(String::number(value));
2337     
2338     axObjectCache()->postNotification(m_renderer, AXObjectCache::AXValueChanged, true);
2339 }
2340     
2341 void AccessibilityRenderObject::changeValueByPercent(float percentChange)
2342 {
2343     float range = maxValueForRange() - minValueForRange();
2344     float value = valueForRange();
2345     
2346     value += range * (percentChange / 100);
2347     setValue(String::number(value));
2348     
2349     axObjectCache()->postNotification(m_renderer, AXObjectCache::AXValueChanged, true);
2350 }
2351
2352 void AccessibilityRenderObject::setSelectedRows(AccessibilityChildrenVector& selectedRows)
2353 {
2354     // Setting selected only makes sense in trees and tables (and tree-tables).
2355     AccessibilityRole role = roleValue();
2356     if (role != TreeRole && role != TreeGridRole && role != TableRole)
2357         return;
2358     
2359     bool isMulti = isMultiSelectable();
2360     unsigned count = selectedRows.size();
2361     if (count > 1 && !isMulti)
2362         count = 1;
2363     
2364     for (unsigned k = 0; k < count; ++k)
2365         selectedRows[k]->setSelected(true);
2366 }
2367     
2368 void AccessibilityRenderObject::setValue(const String& string)
2369 {
2370     if (!m_renderer || !m_renderer->node() || !m_renderer->node()->isElementNode())
2371         return;
2372     Element* element = static_cast<Element*>(m_renderer->node());
2373
2374     if (!m_renderer->isBoxModelObject())
2375         return;
2376     RenderBoxModelObject* renderer = toRenderBoxModelObject(m_renderer);
2377
2378     // FIXME: Do we want to do anything here for ARIA textboxes?
2379     if (renderer->isTextField()) {
2380         // FIXME: This is not safe!  Other elements could have a TextField renderer.
2381         static_cast<HTMLInputElement*>(element)->setValue(string);
2382     } else if (renderer->isTextArea()) {
2383         // FIXME: This is not safe!  Other elements could have a TextArea renderer.
2384         static_cast<HTMLTextAreaElement*>(element)->setValue(string);
2385     }
2386 }
2387
2388 void AccessibilityRenderObject::ariaOwnsElements(AccessibilityChildrenVector& axObjects) const
2389 {
2390     Vector<Element*> elements;
2391     elementsFromAttribute(elements, aria_ownsAttr);
2392     
2393     unsigned count = elements.size();
2394     for (unsigned k = 0; k < count; ++k) {
2395         RenderObject* render = elements[k]->renderer();
2396         AccessibilityObject* obj = axObjectCache()->getOrCreate(render);
2397         if (obj)
2398             axObjects.append(obj);
2399     }
2400 }
2401
2402 bool AccessibilityRenderObject::supportsARIAOwns() const
2403 {
2404     if (!m_renderer)
2405         return false;
2406     const AtomicString& ariaOwns = getAttribute(aria_ownsAttr);
2407
2408     return !ariaOwns.isEmpty();
2409 }
2410     
2411 bool AccessibilityRenderObject::isEnabled() const
2412 {
2413     ASSERT(m_renderer);
2414     
2415     if (equalIgnoringCase(getAttribute(aria_disabledAttr), "true"))
2416         return false;
2417     
2418     Node* node = m_renderer->node();
2419     if (!node || !node->isElementNode())
2420         return true;
2421
2422     return static_cast<Element*>(node)->isEnabledFormControl();
2423 }
2424
2425 RenderView* AccessibilityRenderObject::topRenderer() const
2426 {
2427     Document* topDoc = topDocument();
2428     if (!topDoc)
2429         return 0;
2430     
2431     return topDoc->renderView();
2432 }
2433
2434 Document* AccessibilityRenderObject::document() const
2435 {
2436     if (!m_renderer)
2437         return 0;
2438     return m_renderer->document();
2439 }
2440
2441 Document* AccessibilityRenderObject::topDocument() const
2442 {
2443     if (!document())
2444         return 0;
2445     return document()->topDocument();
2446 }
2447     
2448 FrameView* AccessibilityRenderObject::topDocumentFrameView() const
2449 {
2450     RenderView* renderView = topRenderer();
2451     if (!renderView || !renderView->view())
2452         return 0;
2453     return renderView->view()->frameView();
2454 }
2455
2456 Widget* AccessibilityRenderObject::widget() const
2457 {
2458     if (!m_renderer->isBoxModelObject() || !toRenderBoxModelObject(m_renderer)->isWidget())
2459         return 0;
2460     return toRenderWidget(m_renderer)->widget();
2461 }
2462
2463 AccessibilityObject* AccessibilityRenderObject::accessibilityParentForImageMap(HTMLMapElement* map) const
2464 {
2465     // find an image that is using this map
2466     if (!map)
2467         return 0;
2468
2469     HTMLImageElement* imageElement = map->imageElement();
2470     if (!imageElement)
2471         return 0;
2472     
2473     return axObjectCache()->getOrCreate(imageElement);
2474 }
2475     
2476 void AccessibilityRenderObject::getDocumentLinks(AccessibilityChildrenVector& result)
2477 {
2478     Document* document = m_renderer->document();
2479     RefPtr<HTMLCollection> links = document->links();
2480     for (unsigned i = 0; Node* curr = links->item(i); i++) {
2481         RenderObject* obj = curr->renderer();
2482         if (obj) {
2483             RefPtr<AccessibilityObject> axobj = document->axObjectCache()->getOrCreate(obj);
2484             ASSERT(axobj);
2485             if (!axobj->accessibilityIsIgnored() && axobj->isLink())
2486                 result.append(axobj);
2487         } else {
2488             Node* parent = curr->parentNode();
2489             if (parent && curr->hasTagName(areaTag) && parent->hasTagName(mapTag)) {
2490                 AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(axObjectCache()->getOrCreate(ImageMapLinkRole));
2491                 areaObject->setHTMLAreaElement(static_cast<HTMLAreaElement*>(curr));
2492                 areaObject->setHTMLMapElement(static_cast<HTMLMapElement*>(parent));
2493                 areaObject->setParent(accessibilityParentForImageMap(static_cast<HTMLMapElement*>(parent)));
2494
2495                 result.append(areaObject);
2496             }
2497         }
2498     }
2499 }
2500
2501 FrameView* AccessibilityRenderObject::documentFrameView() const 
2502
2503     if (!m_renderer || !m_renderer->document()) 
2504         return 0; 
2505
2506     // this is the RenderObject's Document's Frame's FrameView 
2507     return m_renderer->document()->view();
2508 }
2509
2510 Widget* AccessibilityRenderObject::widgetForAttachmentView() const
2511 {
2512     if (!isAttachment())
2513         return 0;
2514     return toRenderWidget(m_renderer)->widget();
2515 }
2516
2517 FrameView* AccessibilityRenderObject::frameViewIfRenderView() const
2518 {
2519     if (!m_renderer->isRenderView())
2520         return 0;
2521     // this is the RenderObject's Document's renderer's FrameView
2522     return m_renderer->view()->frameView();
2523 }
2524
2525 // This function is like a cross-platform version of - (WebCoreTextMarkerRange*)textMarkerRange. It returns
2526 // a Range that we can convert to a WebCoreTextMarkerRange in the Obj-C file
2527 VisiblePositionRange AccessibilityRenderObject::visiblePositionRange() const
2528 {
2529     if (!m_renderer)
2530         return VisiblePositionRange();
2531     
2532     // construct VisiblePositions for start and end
2533     Node* node = m_renderer->node();
2534     if (!node)
2535         return VisiblePositionRange();
2536
2537     VisiblePosition startPos = firstPositionInOrBeforeNode(node);
2538     VisiblePosition endPos = lastPositionInOrAfterNode(node);
2539
2540     // the VisiblePositions are equal for nodes like buttons, so adjust for that
2541     // FIXME: Really?  [button, 0] and [button, 1] are distinct (before and after the button)
2542     // I expect this code is only hit for things like empty divs?  In which case I don't think
2543     // the behavior is correct here -- eseidel
2544     if (startPos == endPos) {
2545         endPos = endPos.next();
2546         if (endPos.isNull())
2547             endPos = startPos;
2548     }
2549
2550     return VisiblePositionRange(startPos, endPos);
2551 }
2552
2553 VisiblePositionRange AccessibilityRenderObject::visiblePositionRangeForLine(unsigned lineCount) const
2554 {
2555     if (!lineCount || !m_renderer)
2556         return VisiblePositionRange();
2557     
2558     // iterate over the lines
2559     // FIXME: this is wrong when lineNumber is lineCount+1,  because nextLinePosition takes you to the
2560     // last offset of the last line
2561     VisiblePosition visiblePos = m_renderer->document()->renderer()->positionForPoint(IntPoint());
2562     VisiblePosition savedVisiblePos;
2563     while (--lineCount) {
2564         savedVisiblePos = visiblePos;
2565         visiblePos = nextLinePosition(visiblePos, 0);
2566         if (visiblePos.isNull() || visiblePos == savedVisiblePos)
2567             return VisiblePositionRange();
2568     }
2569     
2570     // make a caret selection for the marker position, then extend it to the line
2571     // NOTE: ignores results of sel.modify because it returns false when
2572     // starting at an empty line.  The resulting selection in that case
2573     // will be a caret at visiblePos.
2574     FrameSelection selection;
2575     selection.setSelection(VisibleSelection(visiblePos));
2576     selection.modify(FrameSelection::AlterationExtend, DirectionRight, LineBoundary);
2577     
2578     return VisiblePositionRange(selection.selection().visibleStart(), selection.selection().visibleEnd());
2579 }
2580     
2581 VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(int index) const
2582 {
2583     if (!m_renderer)
2584         return VisiblePosition();
2585     
2586     if (isNativeTextControl())
2587         return toRenderTextControl(m_renderer)->visiblePositionForIndex(index);
2588
2589     if (!allowsTextRanges() && !m_renderer->isText())
2590         return VisiblePosition();
2591     
2592     Node* node = m_renderer->node();
2593     if (!node)
2594         return VisiblePosition();
2595     
2596     if (index <= 0)
2597         return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
2598     
2599     ExceptionCode ec = 0;
2600     RefPtr<Range> range = Range::create(m_renderer->document());
2601     range->selectNodeContents(node, ec);
2602     CharacterIterator it(range.get());
2603     it.advance(index - 1);
2604     return VisiblePosition(Position(it.range()->endContainer(ec), it.range()->endOffset(ec), Position::PositionIsOffsetInAnchor), UPSTREAM);
2605 }
2606     
2607 int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& pos) const
2608 {
2609     if (isNativeTextControl()) {
2610         HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
2611         return textControl->indexForVisiblePosition(pos);
2612     }
2613
2614     if (!isTextControl())
2615         return 0;
2616     
2617     Node* node = m_renderer->node();
2618     if (!node)
2619         return 0;
2620     
2621     Position indexPosition = pos.deepEquivalent();
2622     if (indexPosition.isNull() || highestEditableRoot(indexPosition, HasEditableAXRole) != node)
2623         return 0;
2624     
2625     ExceptionCode ec = 0;
2626     RefPtr<Range> range = Range::create(m_renderer->document());
2627     range->setStart(node, 0, ec);
2628     range->setEnd(indexPosition, ec);
2629
2630 #if PLATFORM(GTK)
2631     // We need to consider replaced elements for GTK, as they will be
2632     // presented with the 'object replacement character' (0xFFFC).
2633     return TextIterator::rangeLength(range.get(), true);
2634 #else
2635     return TextIterator::rangeLength(range.get());
2636 #endif
2637 }
2638
2639 Element* AccessibilityRenderObject::rootEditableElementForPosition(const Position& position) const
2640 {
2641     // Find the root editable or pseudo-editable (i.e. having an editable ARIA role) element.
2642     Element* result = 0;
2643     
2644     Element* rootEditableElement = position.rootEditableElement();
2645
2646     for (Element* e = position.element(); e && e != rootEditableElement; e = e->parentElement()) {
2647         if (nodeIsTextControl(e))
2648             result = e;
2649         if (e->hasTagName(bodyTag))
2650             break;
2651     }
2652
2653     if (result)
2654         return result;
2655
2656     return rootEditableElement;
2657 }
2658
2659 bool AccessibilityRenderObject::nodeIsTextControl(const Node* node) const
2660 {
2661     if (!node)
2662         return false;
2663
2664     const AccessibilityObject* axObjectForNode = axObjectCache()->getOrCreate(const_cast<Node*>(node));
2665     if (!axObjectForNode)
2666         return false;
2667
2668     return axObjectForNode->isTextControl();
2669 }
2670
2671 IntRect AccessibilityRenderObject::boundsForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
2672 {
2673     if (visiblePositionRange.isNull())
2674         return IntRect();
2675     
2676     // Create a mutable VisiblePositionRange.
2677     VisiblePositionRange range(visiblePositionRange);
2678     LayoutRect rect1 = range.start.absoluteCaretBounds();
2679     LayoutRect rect2 = range.end.absoluteCaretBounds();
2680     
2681     // 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
2682     if (rect2.y() != rect1.y()) {
2683         VisiblePosition endOfFirstLine = endOfLine(range.start);
2684         if (range.start == endOfFirstLine) {
2685             range.start.setAffinity(DOWNSTREAM);
2686             rect1 = range.start.absoluteCaretBounds();
2687         }
2688         if (range.end == endOfFirstLine) {
2689             range.end.setAffinity(UPSTREAM);
2690             rect2 = range.end.absoluteCaretBounds();
2691         }
2692     }
2693     
2694     LayoutRect ourrect = rect1;
2695     ourrect.unite(rect2);
2696     
2697     // if the rectangle spans lines and contains multiple text chars, use the range's bounding box intead
2698     if (rect1.maxY() != rect2.maxY()) {
2699         RefPtr<Range> dataRange = makeRange(range.start, range.end);
2700         LayoutRect boundingBox = dataRange->boundingBox();
2701         String rangeString = plainText(dataRange.get());
2702         if (rangeString.length() > 1 && !boundingBox.isEmpty())
2703             ourrect = boundingBox;
2704     }
2705     
2706 #if PLATFORM(MAC)
2707     return m_renderer->document()->view()->contentsToScreen(pixelSnappedIntRect(ourrect));
2708 #else
2709     return pixelSnappedIntRect(ourrect);
2710 #endif
2711 }
2712     
2713 void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePositionRange& range) const
2714 {
2715     if (range.start.isNull() || range.end.isNull())
2716         return;
2717     
2718     // make selection and tell the document to use it. if it's zero length, then move to that position
2719     if (range.start == range.end)
2720         m_renderer->frame()->selection()->moveTo(range.start, UserTriggered);
2721     else {
2722         VisibleSelection newSelection = VisibleSelection(range.start, range.end);
2723         m_renderer->frame()->selection()->setSelection(newSelection);
2724     }    
2725 }
2726
2727 VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoint& point) const
2728 {
2729     if (!m_renderer)
2730         return VisiblePosition();
2731     
2732     // convert absolute point to view coordinates
2733     Document* topDoc = topDocument();
2734     if (!topDoc || !topDoc->renderer() || !topDoc->renderer()->view())
2735         return VisiblePosition();
2736     
2737     FrameView* frameView = topDoc->renderer()->view()->frameView();
2738     if (!frameView)
2739         return VisiblePosition();
2740     
2741     RenderView* renderView = topRenderer();
2742     if (!renderView)
2743         return VisiblePosition();
2744     
2745     Node* innerNode = 0;
2746     
2747     // locate the node containing the point
2748     LayoutPoint pointResult;
2749     while (1) {
2750         LayoutPoint ourpoint;
2751 #if PLATFORM(MAC)
2752         ourpoint = frameView->screenToContents(point);
2753 #else
2754         ourpoint = point;
2755 #endif
2756         HitTestRequest request(HitTestRequest::ReadOnly |
2757                                HitTestRequest::Active);
2758         HitTestResult result(ourpoint);
2759         renderView->hitTest(request, result);
2760         innerNode = result.innerNode();
2761         if (!innerNode)
2762             return VisiblePosition();
2763         
2764         RenderObject* renderer = innerNode->renderer();
2765         if (!renderer)
2766             return VisiblePosition();
2767         
2768         pointResult = result.localPoint();
2769
2770         // done if hit something other than a widget
2771         if (!renderer->isWidget())
2772             break;
2773
2774         // descend into widget (FRAME, IFRAME, OBJECT...)
2775         Widget* widget = toRenderWidget(renderer)->widget();
2776         if (!widget || !widget->isFrameView())
2777             break;
2778         Frame* frame = static_cast<FrameView*>(widget)->frame();
2779         if (!frame)
2780             break;
2781         renderView = frame->document()->renderView();
2782         frameView = static_cast<FrameView*>(widget);
2783     }
2784     
2785     return innerNode->renderer()->positionForPoint(pointResult);
2786 }
2787
2788 // NOTE: Consider providing this utility method as AX API
2789 VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const
2790 {
2791     if (!isTextControl())
2792         return VisiblePosition();
2793     
2794     // lastIndexOK specifies whether the position after the last character is acceptable
2795     if (indexValue >= text().length()) {
2796         if (!lastIndexOK || indexValue > text().length())
2797             return VisiblePosition();
2798     }
2799     VisiblePosition position = visiblePositionForIndex(indexValue);
2800     position.setAffinity(DOWNSTREAM);
2801     return position;
2802 }
2803
2804 // NOTE: Consider providing this utility method as AX API
2805 int AccessibilityRenderObject::index(const VisiblePosition& position) const
2806 {
2807     if (position.isNull() || !isTextControl())
2808         return -1;
2809
2810     if (renderObjectContainsPosition(m_renderer, position.deepEquivalent()))
2811         return indexForVisiblePosition(position);
2812     
2813     return -1;
2814 }
2815
2816 // Given a line number, the range of characters of the text associated with this accessibility
2817 // object that contains the line number.
2818 PlainTextRange AccessibilityRenderObject::doAXRangeForLine(unsigned lineNumber) const
2819 {
2820     if (!isTextControl())
2821         return PlainTextRange();
2822     
2823     // iterate to the specified line
2824     VisiblePosition visiblePos = visiblePositionForIndex(0);
2825     VisiblePosition savedVisiblePos;
2826     for (unsigned lineCount = lineNumber; lineCount; lineCount -= 1) {
2827         savedVisiblePos = visiblePos;
2828         visiblePos = nextLinePosition(visiblePos, 0);
2829         if (visiblePos.isNull() || visiblePos == savedVisiblePos)
2830             return PlainTextRange();
2831     }
2832
2833     // Get the end of the line based on the starting position.
2834     VisiblePosition endPosition = endOfLine(visiblePos);
2835
2836     int index1 = indexForVisiblePosition(visiblePos);
2837     int index2 = indexForVisiblePosition(endPosition);
2838     
2839     // add one to the end index for a line break not caused by soft line wrap (to match AppKit)
2840     if (endPosition.affinity() == DOWNSTREAM && endPosition.next().isNotNull())
2841         index2 += 1;
2842     
2843     // return nil rather than an zero-length range (to match AppKit)
2844     if (index1 == index2)
2845         return PlainTextRange();
2846     
2847     return PlainTextRange(index1, index2 - index1);
2848 }
2849
2850 // The composed character range in the text associated with this accessibility object that
2851 // is specified by the given index value. This parameterized attribute returns the complete
2852 // range of characters (including surrogate pairs of multi-byte glyphs) at the given index.
2853 PlainTextRange AccessibilityRenderObject::doAXRangeForIndex(unsigned index) const
2854 {
2855     if (!isTextControl())
2856         return PlainTextRange();
2857     
2858     String elementText = text();
2859     if (!elementText.length() || index > elementText.length() - 1)
2860         return PlainTextRange();
2861     
2862     return PlainTextRange(index, 1);
2863 }
2864
2865 // A substring of the text associated with this accessibility object that is
2866 // specified by the given character range.
2867 String AccessibilityRenderObject::doAXStringForRange(const PlainTextRange& range) const
2868 {
2869     if (!range.length)
2870         return String();
2871     
2872     if (!isTextControl())
2873         return String();
2874     
2875     String elementText = isPasswordField() ? passwordFieldValue() : text();
2876     if (range.start + range.length > elementText.length())
2877         return String();
2878     
2879     return elementText.substring(range.start, range.length);
2880 }
2881
2882 // The bounding rectangle of the text associated with this accessibility object that is
2883 // specified by the given range. This is the bounding rectangle a sighted user would see
2884 // on the display screen, in pixels.
2885 IntRect AccessibilityRenderObject::doAXBoundsForRange(const PlainTextRange& range) const
2886 {
2887     if (allowsTextRanges())
2888         return boundsForVisiblePositionRange(visiblePositionRangeForRange(range));
2889     return IntRect();
2890 }
2891
2892 AccessibilityObject* AccessibilityRenderObject::accessibilityImageMapHitTest(HTMLAreaElement* area, const IntPoint& point) const
2893 {
2894     if (!area)
2895         return 0;
2896     
2897     HTMLMapElement* map = static_cast<HTMLMapElement*>(area->parentNode());
2898     AccessibilityObject* parent = accessibilityParentForImageMap(map);
2899     if (!parent)
2900         return 0;
2901     
2902     AccessibilityObject::AccessibilityChildrenVector children = parent->children();
2903     
2904     unsigned count = children.size();
2905     for (unsigned k = 0; k < count; ++k) {
2906         if (children[k]->elementRect().contains(point))
2907             return children[k].get();
2908     }
2909     
2910     return 0;
2911 }
2912     
2913 AccessibilityObject* AccessibilityRenderObject::accessibilityHitTest(const IntPoint& point) const
2914 {
2915     if (!m_renderer || !m_renderer->hasLayer())
2916         return 0;
2917     
2918     RenderLayer* layer = toRenderBox(m_renderer)->layer();
2919      
2920     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
2921     HitTestResult hitTestResult = HitTestResult(point);
2922     layer->hitTest(request, hitTestResult);
2923     if (!hitTestResult.innerNode())
2924         return 0;
2925     Node* node = hitTestResult.innerNode()->shadowAncestorNode();
2926
2927     if (node->hasTagName(areaTag)) 
2928         return accessibilityImageMapHitTest(static_cast<HTMLAreaElement*>(node), point);
2929     
2930     if (node->hasTagName(optionTag))
2931         node = static_cast<HTMLOptionElement*>(node)->ownerSelectElement();
2932     
2933     RenderObject* obj = node->renderer();
2934     if (!obj)
2935         return 0;
2936     
2937     AccessibilityObject* result = obj->document()->axObjectCache()->getOrCreate(obj);
2938     result->updateChildrenIfNecessary();
2939
2940     // Allow the element to perform any hit-testing it might need to do to reach non-render children.
2941     result = result->elementAccessibilityHitTest(point);
2942     
2943     if (result && result->accessibilityIsIgnored()) {
2944         // If this element is the label of a control, a hit test should return the control.
2945         AccessibilityObject* controlObject = result->correspondingControlForLabelElement();
2946         if (controlObject && !controlObject->exposesTitleUIElement())
2947             return controlObject;
2948
2949         result = result->parentObjectUnignored();
2950     }
2951
2952     return result;
2953 }
2954
2955 bool AccessibilityRenderObject::shouldFocusActiveDescendant() const
2956 {
2957     switch (ariaRoleAttribute()) {
2958     case GroupRole:
2959     case ComboBoxRole:
2960     case ListBoxRole:
2961     case MenuRole:
2962     case MenuBarRole:
2963     case RadioGroupRole:
2964     case RowRole:
2965     case PopUpButtonRole:
2966     case ProgressIndicatorRole:
2967     case ToolbarRole:
2968     case OutlineRole:
2969     case TreeRole:
2970     case GridRole:
2971     /* FIXME: replace these with actual roles when they are added to AccessibilityRole
2972     composite
2973     alert
2974     alertdialog
2975     status
2976     timer
2977     */
2978         return true;
2979     default:
2980         return false;
2981     }
2982 }
2983
2984 AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
2985 {
2986     if (!m_renderer)
2987         return 0;
2988     
2989     if (m_renderer->node() && !m_renderer->node()->isElementNode())
2990         return 0;
2991     Element* element = static_cast<Element*>(m_renderer->node());
2992         
2993     const AtomicString& activeDescendantAttrStr = element->getAttribute(aria_activedescendantAttr);
2994     if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
2995         return 0;
2996     
2997     Element* target = element->treeScope()->getElementById(activeDescendantAttrStr);
2998     if (!target)
2999         return 0;
3000     
3001     AccessibilityObject* obj = axObjectCache()->getOrCreate(target);
3002     if (obj && obj->isAccessibilityRenderObject())
3003     // an activedescendant is only useful if it has a renderer, because that's what's needed to post the notification
3004         return obj;
3005     return 0;
3006 }
3007
3008 void AccessibilityRenderObject::handleAriaExpandedChanged()
3009 {
3010     // Find if a parent of this object should handle aria-expanded changes.
3011     AccessibilityObject* containerParent = this->parentObject();
3012     while (containerParent) {
3013         bool foundParent = false;
3014         
3015         switch (containerParent->roleValue()) {
3016         case TreeRole:
3017         case TreeGridRole:
3018         case GridRole:
3019         case TableRole:
3020         case BrowserRole:
3021             foundParent = true;
3022             break;
3023         default:
3024             break;
3025         }
3026         
3027         if (foundParent)
3028             break;
3029         
3030         containerParent = containerParent->parentObject();
3031     }
3032     
3033     // Post that the row count changed.
3034     if (containerParent)
3035         axObjectCache()->postNotification(containerParent, document(), AXObjectCache::AXRowCountChanged, true);
3036
3037     // Post that the specific row either collapsed or expanded.
3038     if (roleValue() == RowRole || roleValue() == TreeItemRole)
3039         axObjectCache()->postNotification(this, document(), isExpanded() ? AXObjectCache::AXRowExpanded : AXObjectCache::AXRowCollapsed, true);
3040 }
3041
3042 void AccessibilityRenderObject::handleActiveDescendantChanged()
3043 {
3044     Element* element = static_cast<Element*>(renderer()->node());
3045     if (!element)
3046         return;
3047     Document* doc = renderer()->document();
3048     if (!doc->frame()->selection()->isFocusedAndActive() || doc->focusedNode() != element)
3049         return; 
3050     AccessibilityRenderObject* activedescendant = static_cast<AccessibilityRenderObject*>(activeDescendant());
3051     
3052     if (activedescendant && shouldFocusActiveDescendant())
3053         doc->axObjectCache()->postNotification(m_renderer, AXObjectCache::AXActiveDescendantChanged, true);
3054 }
3055
3056 AccessibilityObject* AccessibilityRenderObject::correspondingControlForLabelElement() const
3057 {
3058     HTMLLabelElement* labelElement = labelElementContainer();
3059     if (!labelElement)
3060         return 0;
3061     
3062     HTMLElement* correspondingControl = labelElement->control();
3063     if (!correspondingControl)
3064         return 0;
3065     
3066     return axObjectCache()->getOrCreate(correspondingControl);     
3067 }
3068
3069 AccessibilityObject* AccessibilityRenderObject::correspondingLabelForControlElement() const
3070 {
3071     if (!m_renderer)
3072         return 0;
3073
3074     Node* node = m_renderer->node();
3075     if (node && node->isHTMLElement()) {
3076         HTMLLabelElement* label = labelForElement(static_cast<Element*>(node));
3077         if (label)
3078             return axObjectCache()->getOrCreate(label);
3079     }
3080
3081     return 0;
3082 }
3083
3084 bool AccessibilityRenderObject::renderObjectIsObservable(RenderObject* renderer) const
3085 {
3086     // AX clients will listen for AXValueChange on a text control.
3087     if (renderer->isTextControl())
3088         return true;
3089     
3090     // AX clients will listen for AXSelectedChildrenChanged on listboxes.
3091     Node* node = renderer->node();
3092     if (nodeHasRole(node, "listbox") || (renderer->isBoxModelObject() && toRenderBoxModelObject(renderer)->isListBox()))
3093         return true;
3094
3095     // Textboxes should send out notifications.
3096     if (nodeHasRole(node, "textbox"))
3097         return true;
3098     
3099     return false;
3100 }
3101     
3102 AccessibilityObject* AccessibilityRenderObject::observableObject() const
3103 {
3104     // Find the object going up the parent chain that is used in accessibility to monitor certain notifications.
3105     for (RenderObject* renderer = m_renderer; renderer && renderer->node(); renderer = renderer->parent()) {
3106         if (renderObjectIsObservable(renderer))
3107             return axObjectCache()->getOrCreate(renderer);
3108     }
3109     
3110     return 0;
3111 }
3112
3113 bool AccessibilityRenderObject::isDescendantOfElementType(const QualifiedName& tagName) const
3114 {
3115     for (RenderObject* parent = m_renderer->parent(); parent; parent = parent->parent()) {
3116         if (parent->node() && parent->node()->hasTagName(tagName))
3117             return true;
3118     }
3119     return false;
3120 }
3121     
3122 AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole()
3123 {
3124     if (!m_renderer)
3125         return UnknownRole;
3126
3127     m_ariaRole = determineAriaRoleAttribute();
3128     
3129     Node* node = m_renderer->node();
3130     AccessibilityRole ariaRole = ariaRoleAttribute();
3131     if (ariaRole != UnknownRole)
3132         return ariaRole;
3133
3134     RenderBoxModelObject* cssBox = renderBoxModelObject();
3135
3136     if (node && node->isLink()) {
3137         if (cssBox && cssBox->isImage())
3138             return ImageMapRole;
3139         return WebCoreLinkRole;
3140     }
3141     if (cssBox && cssBox->isListItem())
3142         return ListItemRole;
3143     if (m_renderer->isListMarker())
3144         return ListMarkerRole;
3145     if (node && node->hasTagName(buttonTag))
3146         return buttonRoleType();
3147     if (m_renderer->isText())
3148         return StaticTextRole;
3149     if (cssBox && cssBox->isImage()) {
3150         if (node && node->hasTagName(inputTag))
3151             return ariaHasPopup() ? PopUpButtonRole : ButtonRole;
3152         return ImageRole;
3153     }
3154     if (node && node->hasTagName(canvasTag))
3155         return ImageRole;
3156
3157     if (cssBox && cssBox->isRenderView())
3158         return WebAreaRole;
3159     
3160     if (cssBox && cssBox->isTextField())
3161         return TextFieldRole;
3162     
3163     if (cssBox && cssBox->isTextArea())
3164         return TextAreaRole;
3165
3166     if (node && node->hasTagName(inputTag)) {
3167         HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
3168         if (input->isCheckbox())
3169             return CheckBoxRole;
3170         if (input->isRadioButton())
3171             return RadioButtonRole;
3172         if (input->isTextButton())
3173             return buttonRoleType();
3174     }
3175
3176     if (isFileUploadButton())
3177         return ButtonRole;
3178     
3179     if (cssBox && cssBox->isMenuList())
3180         return PopUpButtonRole;
3181     
3182     if (headingLevel())
3183         return HeadingRole;
3184     
3185 #if ENABLE(MATHML)
3186     if (node && node->hasTagName(MathMLNames::mathTag))
3187         return DocumentMathRole;
3188 #endif
3189     
3190     if (node && node->hasTagName(ddTag))
3191         return DefinitionListDefinitionRole;
3192     
3193     if (node && node->hasTagName(dtTag))
3194         return DefinitionListTermRole;
3195
3196     if (node && (node->hasTagName(rpTag) || node->hasTagName(rtTag)))
3197         return AnnotationRole;
3198
3199 #if PLATFORM(GTK)
3200     // Gtk ATs expect all tables, data and layout, to be exposed as tables.
3201     if (node && (node->hasTagName(tdTag) || node->hasTagName(thTag)))
3202         return CellRole;
3203
3204     if (node && node->hasTagName(trTag))
3205         return RowRole;
3206
3207     if (node && node->hasTagName(tableTag))
3208         return TableRole;
3209 #endif
3210
3211     // Table sections should be ignored.
3212     if (m_renderer->isTableSection())
3213         return IgnoredRole;
3214     
3215 #if PLATFORM(GTK)
3216     if (m_renderer->isHR())
3217         return SplitterRole;
3218
3219     if (node && node->hasTagName(pTag))
3220         return ParagraphRole;
3221
3222     if (node && node->hasTagName(labelTag))
3223         return LabelRole;
3224
3225     if (node && node->hasTagName(divTag))
3226         return DivRole;
3227
3228     if (node && node->hasTagName(formTag))
3229         return FormRole;
3230 #else
3231     if (node && node->hasTagName(labelTag))
3232         return GroupRole;
3233 #endif
3234
3235     if (node && node->hasTagName(articleTag))
3236         return DocumentArticleRole;
3237
3238     if (node && node->hasTagName(navTag))
3239         return LandmarkNavigationRole;
3240
3241     if (node && node->hasTagName(asideTag))
3242         return LandmarkComplementaryRole;
3243
3244     if (node && node->hasTagName(sectionTag))
3245         return DocumentRegionRole;
3246
3247     if (node && node->hasTagName(addressTag))
3248         return LandmarkContentInfoRole;
3249
3250     // There should only be one banner/contentInfo per page. If header/footer are being used within an article or section
3251     // then it should not be exposed as whole page's banner/contentInfo
3252     if (node && node->hasTagName(headerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag))
3253         return LandmarkBannerRole;
3254     if (node && node->hasTagName(footerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag))
3255         return FooterRole;
3256
3257     if (m_renderer->isBlockFlow())
3258         return GroupRole;
3259     
3260     // If the element does not have role, but it has ARIA attributes, accessibility should fallback to exposing it as a group.
3261     if (supportsARIAAttributes())
3262         return GroupRole;
3263     
3264     return UnknownRole;
3265 }
3266
3267 AccessibilityOrientation AccessibilityRenderObject::orientation() const
3268 {
3269     const AtomicString& ariaOrientation = getAttribute(aria_orientationAttr);
3270     if (equalIgnoringCase(ariaOrientation, "horizontal"))
3271         return AccessibilityOrientationHorizontal;
3272     if (equalIgnoringCase(ariaOrientation, "vertical"))
3273         return AccessibilityOrientationVertical;
3274     
3275     return AccessibilityObject::orientation();
3276 }
3277     
3278 bool AccessibilityRenderObject::inheritsPresentationalRole() const
3279 {
3280     // ARIA states if an item can get focus, it should not be presentational.
3281     if (canSetFocusAttribute())
3282         return false;
3283     
3284     // ARIA spec says that when a parent object is presentational, and it has required child elements,
3285     // those child elements are also presentational. For example, <li> becomes presentational from <ul>.
3286     // http://www.w3.org/WAI/PF/aria/complete#presentation
3287     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, listItemParents, ());
3288
3289     HashSet<QualifiedName>* possibleParentTagNames = 0;
3290     switch (roleValue()) {
3291     case ListItemRole:
3292     case ListMarkerRole:
3293         if (listItemParents.isEmpty()) {
3294             listItemParents.add(ulTag);
3295             listItemParents.add(olTag);
3296             listItemParents.add(dlTag);
3297         }
3298         possibleParentTagNames = &listItemParents;
3299         break;
3300     default:
3301         break;
3302     }
3303     
3304     // Not all elements need to check for this, only ones that are required children.
3305     if (!possibleParentTagNames)
3306         return false;
3307     
3308     for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) { 
3309         if (!parent->isAccessibilityRenderObject())
3310             continue;
3311         
3312         Node* elementNode = static_cast<AccessibilityRenderObject*>(parent)->node();
3313         if (!elementNode || !elementNode->isElementNode())
3314             continue;
3315         
3316         // If native tag of the parent element matches an acceptable name, then return
3317         // based on its presentational status.
3318         if (possibleParentTagNames->contains(static_cast<Element*>(elementNode)->tagQName()))
3319             return parent->roleValue() == PresentationalRole;
3320     }
3321     
3322     return false;
3323 }
3324     
3325 bool AccessibilityRenderObject::isPresentationalChildOfAriaRole() const
3326 {
3327     // Walk the parent chain looking for a parent that has presentational children
3328     AccessibilityObject* parent;
3329     for (parent = parentObject(); parent && !parent->ariaRoleHasPresentationalChildren(); parent = parent->parentObject())
3330     { }
3331     
3332     return parent;
3333 }
3334     
3335 bool AccessibilityRenderObject::ariaRoleHasPresentationalChildren() const
3336 {
3337     switch (m_ariaRole) {
3338     case ButtonRole:
3339     case SliderRole:
3340     case ImageRole:
3341     case ProgressIndicatorRole:
3342     // case SeparatorRole:
3343         return true;
3344     default:
3345         return false;
3346     }
3347 }
3348
3349 bool AccessibilityRenderObject::canSetExpandedAttribute() const
3350 {
3351     // An object can be expanded if it aria-expanded is true or false.
3352     const AtomicString& ariaExpanded = getAttribute(aria_expandedAttr);
3353     return equalIgnoringCase(ariaExpanded, "true") || equalIgnoringCase(ariaExpanded, "false");
3354 }
3355
3356 bool AccessibilityRenderObject::canSetValueAttribute() const
3357 {
3358     if (equalIgnoringCase(getAttribute(aria_readonlyAttr), "true"))
3359         return false;
3360
3361     if (isProgressIndicator() || isSlider())
3362         return true;
3363
3364     if (isTextControl() && !isNativeTextControl())
3365         return true;
3366
3367     // Any node could be contenteditable, so isReadOnly should be relied upon
3368     // for this information for all elements.
3369     return !isReadOnly();
3370 }
3371
3372 bool AccessibilityRenderObject::canSetTextRangeAttributes() const
3373 {
3374     return isTextControl();
3375 }
3376
3377 void AccessibilityRenderObject::contentChanged()
3378 {
3379     // If this element supports ARIA live regions, or is part of a region with an ARIA editable role,
3380     // then notify the AT of changes.
3381     AXObjectCache* cache = axObjectCache();
3382     for (RenderObject* renderParent = m_renderer; renderParent; renderParent = renderParent->parent()) {
3383         AccessibilityObject* parent = cache->get(renderParent);
3384         if (!parent)
3385             continue;
3386         
3387         if (parent->supportsARIALiveRegion())
3388             cache->postNotification(renderParent, AXObjectCache::AXLiveRegionChanged, true);
3389
3390         if (parent->isARIATextControl() && !parent->isNativeTextControl() && !parent->node()->rendererIsEditable())
3391             cache->postNotification(renderParent, AXObjectCache::AXValueChanged, true);
3392     }
3393 }
3394     
3395 bool AccessibilityRenderObject::canHaveChildren() const
3396 {
3397     if (!m_renderer)
3398         return false;
3399     
3400     // Canvas is a special case; its role is ImageRole but it is allowed to have children.
3401     if (node() && node()->hasTagName(canvasTag))
3402         return true;
3403
3404     // Elements that should not have children
3405     switch (roleValue()) {
3406     case ImageRole:
3407     case ButtonRole:
3408     case PopUpButtonRole:
3409     case CheckBoxRole:
3410     case RadioButtonRole:
3411     case TabRole:
3412     case StaticTextRole:
3413     case ListBoxOptionRole:
3414     case ScrollBarRole:
3415         return false;
3416     default:
3417         return true;
3418     }
3419 }
3420
3421 void AccessibilityRenderObject::clearChildren()
3422 {
3423     AccessibilityObject::clearChildren();
3424     m_childrenDirty = false;
3425 }
3426
3427 void AccessibilityRenderObject::addImageMapChildren()
3428 {
3429     RenderBoxModelObject* cssBox = renderBoxModelObject();
3430     if (!cssBox || !cssBox->isRenderImage())
3431         return;
3432     
3433     HTMLMapElement* map = toRenderImage(cssBox)->imageMap();
3434     if (!map)
3435         return;
3436
3437     for (Node* current = map->firstChild(); current; current = current->traverseNextNode(map)) {
3438         
3439         // add an <area> element for this child if it has a link
3440         if (current->hasTagName(areaTag) && current->isLink()) {
3441             AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(axObjectCache()->getOrCreate(ImageMapLinkRole));
3442             areaObject->setHTMLAreaElement(static_cast<HTMLAreaElement*>(current));
3443             areaObject->setHTMLMapElement(map);
3444             areaObject->setParent(this);
3445             
3446             m_children.append(areaObject);
3447         }
3448     }
3449 }
3450
3451 void AccessibilityRenderObject::updateChildrenIfNecessary()
3452 {
3453     if (needsToUpdateChildren())
3454         clearChildren();        
3455     
3456     AccessibilityObject::updateChildrenIfNecessary();
3457 }
3458     
3459 void AccessibilityRenderObject::addTextFieldChildren()
3460 {
3461     Node* node = this->node();
3462     if (!node || !node->hasTagName(inputTag))
3463         return;
3464     
3465     HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
3466     HTMLElement* spinButtonElement = input->innerSpinButtonElement();
3467     if (!spinButtonElement || !spinButtonElement->isSpinButtonElement())
3468         return;
3469
3470     AccessibilitySpinButton* axSpinButton = static_cast<AccessibilitySpinButton*>(axObjectCache()->getOrCreate(SpinButtonRole));
3471     axSpinButton->setSpinButtonElement(static_cast<SpinButtonElement*>(spinButtonElement));
3472     axSpinButton->setParent(this);
3473     m_children.append(axSpinButton);
3474 }
3475
3476 void AccessibilityRenderObject::addCanvasChildren()
3477 {
3478     if (!node() || !node()->hasTagName(canvasTag))
3479         return;
3480
3481     // If it's a canvas, it won't have rendered children, but it might have accessible fallback content.
3482     // Clear m_haveChildren because AccessibilityNodeObject::addChildren will expect it to be false.
3483     ASSERT(!m_children.size());
3484     m_haveChildren = false;
3485     AccessibilityNodeObject::addChildren();
3486 }
3487
3488 void AccessibilityRenderObject::addAttachmentChildren()
3489 {
3490     if (!isAttachment())
3491         return;
3492
3493     // FrameView's need to be inserted into the AX hierarchy when encountered.
3494     Widget* widget = widgetForAttachmentView();
3495     if (!widget || !widget->isFrameView())
3496         return;
3497     
3498     AccessibilityObject* axWidget = axObjectCache()->getOrCreate(widget);
3499     if (!axWidget->accessibilityIsIgnored())
3500         m_children.append(axWidget);
3501 }
3502
3503 #if PLATFORM(MAC)
3504 void AccessibilityRenderObject::updateAttachmentViewParents()
3505 {
3506     // Only the unignored parent should set the attachment parent, because that's what is reflected in the AX 
3507     // hierarchy to the client.
3508     if (accessibilityIsIgnored())
3509         return;
3510     
3511     size_t length = m_children.size();
3512     for (size_t k = 0; k < length; k++) {
3513         if (m_children[k]->isAttachment())
3514             m_children[k]->overrideAttachmentParent(this);
3515     }
3516 }
3517 #endif
3518
3519 void AccessibilityRenderObject::addChildren()
3520 {
3521     // If the need to add more children in addition to existing children arises, 
3522     // childrenChanged should have been called, leaving the object with no children.
3523     ASSERT(!m_haveChildren); 
3524
3525     m_haveChildren = true;
3526     
3527     if (!canHaveChildren())
3528         return;
3529     
3530     // add all unignored acc children
3531     for (RefPtr<AccessibilityObject> obj = firstChild(); obj; obj = obj->nextSibling()) {
3532         // If the parent is asking for this child's children, then either it's the first time (and clearing is a no-op), 
3533         // or its visibility has changed. In the latter case, this child may have a stale child cached. 
3534         // This can prevent aria-hidden changes from working correctly. Hence, whenever a parent is getting children, ensure data is not stale.
3535         obj->clearChildren();
3536
3537         if (obj->accessibilityIsIgnored()) {
3538             AccessibilityChildrenVector children = obj->children();
3539             unsigned length = children.size();
3540             for (unsigned i = 0; i < length; ++i)
3541                 m_children.append(children[i]);
3542         } else {
3543             ASSERT(obj->parentObject() == this);
3544             m_children.append(obj);
3545         }
3546     }
3547     
3548     addAttachmentChildren();
3549     addImageMapChildren();
3550     addTextFieldChildren();
3551     addCanvasChildren();
3552
3553 #if PLATFORM(MAC)
3554     updateAttachmentViewParents();
3555 #endif
3556 }
3557         
3558 const AtomicString& AccessibilityRenderObject::ariaLiveRegionStatus() const
3559 {
3560     DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusAssertive, ("assertive"));
3561     DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusPolite, ("polite"));
3562     DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusOff, ("off"));
3563     
3564     const AtomicString& liveRegionStatus = getAttribute(aria_liveAttr);
3565     // These roles have implicit live region status.
3566     if (liveRegionStatus.isEmpty()) {
3567         switch (roleValue()) {
3568         case ApplicationAlertDialogRole:
3569         case ApplicationAlertRole:
3570             return liveRegionStatusAssertive;
3571         case ApplicationLogRole:
3572         case ApplicationStatusRole:
3573             return liveRegionStatusPolite;
3574         case ApplicationTimerRole:
3575         case ApplicationMarqueeRole:
3576             return liveRegionStatusOff;
3577         default:
3578             break;
3579         }
3580     }
3581
3582     return liveRegionStatus;
3583 }
3584
3585 const AtomicString& AccessibilityRenderObject::ariaLiveRegionRelevant() const
3586 {
3587     DEFINE_STATIC_LOCAL(const AtomicString, defaultLiveRegionRelevant, ("additions text"));
3588     const AtomicString& relevant = getAttribute(aria_relevantAttr);
3589
3590     // Default aria-relevant = "additions text".
3591     if (relevant.isEmpty())
3592         return defaultLiveRegionRelevant;
3593     
3594     return relevant;
3595 }
3596
3597 bool AccessibilityRenderObject::ariaLiveRegionAtomic() const
3598 {
3599     return elementAttributeValue(aria_atomicAttr);    
3600 }
3601
3602 bool AccessibilityRenderObject::ariaLiveRegionBusy() const
3603 {
3604     return elementAttributeValue(aria_busyAttr);    
3605 }
3606     
3607 void AccessibilityRenderObject::ariaSelectedRows(AccessibilityChildrenVector& result)
3608 {
3609     // Get all the rows. 
3610     AccessibilityChildrenVector allRows;
3611     if (isTree())
3612         ariaTreeRows(allRows);
3613     else if (isAccessibilityTable() && toAccessibilityTable(this)->supportsSelectedRows())
3614         allRows = toAccessibilityTable(this)->rows();
3615
3616     // Determine which rows are selected.
3617     bool isMulti = isMultiSelectable();
3618
3619     // Prefer active descendant over aria-selected.
3620     AccessibilityObject* activeDesc = activeDescendant();
3621     if (activeDesc && (activeDesc->isTreeItem() || activeDesc->isTableRow())) {
3622         result.append(activeDesc);    
3623         if (!isMulti)
3624             return;
3625     }
3626
3627     unsigned count = allRows.size();
3628     for (unsigned k = 0; k < count; ++k) {
3629         if (allRows[k]->isSelected()) {
3630             result.append(allRows[k]);
3631             if (!isMulti)
3632                 break;
3633         }
3634     }
3635 }
3636     
3637 void AccessibilityRenderObject::ariaListboxSelectedChildren(AccessibilityChildrenVector& result)
3638 {
3639     bool isMulti = isMultiSelectable();
3640
3641     AccessibilityChildrenVector childObjects = children();
3642     unsigned childrenSize = childObjects.size();
3643     for (unsigned k = 0; k < childrenSize; ++k) {
3644         // Every child should have aria-role option, and if so, check for selected attribute/state.
3645         AccessibilityObject* child = childObjects[k].get();
3646         if (child->isSelected() && child->ariaRoleAttribute() == ListBoxOptionRole) {
3647             result.append(child);
3648             if (!isMulti)
3649                 return;
3650         }
3651     }
3652 }
3653
3654 void AccessibilityRenderObject::selectedChildren(AccessibilityChildrenVector& result)
3655 {
3656     ASSERT(result.isEmpty());
3657
3658     // only listboxes should be asked for their selected children. 
3659     AccessibilityRole role = roleValue();
3660     if (role == ListBoxRole) // native list boxes would be AccessibilityListBoxes, so only check for aria list boxes
3661         ariaListboxSelectedChildren(result);
3662     else if (role == TreeRole || role == TreeGridRole || role == TableRole)
3663         ariaSelectedRows(result);
3664 }
3665
3666 void AccessibilityRenderObject::ariaListboxVisibleChildren(AccessibilityChildrenVector& result)      
3667 {
3668     if (!hasChildren())
3669         addChildren();
3670     
3671     AccessibilityObject::AccessibilityChildrenVector children = this->children();
3672     size_t size = children.size();
3673     for (size_t i = 0; i < size; i++) {
3674         if (!children[i]->isOffScreen())
3675             result.append(children[i]);
3676     }
3677 }
3678
3679 void AccessibilityRenderObject::visibleChildren(AccessibilityChildrenVector& result)
3680 {
3681     ASSERT(result.isEmpty());
3682         
3683     // only listboxes are asked for their visible children. 
3684     if (ariaRoleAttribute() != ListBoxRole) { // native list boxes would be AccessibilityListBoxes, so only check for aria list boxes
3685         ASSERT_NOT_REACHED();
3686         return;
3687     }
3688     return ariaListboxVisibleChildren(result);
3689 }
3690  
3691 void AccessibilityRenderObject::tabChildren(AccessibilityChildrenVector& result)
3692 {
3693     ASSERT(roleValue() == TabListRole);
3694     
3695     AccessibilityObject::AccessibilityChildrenVector children = this->children();
3696     size_t size = children.size();
3697     for (size_t i = 0; i < size; ++i) {
3698         if (children[i]->isTabItem())
3699             result.append(children[i]);
3700     }
3701 }
3702     
3703 const String& AccessibilityRenderObject::actionVerb() const
3704 {
3705     // FIXME: Need to add verbs for select elements.
3706     DEFINE_STATIC_LOCAL(const String, buttonAction, (AXButtonActionVerb()));
3707     DEFINE_STATIC_LOCAL(const String, textFieldAction, (AXTextFieldActionVerb()));
3708     DEFINE_STATIC_LOCAL(const String, radioButtonAction, (AXRadioButtonActionVerb()));
3709     DEFINE_STATIC_LOCAL(const String, checkedCheckBoxAction, (AXCheckedCheckBoxActionVerb()));
3710     DEFINE_STATIC_LOCAL(const String, uncheckedCheckBoxAction, (AXUncheckedCheckBoxActionVerb()));
3711     DEFINE_STATIC_LOCAL(const String, linkAction, (AXLinkActionVerb()));
3712     DEFINE_STATIC_LOCAL(const String, noAction, ());
3713     
3714     switch (roleValue()) {
3715     case ButtonRole:
3716         return buttonAction;
3717     case TextFieldRole:
3718     case TextAreaRole:
3719         return textFieldAction;
3720     case RadioButtonRole:
3721         return radioButtonAction;
3722     case CheckBoxRole:
3723         return isChecked() ? checkedCheckBoxAction : uncheckedCheckBoxAction;
3724     case LinkRole:
3725     case WebCoreLinkRole:
3726         return linkAction;
3727     default:
3728         return noAction;
3729     }
3730 }
3731     
3732 void AccessibilityRenderObject::setAccessibleName(const AtomicString& name)
3733 {
3734     // Setting the accessible name can store the value in the DOM
3735     if (!m_renderer)
3736         return;
3737
3738     Node* domNode = 0;
3739     // For web areas, set the aria-label on the HTML element.
3740     if (isWebArea())
3741         domNode = m_renderer->document()->documentElement();
3742     else
3743         domNode = m_renderer->node();
3744
3745     if (domNode && domNode->isElementNode())
3746         static_cast<Element*>(domNode)->setAttribute(aria_labelAttr, name);
3747 }
3748     
3749 static bool isLinkable(const AccessibilityRenderObject& object)
3750 {
3751     if (!object.renderer())
3752         return false;
3753
3754     // See https://wiki.mozilla.org/Accessibility/AT-Windows-API for the elements
3755     // Mozilla considers linkable.
3756     return object.isLink() || object.isImage() || object.renderer()->isText();
3757 }
3758
3759 String AccessibilityRenderObject::stringValueForMSAA() const
3760 {
3761     if (isLinkable(*this)) {
3762         Element* anchor = anchorElement();
3763         if (anchor && anchor->hasTagName(aTag))
3764             return static_cast<HTMLAnchorElement*>(anchor)->href();
3765     }
3766
3767     return stringValue();
3768 }
3769
3770 bool AccessibilityRenderObject::isLinked() const
3771 {
3772     if (!isLinkable(*this))
3773         return false;
3774
3775     Element* anchor = anchorElement();
3776     if (!anchor || !anchor->hasTagName(aTag))
3777         return false;
3778
3779     return !static_cast<HTMLAnchorElement*>(anchor)->href().isEmpty();
3780 }
3781
3782 bool AccessibilityRenderObject::hasBoldFont() const
3783 {
3784     if (!m_renderer)
3785         return false;
3786     
3787     return m_renderer->style()->fontDescription().weight() >= FontWeightBold;
3788 }
3789
3790 bool AccessibilityRenderObject::hasItalicFont() const
3791 {
3792     if (!m_renderer)
3793         return false;
3794     
3795     return m_renderer->style()->fontDescription().italic() == FontItalicOn;
3796 }
3797
3798 bool AccessibilityRenderObject::hasPlainText() const
3799 {
3800     if (!m_renderer)
3801         return false;
3802     
3803     RenderStyle* style = m_renderer->style();
3804     
3805     return style->fontDescription().weight() == FontWeightNormal
3806         && style->fontDescription().italic() == FontItalicOff
3807         && style->textDecorationsInEffect() == TDNONE;
3808 }
3809
3810 bool AccessibilityRenderObject::hasSameFont(RenderObject* renderer) const
3811 {
3812     if (!m_renderer || !renderer)
3813         return false;
3814     
3815     return m_renderer->style()->fontDescription().family() == renderer->style()->fontDescription().family();
3816 }
3817
3818 bool AccessibilityRenderObject::hasSameFontColor(RenderObject* renderer) const
3819 {
3820     if (!m_renderer || !renderer)
3821         return false;
3822     
3823     return m_renderer->style()->visitedDependentColor(CSSPropertyColor) == renderer->style()->visitedDependentColor(CSSPropertyColor);
3824 }
3825
3826 bool AccessibilityRenderObject::hasSameStyle(RenderObject* renderer) const
3827 {
3828     if (!m_renderer || !renderer)
3829         return false;
3830     
3831     return m_renderer->style() == renderer->style();
3832 }
3833
3834 bool AccessibilityRenderObject::hasUnderline() const
3835 {
3836     if (!m_renderer)
3837         return false;
3838     
3839     return m_renderer->style()->textDecorationsInEffect() & UNDERLINE;
3840 }
3841
3842 String AccessibilityRenderObject::nameForMSAA() const
3843 {
3844     if (m_renderer && m_renderer->isText())
3845         return textUnderElement();
3846
3847     return title();
3848 }
3849
3850 static bool shouldReturnTagNameAsRoleForMSAA(const Element& element)
3851 {
3852     // See "document structure",
3853     // https://wiki.mozilla.org/Accessibility/AT-Windows-API
3854     // FIXME: Add the other tag names that should be returned as the role.
3855     return element.hasTagName(h1Tag) || element.hasTagName(h2Tag) 
3856         || element.hasTagName(h3Tag) || element.hasTagName(h4Tag)
3857         || element.hasTagName(h5Tag) || element.hasTagName(h6Tag);
3858 }
3859
3860 String AccessibilityRenderObject::stringRoleForMSAA() const
3861 {
3862     if (!m_renderer)
3863         return String();
3864
3865     Node* node = m_renderer->node();
3866     if (!node || !node->isElementNode())
3867         return String();
3868
3869     Element* element = static_cast<Element*>(node);
3870     if (!shouldReturnTagNameAsRoleForMSAA(*element))