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