- add third_party src.
[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 WebKit {
59
60 void WebAXObject::reset()
61 {
62     m_private.reset();
63 }
64
65 void WebAXObject::assign(const WebKit::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 bool WebAXObject::ariaHasPopup() const
418 {
419     if (isDetached())
420         return 0;
421
422     return m_private->ariaHasPopup();
423 }
424
425 bool WebAXObject::ariaLiveRegionAtomic() const
426 {
427     if (isDetached())
428         return 0;
429
430     return m_private->ariaLiveRegionAtomic();
431 }
432
433 bool WebAXObject::ariaLiveRegionBusy() const
434 {
435     if (isDetached())
436         return 0;
437
438     return m_private->ariaLiveRegionBusy();
439 }
440
441 WebString WebAXObject::ariaLiveRegionRelevant() const
442 {
443     if (isDetached())
444         return WebString();
445
446     return m_private->ariaLiveRegionRelevant();
447 }
448
449 WebString WebAXObject::ariaLiveRegionStatus() const
450 {
451     if (isDetached())
452         return WebString();
453
454     return m_private->ariaLiveRegionStatus();
455 }
456
457 WebRect WebAXObject::boundingBoxRect() const
458 {
459     if (isDetached())
460         return WebRect();
461
462     return pixelSnappedIntRect(m_private->elementRect());
463 }
464
465 bool WebAXObject::canvasHasFallbackContent() const
466 {
467     if (isDetached())
468         return false;
469
470     return m_private->canvasHasFallbackContent();
471 }
472
473 WebPoint WebAXObject::clickPoint() const
474 {
475     if (isDetached())
476         return WebPoint();
477
478     return WebPoint(m_private->clickPoint());
479 }
480
481 void WebAXObject::colorValue(int& r, int& g, int& b) const
482 {
483     if (isDetached())
484         return;
485
486     m_private->colorValue(r, g, b);
487 }
488
489 double WebAXObject::estimatedLoadingProgress() const
490 {
491     if (isDetached())
492         return 0.0;
493
494     return m_private->estimatedLoadingProgress();
495 }
496
497 WebString WebAXObject::helpText() const
498 {
499     if (isDetached())
500         return WebString();
501
502     return m_private->helpText();
503 }
504
505 int WebAXObject::headingLevel() const
506 {
507     if (isDetached())
508         return 0;
509
510     return m_private->headingLevel();
511 }
512
513 int WebAXObject::hierarchicalLevel() const
514 {
515     if (isDetached())
516         return 0;
517
518     return m_private->hierarchicalLevel();
519 }
520
521 WebAXObject WebAXObject::hitTest(const WebPoint& point) const
522 {
523     if (isDetached())
524         return WebAXObject();
525
526     IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
527     RefPtr<AXObject> hit = m_private->accessibilityHitTest(contentsPoint);
528
529     if (hit)
530         return WebAXObject(hit);
531
532     if (m_private->elementRect().contains(contentsPoint))
533         return *this;
534
535     return WebAXObject();
536 }
537
538 WebString WebAXObject::keyboardShortcut() const
539 {
540     if (isDetached())
541         return WebString();
542
543     String accessKey = m_private->accessKey();
544     if (accessKey.isNull())
545         return WebString();
546
547     DEFINE_STATIC_LOCAL(String, modifierString, ());
548     if (modifierString.isNull()) {
549         unsigned modifiers = EventHandler::accessKeyModifiers();
550         // Follow the same order as Mozilla MSAA implementation:
551         // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
552         // should not be localized and defines the separator as "+".
553         StringBuilder modifierStringBuilder;
554         if (modifiers & PlatformEvent::CtrlKey)
555             modifierStringBuilder.appendLiteral("Ctrl+");
556         if (modifiers & PlatformEvent::AltKey)
557             modifierStringBuilder.appendLiteral("Alt+");
558         if (modifiers & PlatformEvent::ShiftKey)
559             modifierStringBuilder.appendLiteral("Shift+");
560         if (modifiers & PlatformEvent::MetaKey)
561             modifierStringBuilder.appendLiteral("Win+");
562         modifierString = modifierStringBuilder.toString();
563     }
564
565     return String(modifierString + accessKey);
566 }
567
568 bool WebAXObject::performDefaultAction() const
569 {
570     if (isDetached())
571         return false;
572
573     return m_private->performDefaultAction();
574 }
575
576 bool WebAXObject::increment() const
577 {
578     if (isDetached())
579         return false;
580
581     if (canIncrement()) {
582         m_private->increment();
583         return true;
584     }
585     return false;
586 }
587
588 bool WebAXObject::decrement() const
589 {
590     if (isDetached())
591         return false;
592
593     if (canDecrement()) {
594         m_private->decrement();
595         return true;
596     }
597     return false;
598 }
599
600 bool WebAXObject::press() const
601 {
602     if (isDetached())
603         return false;
604
605     return m_private->press();
606 }
607
608 WebAXRole WebAXObject::role() const
609 {
610     if (isDetached())
611         return WebKit::WebAXRoleUnknown;
612
613     return static_cast<WebAXRole>(m_private->roleValue());
614 }
615
616 unsigned WebAXObject::selectionEnd() const
617 {
618     if (isDetached())
619         return 0;
620
621     return m_private->selectedTextRange().start + m_private->selectedTextRange().length;
622 }
623
624 unsigned WebAXObject::selectionStart() const
625 {
626     if (isDetached())
627         return 0;
628
629     return m_private->selectedTextRange().start;
630 }
631
632 unsigned WebAXObject::selectionEndLineNumber() const
633 {
634     if (isDetached())
635         return 0;
636
637     VisiblePosition position = m_private->visiblePositionForIndex(selectionEnd());
638     int lineNumber = m_private->lineForPosition(position);
639     if (lineNumber < 0)
640         return 0;
641     return lineNumber;
642 }
643
644 unsigned WebAXObject::selectionStartLineNumber() const
645 {
646     if (isDetached())
647         return 0;
648
649     VisiblePosition position = m_private->visiblePositionForIndex(selectionStart());
650     int lineNumber = m_private->lineForPosition(position);
651     if (lineNumber < 0)
652         return 0;
653     return lineNumber;
654 }
655
656 void WebAXObject::setFocused(bool on) const
657 {
658     if (!isDetached())
659         m_private->setFocused(on);
660 }
661
662 void WebAXObject::setSelectedTextRange(int selectionStart, int selectionEnd) const
663 {
664     if (isDetached())
665         return;
666
667     m_private->setSelectedTextRange(AXObject::PlainTextRange(selectionStart, selectionEnd - selectionStart));
668 }
669
670 WebString WebAXObject::stringValue() const
671 {
672     if (isDetached())
673         return WebString();
674
675     return m_private->stringValue();
676 }
677
678 WebString WebAXObject::title() const
679 {
680     if (isDetached())
681         return WebString();
682
683     return m_private->title();
684 }
685
686 WebAXObject WebAXObject::titleUIElement() const
687 {
688     if (isDetached())
689         return WebAXObject();
690
691     if (!m_private->exposesTitleUIElement())
692         return WebAXObject();
693
694     return WebAXObject(m_private->titleUIElement());
695 }
696
697 WebURL WebAXObject::url() const
698 {
699     if (isDetached())
700         return WebURL();
701
702     return m_private->url();
703 }
704
705 bool WebAXObject::supportsRangeValue() const
706 {
707     if (isDetached())
708         return false;
709
710     return m_private->supportsRangeValue();
711 }
712
713 WebString WebAXObject::valueDescription() const
714 {
715     if (isDetached())
716         return WebString();
717
718     return m_private->valueDescription();
719 }
720
721 float WebAXObject::valueForRange() const
722 {
723     if (isDetached())
724         return 0.0;
725
726     return m_private->valueForRange();
727 }
728
729 float WebAXObject::maxValueForRange() const
730 {
731     if (isDetached())
732         return 0.0;
733
734     return m_private->maxValueForRange();
735 }
736
737 float WebAXObject::minValueForRange() const
738 {
739     if (isDetached())
740         return 0.0;
741
742     return m_private->minValueForRange();
743 }
744
745 WebNode WebAXObject::node() const
746 {
747     if (isDetached())
748         return WebNode();
749
750     Node* node = m_private->node();
751     if (!node)
752         return WebNode();
753
754     return WebNode(node);
755 }
756
757 WebDocument WebAXObject::document() const
758 {
759     if (isDetached())
760         return WebDocument();
761
762     Document* document = m_private->document();
763     if (!document)
764         return WebDocument();
765
766     return WebDocument(document);
767 }
768
769 bool WebAXObject::hasComputedStyle() const
770 {
771     if (isDetached())
772         return false;
773
774     Document* document = m_private->document();
775     if (document)
776         document->updateStyleIfNeeded();
777
778     Node* node = m_private->node();
779     if (!node)
780         return false;
781
782     return node->computedStyle();
783 }
784
785 WebString WebAXObject::computedStyleDisplay() const
786 {
787     if (isDetached())
788         return WebString();
789
790     Document* document = m_private->document();
791     if (document)
792         document->updateStyleIfNeeded();
793
794     Node* node = m_private->node();
795     if (!node)
796         return WebString();
797
798     RenderStyle* renderStyle = node->computedStyle();
799     if (!renderStyle)
800         return WebString();
801
802     return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue());
803 }
804
805 bool WebAXObject::accessibilityIsIgnored() const
806 {
807     if (isDetached())
808         return false;
809
810     return m_private->accessibilityIsIgnored();
811 }
812
813 bool WebAXObject::lineBreaks(WebVector<int>& result) const
814 {
815     if (isDetached())
816         return false;
817
818     Vector<int> lineBreaksVector;
819     m_private->lineBreaks(lineBreaksVector);
820
821     size_t vectorSize = lineBreaksVector.size();
822     WebVector<int> lineBreaksWebVector(vectorSize);
823     for (size_t i = 0; i< vectorSize; i++)
824         lineBreaksWebVector[i] = lineBreaksVector[i];
825     result.swap(lineBreaksWebVector);
826
827     return true;
828 }
829
830 unsigned WebAXObject::columnCount() const
831 {
832     if (isDetached())
833         return false;
834
835     if (!m_private->isAXTable())
836         return 0;
837
838     return toAXTable(m_private.get())->columnCount();
839 }
840
841 unsigned WebAXObject::rowCount() const
842 {
843     if (isDetached())
844         return false;
845
846     if (!m_private->isAXTable())
847         return 0;
848
849     return toAXTable(m_private.get())->rowCount();
850 }
851
852 WebAXObject WebAXObject::cellForColumnAndRow(unsigned column, unsigned row) const
853 {
854     if (isDetached())
855         return WebAXObject();
856
857     if (!m_private->isAXTable())
858         return WebAXObject();
859
860     WebCore::AXTableCell* cell = toAXTable(m_private.get())->cellForColumnAndRow(column, row);
861     return WebAXObject(static_cast<WebCore::AXObject*>(cell));
862 }
863
864 WebAXObject WebAXObject::headerContainerObject() const
865 {
866     if (isDetached())
867         return WebAXObject();
868
869     if (!m_private->isAXTable())
870         return WebAXObject();
871
872     return WebAXObject(toAXTable(m_private.get())->headerContainer());
873 }
874
875 WebAXObject WebAXObject::rowAtIndex(unsigned rowIndex) const
876 {
877     if (isDetached())
878         return WebAXObject();
879
880     if (!m_private->isAXTable())
881         return WebAXObject();
882
883     const AXObject::AccessibilityChildrenVector& rows = toAXTable(m_private.get())->rows();
884     if (rowIndex < rows.size())
885         return WebAXObject(rows[rowIndex]);
886
887     return WebAXObject();
888 }
889
890 WebAXObject WebAXObject::columnAtIndex(unsigned columnIndex) const
891 {
892     if (isDetached())
893         return WebAXObject();
894
895     if (!m_private->isAXTable())
896         return WebAXObject();
897
898     const AXObject::AccessibilityChildrenVector& columns = toAXTable(m_private.get())->columns();
899     if (columnIndex < columns.size())
900         return WebAXObject(columns[columnIndex]);
901
902     return WebAXObject();
903 }
904
905 unsigned WebAXObject::rowIndex() const
906 {
907     if (isDetached())
908         return 0;
909
910     if (!m_private->isTableRow())
911         return 0;
912
913     return WebCore::toAXTableRow(m_private.get())->rowIndex();
914 }
915
916 WebAXObject WebAXObject::rowHeader() const
917 {
918     if (isDetached())
919         return WebAXObject();
920
921     if (!m_private->isTableRow())
922         return WebAXObject();
923
924     return WebAXObject(WebCore::toAXTableRow(m_private.get())->headerObject());
925 }
926
927 unsigned WebAXObject::columnIndex() const
928 {
929     if (isDetached())
930         return 0;
931
932     if (m_private->roleValue() != ColumnRole)
933         return 0;
934
935     return WebCore::toAXTableColumn(m_private.get())->columnIndex();
936 }
937
938 WebAXObject WebAXObject::columnHeader() const
939 {
940     if (isDetached())
941         return WebAXObject();
942
943     if (m_private->roleValue() != ColumnRole)
944         return WebAXObject();
945
946     return WebAXObject(WebCore::toAXTableColumn(m_private.get())->headerObject());
947 }
948
949 unsigned WebAXObject::cellColumnIndex() const
950 {
951     if (isDetached())
952         return 0;
953
954     if (!m_private->isTableCell())
955         return 0;
956
957     pair<unsigned, unsigned> columnRange;
958     WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange);
959     return columnRange.first;
960 }
961
962 unsigned WebAXObject::cellColumnSpan() const
963 {
964     if (isDetached())
965         return 0;
966
967     if (!m_private->isTableCell())
968         return 0;
969
970     pair<unsigned, unsigned> columnRange;
971     WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange);
972     return columnRange.second;
973 }
974
975 unsigned WebAXObject::cellRowIndex() const
976 {
977     if (isDetached())
978         return 0;
979
980     if (!m_private->isTableCell())
981         return 0;
982
983     pair<unsigned, unsigned> rowRange;
984     WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange);
985     return rowRange.first;
986 }
987
988 unsigned WebAXObject::cellRowSpan() const
989 {
990     if (isDetached())
991         return 0;
992
993     if (!m_private->isTableCell())
994         return 0;
995
996     pair<unsigned, unsigned> rowRange;
997     WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange);
998     return rowRange.second;
999 }
1000
1001 WebAXTextDirection WebAXObject::textDirection() const
1002 {
1003     if (isDetached())
1004         return WebAXTextDirectionLR;
1005
1006     return static_cast<WebAXTextDirection>(m_private->textDirection());
1007 }
1008
1009 void WebAXObject::characterOffsets(WebVector<int>& offsets) const
1010 {
1011     if (isDetached())
1012         return;
1013
1014     Vector<int> offsetsVector;
1015     m_private->textCharacterOffsets(offsetsVector);
1016
1017     size_t vectorSize = offsetsVector.size();
1018     WebVector<int> offsetsWebVector(vectorSize);
1019     for (size_t i = 0; i < vectorSize; i++)
1020         offsetsWebVector[i] = offsetsVector[i];
1021     offsets.swap(offsetsWebVector);
1022 }
1023
1024 void WebAXObject::wordBoundaries(WebVector<int>& starts, WebVector<int>& ends) const
1025 {
1026     if (isDetached())
1027         return;
1028
1029     Vector<AXObject::PlainTextRange> words;
1030     m_private->wordBoundaries(words);
1031
1032     WebVector<int> startsWebVector(words.size());
1033     WebVector<int> endsWebVector(words.size());
1034     for (size_t i = 0; i < words.size(); i++) {
1035         startsWebVector[i] = words[i].start;
1036         endsWebVector[i] = words[i].start + words[i].length;
1037     }
1038     starts.swap(startsWebVector);
1039     ends.swap(endsWebVector);
1040 }
1041
1042 void WebAXObject::scrollToMakeVisible() const
1043 {
1044     if (!isDetached())
1045         m_private->scrollToMakeVisible();
1046 }
1047
1048 void WebAXObject::scrollToMakeVisibleWithSubFocus(const WebRect& subfocus) const
1049 {
1050     if (!isDetached())
1051         m_private->scrollToMakeVisibleWithSubFocus(subfocus);
1052 }
1053
1054 void WebAXObject::scrollToGlobalPoint(const WebPoint& point) const
1055 {
1056     if (!isDetached())
1057         m_private->scrollToGlobalPoint(point);
1058 }
1059
1060 WebAXObject::WebAXObject(const WTF::PassRefPtr<WebCore::AXObject>& object)
1061     : m_private(object)
1062 {
1063 }
1064
1065 WebAXObject& WebAXObject::operator=(const WTF::PassRefPtr<WebCore::AXObject>& object)
1066 {
1067     m_private = object;
1068     return *this;
1069 }
1070
1071 WebAXObject::operator WTF::PassRefPtr<WebCore::AXObject>() const
1072 {
1073     return m_private.get();
1074 }
1075
1076 } // namespace WebKit