Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / WebAXObject.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 "WebAXObject.h"
33
34 #include "HTMLNames.h"
35 #include "WebDocument.h"
36 #include "WebNode.h"
37 #include "core/accessibility/AXObject.h"
38 #include "core/accessibility/AXObjectCache.h"
39 #include "core/accessibility/AXTable.h"
40 #include "core/accessibility/AXTableCell.h"
41 #include "core/accessibility/AXTableColumn.h"
42 #include "core/accessibility/AXTableRow.h"
43 #include "core/css/CSSPrimitiveValueMappings.h"
44 #include "core/dom/Document.h"
45 #include "core/dom/Node.h"
46 #include "core/page/EventHandler.h"
47 #include "core/frame/FrameView.h"
48 #include "core/rendering/style/RenderStyle.h"
49 #include "platform/PlatformKeyboardEvent.h"
50 #include "public/platform/WebPoint.h"
51 #include "public/platform/WebRect.h"
52 #include "public/platform/WebString.h"
53 #include "public/platform/WebURL.h"
54 #include "wtf/text/StringBuilder.h"
55
56 using namespace WebCore;
57
58 namespace blink {
59
60 void WebAXObject::reset()
61 {
62     m_private.reset();
63 }
64
65 void WebAXObject::assign(const blink::WebAXObject& other)
66 {
67     m_private = other.m_private;
68 }
69
70 bool WebAXObject::equals(const WebAXObject& n) const
71 {
72     return m_private.get() == n.m_private.get();
73 }
74
75 // static
76 void WebAXObject::enableAccessibility()
77 {
78     AXObjectCache::enableAccessibility();
79 }
80
81 // static
82 bool WebAXObject::accessibilityEnabled()
83 {
84     return AXObjectCache::accessibilityEnabled();
85 }
86
87 // static
88 void WebAXObject::enableInlineTextBoxAccessibility()
89 {
90     AXObjectCache::setInlineTextBoxAccessibility(true);
91 }
92
93 void WebAXObject::startCachingComputedObjectAttributesUntilTreeMutates()
94 {
95     m_private->axObjectCache()->startCachingComputedObjectAttributesUntilTreeMutates();
96 }
97
98 void WebAXObject::stopCachingComputedObjectAttributes()
99 {
100     m_private->axObjectCache()->stopCachingComputedObjectAttributes();
101 }
102
103 bool WebAXObject::isDetached() const
104 {
105     if (m_private.isNull())
106         return true;
107
108     return m_private->isDetached();
109 }
110
111 int WebAXObject::axID() const
112 {
113     if (isDetached())
114         return -1;
115
116     return m_private->axObjectID();
117 }
118
119 bool WebAXObject::updateBackingStoreAndCheckValidity()
120 {
121     if (!isDetached())
122         m_private->updateBackingStore();
123     return !isDetached();
124 }
125
126 WebString WebAXObject::accessibilityDescription() const
127 {
128     if (isDetached())
129         return WebString();
130
131     return m_private->accessibilityDescription();
132 }
133
134 WebString WebAXObject::actionVerb() const
135 {
136     if (isDetached())
137         return WebString();
138
139     return m_private->actionVerb();
140 }
141
142 bool WebAXObject::canDecrement() const
143 {
144     if (isDetached())
145         return false;
146
147     return m_private->isSlider();
148 }
149
150 bool WebAXObject::canIncrement() const
151 {
152     if (isDetached())
153         return false;
154
155     return m_private->isSlider();
156 }
157
158 bool WebAXObject::canPress() const
159 {
160     if (isDetached())
161         return false;
162
163     return m_private->actionElement() || m_private->isButton() || m_private->isMenuRelated();
164 }
165
166 bool WebAXObject::canSetFocusAttribute() const
167 {
168     if (isDetached())
169         return false;
170
171     return m_private->canSetFocusAttribute();
172 }
173
174 bool WebAXObject::canSetValueAttribute() const
175 {
176     if (isDetached())
177         return false;
178
179     return m_private->canSetValueAttribute();
180 }
181
182 unsigned WebAXObject::childCount() const
183 {
184     if (isDetached())
185         return 0;
186
187     return m_private->children().size();
188 }
189
190 WebAXObject WebAXObject::childAt(unsigned index) const
191 {
192     if (isDetached())
193         return WebAXObject();
194
195     if (m_private->children().size() <= index)
196         return WebAXObject();
197
198     return WebAXObject(m_private->children()[index]);
199 }
200
201 WebAXObject WebAXObject::parentObject() const
202 {
203     if (isDetached())
204         return WebAXObject();
205
206     return WebAXObject(m_private->parentObject());
207 }
208
209 bool WebAXObject::canSetSelectedAttribute() const
210 {
211     if (isDetached())
212         return 0;
213
214     return m_private->canSetSelectedAttribute();
215 }
216
217 bool WebAXObject::isAnchor() const
218 {
219     if (isDetached())
220         return 0;
221
222     return m_private->isAnchor();
223 }
224
225 bool WebAXObject::isAriaReadOnly() const
226 {
227     if (isDetached())
228         return 0;
229
230     return equalIgnoringCase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true");
231 }
232
233 bool WebAXObject::isButtonStateMixed() const
234 {
235     if (isDetached())
236         return 0;
237
238     return m_private->checkboxOrRadioValue() == ButtonStateMixed;
239 }
240
241 bool WebAXObject::isChecked() const
242 {
243     if (isDetached())
244         return 0;
245
246     return m_private->isChecked();
247 }
248
249 bool WebAXObject::isClickable() const
250 {
251     if (isDetached())
252         return 0;
253
254     return m_private->isClickable();
255 }
256
257 bool WebAXObject::isCollapsed() const
258 {
259     if (isDetached())
260         return 0;
261
262     return m_private->isCollapsed();
263 }
264
265 bool WebAXObject::isControl() const
266 {
267     if (isDetached())
268         return 0;
269
270     return m_private->isControl();
271 }
272
273 bool WebAXObject::isEnabled() const
274 {
275     if (isDetached())
276         return 0;
277
278     return m_private->isEnabled();
279 }
280
281 bool WebAXObject::isFocused() const
282 {
283     if (isDetached())
284         return 0;
285
286     return m_private->isFocused();
287 }
288
289 bool WebAXObject::isHovered() const
290 {
291     if (isDetached())
292         return 0;
293
294     return m_private->isHovered();
295 }
296
297 bool WebAXObject::isIndeterminate() const
298 {
299     if (isDetached())
300         return 0;
301
302     return m_private->isIndeterminate();
303 }
304
305 bool WebAXObject::isLinked() const
306 {
307     if (isDetached())
308         return 0;
309
310     return m_private->isLinked();
311 }
312
313 bool WebAXObject::isLoaded() const
314 {
315     if (isDetached())
316         return 0;
317
318     return m_private->isLoaded();
319 }
320
321 bool WebAXObject::isMultiSelectable() const
322 {
323     if (isDetached())
324         return 0;
325
326     return m_private->isMultiSelectable();
327 }
328
329 bool WebAXObject::isOffScreen() const
330 {
331     if (isDetached())
332         return 0;
333
334     return m_private->isOffScreen();
335 }
336
337 bool WebAXObject::isPasswordField() const
338 {
339     if (isDetached())
340         return 0;
341
342     return m_private->isPasswordField();
343 }
344
345 bool WebAXObject::isPressed() const
346 {
347     if (isDetached())
348         return 0;
349
350     return m_private->isPressed();
351 }
352
353 bool WebAXObject::isReadOnly() const
354 {
355     if (isDetached())
356         return 0;
357
358     return m_private->isReadOnly();
359 }
360
361 bool WebAXObject::isRequired() const
362 {
363     if (isDetached())
364         return 0;
365
366     return m_private->isRequired();
367 }
368
369 bool WebAXObject::isSelected() const
370 {
371     if (isDetached())
372         return 0;
373
374     return m_private->isSelected();
375 }
376
377 bool WebAXObject::isSelectedOptionActive() const
378 {
379     if (isDetached())
380         return false;
381
382     return m_private->isSelectedOptionActive();
383 }
384
385 bool WebAXObject::isVertical() const
386 {
387     if (isDetached())
388         return 0;
389
390     return m_private->orientation() == AccessibilityOrientationVertical;
391 }
392
393 bool WebAXObject::isVisible() const
394 {
395     if (isDetached())
396         return 0;
397
398     return m_private->isVisible();
399 }
400
401 bool WebAXObject::isVisited() const
402 {
403     if (isDetached())
404         return 0;
405
406     return m_private->isVisited();
407 }
408
409 WebString WebAXObject::accessKey() const
410 {
411     if (isDetached())
412         return WebString();
413
414     return WebString(m_private->accessKey());
415 }
416
417 WebAXObject WebAXObject::ariaActiveDescendant() const
418 {
419     if (isDetached())
420         return WebAXObject();
421
422     return WebAXObject(m_private->activeDescendant());
423 }
424
425 bool WebAXObject::ariaControls(WebVector<WebAXObject>& controlsElements) const
426 {
427     if (isDetached())
428         return false;
429
430     AXObject::AccessibilityChildrenVector controls;
431     m_private->ariaControlsElements(controls);
432
433     WebVector<WebAXObject> result(controls.size());
434     for (size_t i = 0; i < controls.size(); i++)
435         result[i] = WebAXObject(controls[i]);
436     controlsElements.swap(result);
437
438     return true;
439 }
440
441 bool WebAXObject::ariaDescribedby(WebVector<WebAXObject>& describedbyElements) const
442 {
443     if (isDetached())
444         return false;
445
446     AXObject::AccessibilityChildrenVector describedby;
447     m_private->ariaDescribedbyElements(describedby);
448
449     WebVector<WebAXObject> result(describedby.size());
450     for (size_t i = 0; i < describedby.size(); i++)
451         result[i] = WebAXObject(describedby[i]);
452     describedbyElements.swap(result);
453
454     return true;
455 }
456
457 bool WebAXObject::ariaHasPopup() const
458 {
459     if (isDetached())
460         return 0;
461
462     return m_private->ariaHasPopup();
463 }
464
465 bool WebAXObject::ariaFlowTo(WebVector<WebAXObject>& flowToElements) const
466 {
467     if (isDetached())
468         return false;
469
470     AXObject::AccessibilityChildrenVector flowTo;
471     m_private->ariaFlowToElements(flowTo);
472
473     WebVector<WebAXObject> result(flowTo.size());
474     for (size_t i = 0; i < flowTo.size(); i++)
475         result[i] = WebAXObject(flowTo[i]);
476     flowToElements.swap(result);
477
478     return true;
479 }
480
481 bool WebAXObject::ariaLabelledby(WebVector<WebAXObject>& labelledbyElements) const
482 {
483     if (isDetached())
484         return false;
485
486     AXObject::AccessibilityChildrenVector labelledby;
487     m_private->ariaLabelledbyElements(labelledby);
488
489     WebVector<WebAXObject> result(labelledby.size());
490     for (size_t i = 0; i < labelledby.size(); i++)
491         result[i] = WebAXObject(labelledby[i]);
492     labelledbyElements.swap(result);
493
494     return true;
495 }
496
497 bool WebAXObject::ariaLiveRegionAtomic() const
498 {
499     if (isDetached())
500         return 0;
501
502     return m_private->ariaLiveRegionAtomic();
503 }
504
505 bool WebAXObject::ariaLiveRegionBusy() const
506 {
507     if (isDetached())
508         return 0;
509
510     return m_private->ariaLiveRegionBusy();
511 }
512
513 WebString WebAXObject::ariaLiveRegionRelevant() const
514 {
515     if (isDetached())
516         return WebString();
517
518     return m_private->ariaLiveRegionRelevant();
519 }
520
521 WebString WebAXObject::ariaLiveRegionStatus() const
522 {
523     if (isDetached())
524         return WebString();
525
526     return m_private->ariaLiveRegionStatus();
527 }
528
529 bool WebAXObject::ariaOwns(WebVector<WebAXObject>& ownsElements) const
530 {
531     if (isDetached())
532         return false;
533
534     AXObject::AccessibilityChildrenVector owns;
535     m_private->ariaOwnsElements(owns);
536
537     WebVector<WebAXObject> result(owns.size());
538     for (size_t i = 0; i < owns.size(); i++)
539         result[i] = WebAXObject(owns[i]);
540     ownsElements.swap(result);
541
542     return true;
543 }
544
545 WebRect WebAXObject::boundingBoxRect() const
546 {
547     if (isDetached())
548         return WebRect();
549
550     return pixelSnappedIntRect(m_private->elementRect());
551 }
552
553 bool WebAXObject::canvasHasFallbackContent() const
554 {
555     if (isDetached())
556         return false;
557
558     return m_private->canvasHasFallbackContent();
559 }
560
561 WebPoint WebAXObject::clickPoint() const
562 {
563     if (isDetached())
564         return WebPoint();
565
566     return WebPoint(m_private->clickPoint());
567 }
568
569 void WebAXObject::colorValue(int& r, int& g, int& b) const
570 {
571     if (isDetached())
572         return;
573
574     m_private->colorValue(r, g, b);
575 }
576
577 double WebAXObject::estimatedLoadingProgress() const
578 {
579     if (isDetached())
580         return 0.0;
581
582     return m_private->estimatedLoadingProgress();
583 }
584
585 WebString WebAXObject::helpText() const
586 {
587     if (isDetached())
588         return WebString();
589
590     return m_private->helpText();
591 }
592
593 int WebAXObject::headingLevel() const
594 {
595     if (isDetached())
596         return 0;
597
598     return m_private->headingLevel();
599 }
600
601 int WebAXObject::hierarchicalLevel() const
602 {
603     if (isDetached())
604         return 0;
605
606     return m_private->hierarchicalLevel();
607 }
608
609 WebAXObject WebAXObject::hitTest(const WebPoint& point) const
610 {
611     if (isDetached())
612         return WebAXObject();
613
614     IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
615     RefPtr<AXObject> hit = m_private->accessibilityHitTest(contentsPoint);
616
617     if (hit)
618         return WebAXObject(hit);
619
620     if (m_private->elementRect().contains(contentsPoint))
621         return *this;
622
623     return WebAXObject();
624 }
625
626 WebString WebAXObject::keyboardShortcut() const
627 {
628     if (isDetached())
629         return WebString();
630
631     String accessKey = m_private->accessKey();
632     if (accessKey.isNull())
633         return WebString();
634
635     DEFINE_STATIC_LOCAL(String, modifierString, ());
636     if (modifierString.isNull()) {
637         unsigned modifiers = EventHandler::accessKeyModifiers();
638         // Follow the same order as Mozilla MSAA implementation:
639         // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
640         // should not be localized and defines the separator as "+".
641         StringBuilder modifierStringBuilder;
642         if (modifiers & PlatformEvent::CtrlKey)
643             modifierStringBuilder.appendLiteral("Ctrl+");
644         if (modifiers & PlatformEvent::AltKey)
645             modifierStringBuilder.appendLiteral("Alt+");
646         if (modifiers & PlatformEvent::ShiftKey)
647             modifierStringBuilder.appendLiteral("Shift+");
648         if (modifiers & PlatformEvent::MetaKey)
649             modifierStringBuilder.appendLiteral("Win+");
650         modifierString = modifierStringBuilder.toString();
651     }
652
653     return String(modifierString + accessKey);
654 }
655
656 bool WebAXObject::performDefaultAction() const
657 {
658     if (isDetached())
659         return false;
660
661     return m_private->performDefaultAction();
662 }
663
664 bool WebAXObject::increment() const
665 {
666     if (isDetached())
667         return false;
668
669     if (canIncrement()) {
670         m_private->increment();
671         return true;
672     }
673     return false;
674 }
675
676 bool WebAXObject::decrement() const
677 {
678     if (isDetached())
679         return false;
680
681     if (canDecrement()) {
682         m_private->decrement();
683         return true;
684     }
685     return false;
686 }
687
688 bool WebAXObject::press() const
689 {
690     if (isDetached())
691         return false;
692
693     return m_private->press();
694 }
695
696 WebAXRole WebAXObject::role() const
697 {
698     if (isDetached())
699         return blink::WebAXRoleUnknown;
700
701     return static_cast<WebAXRole>(m_private->roleValue());
702 }
703
704 unsigned WebAXObject::selectionEnd() const
705 {
706     if (isDetached())
707         return 0;
708
709     return m_private->selectedTextRange().start + m_private->selectedTextRange().length;
710 }
711
712 unsigned WebAXObject::selectionStart() const
713 {
714     if (isDetached())
715         return 0;
716
717     return m_private->selectedTextRange().start;
718 }
719
720 unsigned WebAXObject::selectionEndLineNumber() const
721 {
722     if (isDetached())
723         return 0;
724
725     VisiblePosition position = m_private->visiblePositionForIndex(selectionEnd());
726     int lineNumber = m_private->lineForPosition(position);
727     if (lineNumber < 0)
728         return 0;
729     return lineNumber;
730 }
731
732 unsigned WebAXObject::selectionStartLineNumber() const
733 {
734     if (isDetached())
735         return 0;
736
737     VisiblePosition position = m_private->visiblePositionForIndex(selectionStart());
738     int lineNumber = m_private->lineForPosition(position);
739     if (lineNumber < 0)
740         return 0;
741     return lineNumber;
742 }
743
744 void WebAXObject::setFocused(bool on) const
745 {
746     if (!isDetached())
747         m_private->setFocused(on);
748 }
749
750 void WebAXObject::setSelectedTextRange(int selectionStart, int selectionEnd) const
751 {
752     if (isDetached())
753         return;
754
755     m_private->setSelectedTextRange(AXObject::PlainTextRange(selectionStart, selectionEnd - selectionStart));
756 }
757
758 WebString WebAXObject::stringValue() const
759 {
760     if (isDetached())
761         return WebString();
762
763     return m_private->stringValue();
764 }
765
766 WebString WebAXObject::title() const
767 {
768     if (isDetached())
769         return WebString();
770
771     return m_private->title();
772 }
773
774 WebAXObject WebAXObject::titleUIElement() const
775 {
776     if (isDetached())
777         return WebAXObject();
778
779     if (!m_private->exposesTitleUIElement())
780         return WebAXObject();
781
782     return WebAXObject(m_private->titleUIElement());
783 }
784
785 WebURL WebAXObject::url() const
786 {
787     if (isDetached())
788         return WebURL();
789
790     return m_private->url();
791 }
792
793 bool WebAXObject::supportsRangeValue() const
794 {
795     if (isDetached())
796         return false;
797
798     return m_private->supportsRangeValue();
799 }
800
801 WebString WebAXObject::valueDescription() const
802 {
803     if (isDetached())
804         return WebString();
805
806     return m_private->valueDescription();
807 }
808
809 float WebAXObject::valueForRange() const
810 {
811     if (isDetached())
812         return 0.0;
813
814     return m_private->valueForRange();
815 }
816
817 float WebAXObject::maxValueForRange() const
818 {
819     if (isDetached())
820         return 0.0;
821
822     return m_private->maxValueForRange();
823 }
824
825 float WebAXObject::minValueForRange() const
826 {
827     if (isDetached())
828         return 0.0;
829
830     return m_private->minValueForRange();
831 }
832
833 WebNode WebAXObject::node() const
834 {
835     if (isDetached())
836         return WebNode();
837
838     Node* node = m_private->node();
839     if (!node)
840         return WebNode();
841
842     return WebNode(node);
843 }
844
845 WebDocument WebAXObject::document() const
846 {
847     if (isDetached())
848         return WebDocument();
849
850     Document* document = m_private->document();
851     if (!document)
852         return WebDocument();
853
854     return WebDocument(document);
855 }
856
857 bool WebAXObject::hasComputedStyle() const
858 {
859     if (isDetached())
860         return false;
861
862     Document* document = m_private->document();
863     if (document)
864         document->updateRenderTreeIfNeeded();
865
866     Node* node = m_private->node();
867     if (!node)
868         return false;
869
870     return node->computedStyle();
871 }
872
873 WebString WebAXObject::computedStyleDisplay() const
874 {
875     if (isDetached())
876         return WebString();
877
878     Document* document = m_private->document();
879     if (document)
880         document->updateRenderTreeIfNeeded();
881
882     Node* node = m_private->node();
883     if (!node)
884         return WebString();
885
886     RenderStyle* renderStyle = node->computedStyle();
887     if (!renderStyle)
888         return WebString();
889
890     return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue());
891 }
892
893 bool WebAXObject::accessibilityIsIgnored() const
894 {
895     if (isDetached())
896         return false;
897
898     return m_private->accessibilityIsIgnored();
899 }
900
901 bool WebAXObject::lineBreaks(WebVector<int>& result) const
902 {
903     if (isDetached())
904         return false;
905
906     Vector<int> lineBreaksVector;
907     m_private->lineBreaks(lineBreaksVector);
908
909     size_t vectorSize = lineBreaksVector.size();
910     WebVector<int> lineBreaksWebVector(vectorSize);
911     for (size_t i = 0; i< vectorSize; i++)
912         lineBreaksWebVector[i] = lineBreaksVector[i];
913     result.swap(lineBreaksWebVector);
914
915     return true;
916 }
917
918 unsigned WebAXObject::columnCount() const
919 {
920     if (isDetached())
921         return false;
922
923     if (!m_private->isAXTable())
924         return 0;
925
926     return toAXTable(m_private.get())->columnCount();
927 }
928
929 unsigned WebAXObject::rowCount() const
930 {
931     if (isDetached())
932         return false;
933
934     if (!m_private->isAXTable())
935         return 0;
936
937     return toAXTable(m_private.get())->rowCount();
938 }
939
940 WebAXObject WebAXObject::cellForColumnAndRow(unsigned column, unsigned row) const
941 {
942     if (isDetached())
943         return WebAXObject();
944
945     if (!m_private->isAXTable())
946         return WebAXObject();
947
948     WebCore::AXTableCell* cell = toAXTable(m_private.get())->cellForColumnAndRow(column, row);
949     return WebAXObject(static_cast<WebCore::AXObject*>(cell));
950 }
951
952 WebAXObject WebAXObject::headerContainerObject() const
953 {
954     if (isDetached())
955         return WebAXObject();
956
957     if (!m_private->isAXTable())
958         return WebAXObject();
959
960     return WebAXObject(toAXTable(m_private.get())->headerContainer());
961 }
962
963 WebAXObject WebAXObject::rowAtIndex(unsigned rowIndex) const
964 {
965     if (isDetached())
966         return WebAXObject();
967
968     if (!m_private->isAXTable())
969         return WebAXObject();
970
971     const AXObject::AccessibilityChildrenVector& rows = toAXTable(m_private.get())->rows();
972     if (rowIndex < rows.size())
973         return WebAXObject(rows[rowIndex]);
974
975     return WebAXObject();
976 }
977
978 WebAXObject WebAXObject::columnAtIndex(unsigned columnIndex) const
979 {
980     if (isDetached())
981         return WebAXObject();
982
983     if (!m_private->isAXTable())
984         return WebAXObject();
985
986     const AXObject::AccessibilityChildrenVector& columns = toAXTable(m_private.get())->columns();
987     if (columnIndex < columns.size())
988         return WebAXObject(columns[columnIndex]);
989
990     return WebAXObject();
991 }
992
993 unsigned WebAXObject::rowIndex() const
994 {
995     if (isDetached())
996         return 0;
997
998     if (!m_private->isTableRow())
999         return 0;
1000
1001     return WebCore::toAXTableRow(m_private.get())->rowIndex();
1002 }
1003
1004 WebAXObject WebAXObject::rowHeader() const
1005 {
1006     if (isDetached())
1007         return WebAXObject();
1008
1009     if (!m_private->isTableRow())
1010         return WebAXObject();
1011
1012     return WebAXObject(WebCore::toAXTableRow(m_private.get())->headerObject());
1013 }
1014
1015 unsigned WebAXObject::columnIndex() const
1016 {
1017     if (isDetached())
1018         return 0;
1019
1020     if (m_private->roleValue() != ColumnRole)
1021         return 0;
1022
1023     return WebCore::toAXTableColumn(m_private.get())->columnIndex();
1024 }
1025
1026 WebAXObject WebAXObject::columnHeader() const
1027 {
1028     if (isDetached())
1029         return WebAXObject();
1030
1031     if (m_private->roleValue() != ColumnRole)
1032         return WebAXObject();
1033
1034     return WebAXObject(WebCore::toAXTableColumn(m_private.get())->headerObject());
1035 }
1036
1037 unsigned WebAXObject::cellColumnIndex() const
1038 {
1039     if (isDetached())
1040         return 0;
1041
1042     if (!m_private->isTableCell())
1043         return 0;
1044
1045     pair<unsigned, unsigned> columnRange;
1046     WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange);
1047     return columnRange.first;
1048 }
1049
1050 unsigned WebAXObject::cellColumnSpan() const
1051 {
1052     if (isDetached())
1053         return 0;
1054
1055     if (!m_private->isTableCell())
1056         return 0;
1057
1058     pair<unsigned, unsigned> columnRange;
1059     WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange);
1060     return columnRange.second;
1061 }
1062
1063 unsigned WebAXObject::cellRowIndex() const
1064 {
1065     if (isDetached())
1066         return 0;
1067
1068     if (!m_private->isTableCell())
1069         return 0;
1070
1071     pair<unsigned, unsigned> rowRange;
1072     WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange);
1073     return rowRange.first;
1074 }
1075
1076 unsigned WebAXObject::cellRowSpan() const
1077 {
1078     if (isDetached())
1079         return 0;
1080
1081     if (!m_private->isTableCell())
1082         return 0;
1083
1084     pair<unsigned, unsigned> rowRange;
1085     WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange);
1086     return rowRange.second;
1087 }
1088
1089 WebAXTextDirection WebAXObject::textDirection() const
1090 {
1091     if (isDetached())
1092         return WebAXTextDirectionLR;
1093
1094     return static_cast<WebAXTextDirection>(m_private->textDirection());
1095 }
1096
1097 void WebAXObject::characterOffsets(WebVector<int>& offsets) const
1098 {
1099     if (isDetached())
1100         return;
1101
1102     Vector<int> offsetsVector;
1103     m_private->textCharacterOffsets(offsetsVector);
1104
1105     size_t vectorSize = offsetsVector.size();
1106     WebVector<int> offsetsWebVector(vectorSize);
1107     for (size_t i = 0; i < vectorSize; i++)
1108         offsetsWebVector[i] = offsetsVector[i];
1109     offsets.swap(offsetsWebVector);
1110 }
1111
1112 void WebAXObject::wordBoundaries(WebVector<int>& starts, WebVector<int>& ends) const
1113 {
1114     if (isDetached())
1115         return;
1116
1117     Vector<AXObject::PlainTextRange> words;
1118     m_private->wordBoundaries(words);
1119
1120     WebVector<int> startsWebVector(words.size());
1121     WebVector<int> endsWebVector(words.size());
1122     for (size_t i = 0; i < words.size(); i++) {
1123         startsWebVector[i] = words[i].start;
1124         endsWebVector[i] = words[i].start + words[i].length;
1125     }
1126     starts.swap(startsWebVector);
1127     ends.swap(endsWebVector);
1128 }
1129
1130 void WebAXObject::scrollToMakeVisible() const
1131 {
1132     if (!isDetached())
1133         m_private->scrollToMakeVisible();
1134 }
1135
1136 void WebAXObject::scrollToMakeVisibleWithSubFocus(const WebRect& subfocus) const
1137 {
1138     if (!isDetached())
1139         m_private->scrollToMakeVisibleWithSubFocus(subfocus);
1140 }
1141
1142 void WebAXObject::scrollToGlobalPoint(const WebPoint& point) const
1143 {
1144     if (!isDetached())
1145         m_private->scrollToGlobalPoint(point);
1146 }
1147
1148 WebAXObject::WebAXObject(const WTF::PassRefPtr<WebCore::AXObject>& object)
1149     : m_private(object)
1150 {
1151 }
1152
1153 WebAXObject& WebAXObject::operator=(const WTF::PassRefPtr<WebCore::AXObject>& object)
1154 {
1155     m_private = object;
1156     return *this;
1157 }
1158
1159 WebAXObject::operator WTF::PassRefPtr<WebCore::AXObject>() const
1160 {
1161     return m_private.get();
1162 }
1163
1164 } // namespace blink