initial import
[vuplus_webkit] / Source / WebKit / chromium / src / WebAccessibilityObject.cpp
1 /*
2  * Copyright (C) 2009 Google 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 are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "WebAccessibilityObject.h"
33
34 #include "AccessibilityObject.h"
35 #include "AccessibilityTable.h"
36 #include "AccessibilityTableCell.h"
37 #include "CSSPrimitiveValueMappings.h"
38 #include "Document.h"
39 #include "EventHandler.h"
40 #include "FrameView.h"
41 #include "HTMLNames.h"
42 #include "Node.h"
43 #include "PlatformKeyboardEvent.h"
44 #include "RenderStyle.h"
45 #include "UserGestureIndicator.h"
46 #include "WebDocument.h"
47 #include "WebNode.h"
48 #include "WebPoint.h"
49 #include "WebRect.h"
50 #include "WebString.h"
51 #include "WebURL.h"
52
53 using namespace WebCore;
54
55 namespace WebKit {
56
57 void WebAccessibilityObject::reset()
58 {
59     m_private.reset();
60 }
61
62 void WebAccessibilityObject::assign(const WebKit::WebAccessibilityObject& other)
63 {
64     m_private = other.m_private;
65 }
66
67 bool WebAccessibilityObject::equals(const WebAccessibilityObject& n) const
68 {
69     return (m_private.get() == n.m_private.get());
70 }
71
72 WebString WebAccessibilityObject::accessibilityDescription() const
73 {
74     if (m_private.isNull())
75         return WebString();
76
77     m_private->updateBackingStore();
78     return m_private->accessibilityDescription();
79 }
80
81 WebString WebAccessibilityObject::actionVerb() const
82 {
83     if (m_private.isNull())
84         return WebString();
85
86     m_private->updateBackingStore();
87     return m_private->actionVerb();
88 }
89
90 bool WebAccessibilityObject::canSetFocusAttribute() const
91 {
92     if (m_private.isNull())
93         return false;
94
95     m_private->updateBackingStore();
96     return m_private->canSetFocusAttribute();
97 }
98
99 bool WebAccessibilityObject::canSetValueAttribute() const
100 {
101     if (m_private.isNull())
102         return false;
103
104     m_private->updateBackingStore();
105     return m_private->canSetValueAttribute();
106 }
107
108 bool WebAccessibilityObject::isValid() const
109 {
110     if (m_private.isNull())
111         return false;
112
113     m_private->updateBackingStore();
114     return m_private->axObjectID();
115 }
116
117 unsigned WebAccessibilityObject::childCount() const
118 {
119     if (m_private.isNull())
120         return 0;
121
122     m_private->updateBackingStore();
123     return m_private->children().size();
124 }
125
126 WebAccessibilityObject WebAccessibilityObject::childAt(unsigned index) const
127 {
128     if (m_private.isNull())
129         return WebAccessibilityObject();
130
131     m_private->updateBackingStore();
132     if (m_private->children().size() <= index)
133         return WebAccessibilityObject();
134
135     return WebAccessibilityObject(m_private->children()[index]);
136 }
137
138 WebAccessibilityObject WebAccessibilityObject::firstChild() const
139 {
140     if (m_private.isNull())
141         return WebAccessibilityObject();
142
143     m_private->updateBackingStore();
144     return WebAccessibilityObject(m_private->firstChild());
145 }
146
147 WebAccessibilityObject WebAccessibilityObject::focusedChild() const
148 {
149     if (m_private.isNull())
150         return WebAccessibilityObject();
151
152     m_private->updateBackingStore();
153     RefPtr<AccessibilityObject> focused = m_private->focusedUIElement();
154     if (m_private.get() == focused.get() || m_private.get() == focused->parentObject())
155         return WebAccessibilityObject(focused);
156
157     return WebAccessibilityObject();
158 }
159
160 WebAccessibilityObject WebAccessibilityObject::lastChild() const
161 {
162     if (m_private.isNull())
163         return WebAccessibilityObject();
164
165     m_private->updateBackingStore();
166     return WebAccessibilityObject(m_private->lastChild());
167 }
168
169
170 WebAccessibilityObject WebAccessibilityObject::nextSibling() const
171 {
172     if (m_private.isNull())
173         return WebAccessibilityObject();
174
175     m_private->updateBackingStore();
176     return WebAccessibilityObject(m_private->nextSibling());
177 }
178
179 WebAccessibilityObject WebAccessibilityObject::parentObject() const
180 {
181     if (m_private.isNull())
182         return WebAccessibilityObject();
183
184     m_private->updateBackingStore();
185     return WebAccessibilityObject(m_private->parentObject());
186 }
187
188
189 WebAccessibilityObject WebAccessibilityObject::previousSibling() const
190 {
191     if (m_private.isNull())
192         return WebAccessibilityObject();
193
194     m_private->updateBackingStore();
195     return WebAccessibilityObject(m_private->previousSibling());
196 }
197
198 bool WebAccessibilityObject::canSetSelectedAttribute() const
199 {
200     if (m_private.isNull())
201         return 0;
202
203     m_private->updateBackingStore();
204     return m_private->canSetSelectedAttribute();
205 }
206
207 bool WebAccessibilityObject::isAnchor() const
208 {
209     if (m_private.isNull())
210         return 0;
211
212     m_private->updateBackingStore();
213     return m_private->isAnchor();
214 }
215
216 bool WebAccessibilityObject::isAriaReadOnly() const
217 {
218     if (m_private.isNull())
219         return 0;
220
221     m_private->updateBackingStore();
222     return equalIgnoringCase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true");
223 }
224
225 bool WebAccessibilityObject::isButtonStateMixed() const
226 {
227     if (m_private.isNull())
228         return 0;
229
230     m_private->updateBackingStore();
231     return m_private->checkboxOrRadioValue() == ButtonStateMixed;
232 }
233
234 bool WebAccessibilityObject::isChecked() const
235 {
236     if (m_private.isNull())
237         return 0;
238
239     m_private->updateBackingStore();
240     return m_private->isChecked();
241 }
242
243 bool WebAccessibilityObject::isCollapsed() const
244 {
245     if (m_private.isNull())
246         return 0;
247
248     m_private->updateBackingStore();
249     return m_private->isCollapsed();
250 }
251
252 bool WebAccessibilityObject::isControl() const
253 {
254     if (m_private.isNull())
255         return 0;
256
257     m_private->updateBackingStore();
258     return m_private->isControl();
259 }
260
261 bool WebAccessibilityObject::isEnabled() const
262 {
263     if (m_private.isNull())
264         return 0;
265
266     m_private->updateBackingStore();
267     return m_private->isEnabled();
268 }
269
270 bool WebAccessibilityObject::isFocused() const
271 {
272     if (m_private.isNull())
273         return 0;
274
275     m_private->updateBackingStore();
276     return m_private->isFocused();
277 }
278
279 bool WebAccessibilityObject::isHovered() const
280 {
281     if (m_private.isNull())
282         return 0;
283
284     m_private->updateBackingStore();
285     return m_private->isHovered();
286 }
287
288 bool WebAccessibilityObject::isIndeterminate() const
289 {
290     if (m_private.isNull())
291         return 0;
292
293     m_private->updateBackingStore();
294     return m_private->isIndeterminate();
295 }
296
297 bool WebAccessibilityObject::isLinked() const
298 {
299     if (m_private.isNull())
300         return 0;
301
302     m_private->updateBackingStore();
303     return m_private->isLinked();
304 }
305
306 bool WebAccessibilityObject::isLoaded() const
307 {
308     if (m_private.isNull())
309         return 0;
310
311     m_private->updateBackingStore();
312     return m_private->isLoaded();
313 }
314
315 bool WebAccessibilityObject::isMultiSelectable() const
316 {
317     if (m_private.isNull())
318         return 0;
319
320     m_private->updateBackingStore();
321     return m_private->isMultiSelectable();
322 }
323
324 bool WebAccessibilityObject::isOffScreen() const
325 {
326     if (m_private.isNull())
327         return 0;
328
329     m_private->updateBackingStore();
330     return m_private->isOffScreen();
331 }
332
333 bool WebAccessibilityObject::isPasswordField() const
334 {
335     if (m_private.isNull())
336         return 0;
337
338     m_private->updateBackingStore();
339     return m_private->isPasswordField();
340 }
341
342 bool WebAccessibilityObject::isPressed() const
343 {
344     if (m_private.isNull())
345         return 0;
346
347     m_private->updateBackingStore();
348     return m_private->isPressed();
349 }
350
351 bool WebAccessibilityObject::isReadOnly() const
352 {
353     if (m_private.isNull())
354         return 0;
355
356     m_private->updateBackingStore();
357     return m_private->isReadOnly();
358 }
359
360 bool WebAccessibilityObject::isRequired() const
361 {
362     if (m_private.isNull())
363         return 0;
364
365     m_private->updateBackingStore();
366     return m_private->isRequired();
367 }
368
369 bool WebAccessibilityObject::isSelected() const
370 {
371     if (m_private.isNull())
372         return 0;
373
374     m_private->updateBackingStore();
375     return m_private->isSelected();
376 }
377
378 bool WebAccessibilityObject::isVertical() const
379 {
380     if (m_private.isNull())
381         return 0;
382
383     m_private->updateBackingStore();
384     return m_private->orientation() == AccessibilityOrientationVertical;
385 }
386
387 bool WebAccessibilityObject::isVisible() const
388 {
389     if (m_private.isNull())
390         return 0;
391
392     m_private->updateBackingStore();
393     return m_private->isVisible();
394 }
395
396 bool WebAccessibilityObject::isVisited() const
397 {
398     if (m_private.isNull())
399         return 0;
400
401     m_private->updateBackingStore();
402     return m_private->isVisited();
403 }
404
405 WebString WebAccessibilityObject::accessKey() const
406 {
407     if (m_private.isNull())
408         return WebString();
409
410     m_private->updateBackingStore();
411     return WebString(m_private->accessKey());
412 }
413
414 bool WebAccessibilityObject::ariaHasPopup() const
415 {
416     if (m_private.isNull())
417         return 0;
418
419     m_private->updateBackingStore();
420     return m_private->ariaHasPopup();
421 }
422
423 bool WebAccessibilityObject::ariaLiveRegionAtomic() const
424 {
425     if (m_private.isNull())
426         return 0;
427
428     m_private->updateBackingStore();
429     return m_private->ariaLiveRegionAtomic();
430 }
431
432 bool WebAccessibilityObject::ariaLiveRegionBusy() const
433 {
434     if (m_private.isNull())
435         return 0;
436
437     m_private->updateBackingStore();
438     return m_private->ariaLiveRegionBusy();
439 }
440
441 WebString WebAccessibilityObject::ariaLiveRegionRelevant() const
442 {
443     if (m_private.isNull())
444         return WebString();
445
446     m_private->updateBackingStore();
447     return m_private->ariaLiveRegionRelevant();
448 }
449
450 WebString WebAccessibilityObject::ariaLiveRegionStatus() const
451 {
452     if (m_private.isNull())
453         return WebString();
454
455     m_private->updateBackingStore();
456     return m_private->ariaLiveRegionStatus();
457 }
458
459 WebRect WebAccessibilityObject::boundingBoxRect() const
460 {
461     if (m_private.isNull())
462         return WebRect();
463
464     m_private->updateBackingStore();
465     return m_private->boundingBoxRect();
466 }
467
468 double WebAccessibilityObject::estimatedLoadingProgress() const
469 {
470     if (m_private.isNull())
471         return 0.0;
472
473     m_private->updateBackingStore();
474     return m_private->estimatedLoadingProgress();
475 }
476
477 WebString WebAccessibilityObject::helpText() const
478 {
479     if (m_private.isNull())
480         return WebString();
481
482     m_private->updateBackingStore();
483     return m_private->helpText();
484 }
485
486 int WebAccessibilityObject::headingLevel() const
487 {
488     if (m_private.isNull())
489         return 0;
490
491     m_private->updateBackingStore();
492     return m_private->headingLevel();
493 }
494
495 int WebAccessibilityObject::hierarchicalLevel() const
496 {
497     if (m_private.isNull())
498         return 0;
499
500     m_private->updateBackingStore();
501     return m_private->hierarchicalLevel();
502 }
503
504 WebAccessibilityObject WebAccessibilityObject::hitTest(const WebPoint& point) const
505 {
506     if (m_private.isNull())
507         return WebAccessibilityObject();
508
509     m_private->updateBackingStore();
510     IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
511     RefPtr<AccessibilityObject> hit = m_private->accessibilityHitTest(contentsPoint);
512
513     if (hit.get())
514         return WebAccessibilityObject(hit);
515
516     if (m_private->boundingBoxRect().contains(contentsPoint))
517         return *this;
518
519     return WebAccessibilityObject();
520 }
521
522 WebString WebAccessibilityObject::keyboardShortcut() const
523 {
524     if (m_private.isNull())
525         return WebString();
526
527     m_private->updateBackingStore();
528     String accessKey = m_private->accessKey();
529     if (accessKey.isNull())
530         return WebString();
531
532     static String modifierString;
533     if (modifierString.isNull()) {
534         unsigned modifiers = EventHandler::accessKeyModifiers();
535         // Follow the same order as Mozilla MSAA implementation:
536         // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
537         // should not be localized and defines the separator as "+".
538         if (modifiers & PlatformKeyboardEvent::CtrlKey)
539             modifierString += "Ctrl+";
540         if (modifiers & PlatformKeyboardEvent::AltKey)
541             modifierString += "Alt+";
542         if (modifiers & PlatformKeyboardEvent::ShiftKey)
543             modifierString += "Shift+";
544         if (modifiers & PlatformKeyboardEvent::MetaKey)
545             modifierString += "Win+";
546     }
547
548     return String(modifierString + accessKey);
549 }
550
551 bool WebAccessibilityObject::performDefaultAction() const
552 {
553     if (m_private.isNull())
554         return false;
555
556     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
557
558     m_private->updateBackingStore();
559     return m_private->performDefaultAction();
560 }
561
562 WebAccessibilityRole WebAccessibilityObject::roleValue() const
563 {
564     if (m_private.isNull())
565         return WebKit::WebAccessibilityRoleUnknown;
566
567     m_private->updateBackingStore();
568     return static_cast<WebAccessibilityRole>(m_private->roleValue());
569 }
570
571 unsigned WebAccessibilityObject::selectionEnd() const
572 {
573     if (m_private.isNull())
574         return 0;
575
576     m_private->updateBackingStore();
577     return m_private->selectedTextRange().start + m_private->selectedTextRange().length;
578 }
579
580 unsigned WebAccessibilityObject::selectionStart() const
581 {
582     if (m_private.isNull())
583         return 0;
584
585     m_private->updateBackingStore();
586     return m_private->selectedTextRange().start;
587 }
588
589 void WebAccessibilityObject::setFocused(bool on) const
590 {
591     if (!m_private.isNull())
592         m_private->setFocused(on);
593 }
594
595 WebString WebAccessibilityObject::stringValue() const
596 {
597     if (m_private.isNull())
598         return WebString();
599
600     m_private->updateBackingStore();
601     return m_private->stringValue();
602 }
603
604 WebString WebAccessibilityObject::title() const
605 {
606     if (m_private.isNull())
607         return WebString();
608
609     m_private->updateBackingStore();
610     return m_private->title();
611 }
612
613 WebURL WebAccessibilityObject::url() const
614 {
615     if (m_private.isNull())
616         return WebURL();
617     
618     m_private->updateBackingStore();
619     return m_private->url();
620 }
621
622 WebString WebAccessibilityObject::valueDescription() const
623 {
624     if (m_private.isNull())
625         return WebString();
626
627     m_private->updateBackingStore();
628     return m_private->valueDescription();
629 }
630
631 float WebAccessibilityObject::valueForRange() const
632 {
633     if (m_private.isNull())
634         return 0.0;
635
636     m_private->updateBackingStore();
637     return m_private->valueForRange();
638 }
639
640 float WebAccessibilityObject::maxValueForRange() const
641 {
642     if (m_private.isNull())
643         return 0.0;
644
645     m_private->updateBackingStore();
646     return m_private->maxValueForRange();
647 }
648
649 float WebAccessibilityObject::minValueForRange() const
650 {
651     if (m_private.isNull())
652         return 0.0;
653
654     m_private->updateBackingStore();
655     return m_private->minValueForRange();
656 }
657
658 WebNode WebAccessibilityObject::node() const
659 {
660     if (m_private.isNull())
661         return WebNode();
662
663     m_private->updateBackingStore();
664
665     Node* node = m_private->node();
666     if (!node)
667         return WebNode();
668
669     return WebNode(node);
670 }
671
672 WebDocument WebAccessibilityObject::document() const
673 {
674     if (m_private.isNull())
675         return WebDocument();
676
677     m_private->updateBackingStore();
678
679     Document* document = m_private->document();
680     if (!document)
681         return WebDocument();
682
683     return WebDocument(document);
684 }
685
686 bool WebAccessibilityObject::hasComputedStyle() const
687 {
688     if (m_private.isNull())
689         return false;
690
691     Document* document = m_private->document();
692     if (document)
693         document->updateStyleIfNeeded();
694
695     Node* node = m_private->node();
696     if (!node)
697         return false;
698
699     return node->computedStyle();
700 }
701
702 WebString WebAccessibilityObject::computedStyleDisplay() const
703 {
704     if (m_private.isNull())
705         return WebString();
706
707     Document* document = m_private->document();
708     if (document)
709         document->updateStyleIfNeeded();
710
711     Node* node = m_private->node();
712     if (!node)
713         return WebString();
714
715     RenderStyle* renderStyle = node->computedStyle();
716     if (!renderStyle)
717         return WebString();
718
719     return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue());
720 }
721
722 bool WebAccessibilityObject::accessibilityIsIgnored() const
723 {
724     if (m_private.isNull())
725         return false;
726
727     m_private->updateBackingStore();
728     return m_private->accessibilityIsIgnored();
729 }
730
731 bool WebAccessibilityObject::lineBreaks(WebVector<int>& result) const
732 {
733     if (m_private.isNull())
734         return false;
735
736     m_private->updateBackingStore();
737     int textLength = m_private->textLength();
738     if (!textLength)
739         return false;
740
741     VisiblePosition pos = m_private->visiblePositionForIndex(textLength);
742     int lineBreakCount = m_private->lineForPosition(pos);
743     if (!lineBreakCount)
744         return false;
745
746     WebVector<int> lineBreaks(static_cast<size_t>(lineBreakCount));
747     for (int i = 0; i < lineBreakCount; i++) {
748         PlainTextRange range = m_private->doAXRangeForLine(i);
749         lineBreaks[i] = range.start + range.length;
750     }
751     result.swap(lineBreaks);
752     return true;
753 }
754
755 unsigned WebAccessibilityObject::columnCount() const
756 {
757     if (m_private.isNull())
758         return false;
759
760     m_private->updateBackingStore();
761     if (!m_private->isAccessibilityTable())
762         return 0;
763
764     return static_cast<WebCore::AccessibilityTable*>(m_private.get())->columnCount();
765 }
766
767 unsigned WebAccessibilityObject::rowCount() const
768 {
769     if (m_private.isNull())
770         return false;
771
772     m_private->updateBackingStore();
773     if (!m_private->isAccessibilityTable())
774         return 0;
775
776     return static_cast<WebCore::AccessibilityTable*>(m_private.get())->rowCount();
777 }
778
779 WebAccessibilityObject WebAccessibilityObject::cellForColumnAndRow(unsigned column, unsigned row) const
780 {
781     m_private->updateBackingStore();
782     if (!m_private->isAccessibilityTable())
783         return WebAccessibilityObject();
784
785     WebCore::AccessibilityTableCell* cell = static_cast<WebCore::AccessibilityTable*>(m_private.get())->cellForColumnAndRow(column, row);
786     return WebAccessibilityObject(static_cast<WebCore::AccessibilityObject*>(cell));
787 }
788
789 unsigned WebAccessibilityObject::cellColumnIndex() const
790 {
791     m_private->updateBackingStore();
792     if (!m_private->isTableCell())
793        return 0;
794
795     pair<int, int> columnRange;
796     static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->columnIndexRange(columnRange);
797     return columnRange.first;
798 }
799
800 unsigned WebAccessibilityObject::cellColumnSpan() const
801 {
802     m_private->updateBackingStore();
803     if (!m_private->isTableCell())
804        return 0;
805
806     pair<int, int> columnRange;
807     static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->columnIndexRange(columnRange);
808     return columnRange.second;
809 }
810
811 unsigned WebAccessibilityObject::cellRowIndex() const
812 {
813     m_private->updateBackingStore();
814     if (!m_private->isTableCell())
815        return 0;
816
817     pair<int, int> rowRange;
818     static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->rowIndexRange(rowRange);
819     return rowRange.first;
820 }
821
822 unsigned WebAccessibilityObject::cellRowSpan() const
823 {
824     m_private->updateBackingStore();
825     if (!m_private->isTableCell())
826        return 0;
827
828     pair<int, int> rowRange;
829     static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->rowIndexRange(rowRange);
830     return rowRange.second;
831 }
832
833 WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
834     : m_private(object)
835 {
836 }
837
838 WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
839 {
840     m_private = object;
841     return *this;
842 }
843
844 WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const
845 {
846     return m_private.get();
847 }
848
849 } // namespace WebKit