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