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
reset()60 void WebAXObject::reset()
61 {
62 m_private.reset();
63 }
64
assign(const blink::WebAXObject & other)65 void WebAXObject::assign(const blink::WebAXObject& other)
66 {
67 m_private = other.m_private;
68 }
69
equals(const WebAXObject & n) const70 bool WebAXObject::equals(const WebAXObject& n) const
71 {
72 return m_private.get() == n.m_private.get();
73 }
74
75 // static
enableAccessibility()76 void WebAXObject::enableAccessibility()
77 {
78 AXObjectCache::enableAccessibility();
79 }
80
81 // static
accessibilityEnabled()82 bool WebAXObject::accessibilityEnabled()
83 {
84 return AXObjectCache::accessibilityEnabled();
85 }
86
87 // static
enableInlineTextBoxAccessibility()88 void WebAXObject::enableInlineTextBoxAccessibility()
89 {
90 AXObjectCache::setInlineTextBoxAccessibility(true);
91 }
92
startCachingComputedObjectAttributesUntilTreeMutates()93 void WebAXObject::startCachingComputedObjectAttributesUntilTreeMutates()
94 {
95 m_private->axObjectCache()->startCachingComputedObjectAttributesUntilTreeMutates();
96 }
97
stopCachingComputedObjectAttributes()98 void WebAXObject::stopCachingComputedObjectAttributes()
99 {
100 m_private->axObjectCache()->stopCachingComputedObjectAttributes();
101 }
102
isDetached() const103 bool WebAXObject::isDetached() const
104 {
105 if (m_private.isNull())
106 return true;
107
108 return m_private->isDetached();
109 }
110
axID() const111 int WebAXObject::axID() const
112 {
113 if (isDetached())
114 return -1;
115
116 return m_private->axObjectID();
117 }
118
updateBackingStoreAndCheckValidity()119 bool WebAXObject::updateBackingStoreAndCheckValidity()
120 {
121 if (!isDetached())
122 m_private->updateBackingStore();
123 return !isDetached();
124 }
125
accessibilityDescription() const126 WebString WebAXObject::accessibilityDescription() const
127 {
128 if (isDetached())
129 return WebString();
130
131 return m_private->accessibilityDescription();
132 }
133
actionVerb() const134 WebString WebAXObject::actionVerb() const
135 {
136 if (isDetached())
137 return WebString();
138
139 return m_private->actionVerb();
140 }
141
canDecrement() const142 bool WebAXObject::canDecrement() const
143 {
144 if (isDetached())
145 return false;
146
147 return m_private->isSlider();
148 }
149
canIncrement() const150 bool WebAXObject::canIncrement() const
151 {
152 if (isDetached())
153 return false;
154
155 return m_private->isSlider();
156 }
157
canPress() const158 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
canSetFocusAttribute() const166 bool WebAXObject::canSetFocusAttribute() const
167 {
168 if (isDetached())
169 return false;
170
171 return m_private->canSetFocusAttribute();
172 }
173
canSetValueAttribute() const174 bool WebAXObject::canSetValueAttribute() const
175 {
176 if (isDetached())
177 return false;
178
179 return m_private->canSetValueAttribute();
180 }
181
childCount() const182 unsigned WebAXObject::childCount() const
183 {
184 if (isDetached())
185 return 0;
186
187 return m_private->children().size();
188 }
189
childAt(unsigned index) const190 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
parentObject() const201 WebAXObject WebAXObject::parentObject() const
202 {
203 if (isDetached())
204 return WebAXObject();
205
206 return WebAXObject(m_private->parentObject());
207 }
208
canSetSelectedAttribute() const209 bool WebAXObject::canSetSelectedAttribute() const
210 {
211 if (isDetached())
212 return 0;
213
214 return m_private->canSetSelectedAttribute();
215 }
216
isAnchor() const217 bool WebAXObject::isAnchor() const
218 {
219 if (isDetached())
220 return 0;
221
222 return m_private->isAnchor();
223 }
224
isAriaReadOnly() const225 bool WebAXObject::isAriaReadOnly() const
226 {
227 if (isDetached())
228 return 0;
229
230 return equalIgnoringCase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true");
231 }
232
isButtonStateMixed() const233 bool WebAXObject::isButtonStateMixed() const
234 {
235 if (isDetached())
236 return 0;
237
238 return m_private->checkboxOrRadioValue() == ButtonStateMixed;
239 }
240
isChecked() const241 bool WebAXObject::isChecked() const
242 {
243 if (isDetached())
244 return 0;
245
246 return m_private->isChecked();
247 }
248
isClickable() const249 bool WebAXObject::isClickable() const
250 {
251 if (isDetached())
252 return 0;
253
254 return m_private->isClickable();
255 }
256
isCollapsed() const257 bool WebAXObject::isCollapsed() const
258 {
259 if (isDetached())
260 return 0;
261
262 return m_private->isCollapsed();
263 }
264
isControl() const265 bool WebAXObject::isControl() const
266 {
267 if (isDetached())
268 return 0;
269
270 return m_private->isControl();
271 }
272
isEnabled() const273 bool WebAXObject::isEnabled() const
274 {
275 if (isDetached())
276 return 0;
277
278 return m_private->isEnabled();
279 }
280
isFocused() const281 bool WebAXObject::isFocused() const
282 {
283 if (isDetached())
284 return 0;
285
286 return m_private->isFocused();
287 }
288
isHovered() const289 bool WebAXObject::isHovered() const
290 {
291 if (isDetached())
292 return 0;
293
294 return m_private->isHovered();
295 }
296
isIndeterminate() const297 bool WebAXObject::isIndeterminate() const
298 {
299 if (isDetached())
300 return 0;
301
302 return m_private->isIndeterminate();
303 }
304
isLinked() const305 bool WebAXObject::isLinked() const
306 {
307 if (isDetached())
308 return 0;
309
310 return m_private->isLinked();
311 }
312
isLoaded() const313 bool WebAXObject::isLoaded() const
314 {
315 if (isDetached())
316 return 0;
317
318 return m_private->isLoaded();
319 }
320
isMultiSelectable() const321 bool WebAXObject::isMultiSelectable() const
322 {
323 if (isDetached())
324 return 0;
325
326 return m_private->isMultiSelectable();
327 }
328
isOffScreen() const329 bool WebAXObject::isOffScreen() const
330 {
331 if (isDetached())
332 return 0;
333
334 return m_private->isOffScreen();
335 }
336
isPasswordField() const337 bool WebAXObject::isPasswordField() const
338 {
339 if (isDetached())
340 return 0;
341
342 return m_private->isPasswordField();
343 }
344
isPressed() const345 bool WebAXObject::isPressed() const
346 {
347 if (isDetached())
348 return 0;
349
350 return m_private->isPressed();
351 }
352
isReadOnly() const353 bool WebAXObject::isReadOnly() const
354 {
355 if (isDetached())
356 return 0;
357
358 return m_private->isReadOnly();
359 }
360
isRequired() const361 bool WebAXObject::isRequired() const
362 {
363 if (isDetached())
364 return 0;
365
366 return m_private->isRequired();
367 }
368
isSelected() const369 bool WebAXObject::isSelected() const
370 {
371 if (isDetached())
372 return 0;
373
374 return m_private->isSelected();
375 }
376
isSelectedOptionActive() const377 bool WebAXObject::isSelectedOptionActive() const
378 {
379 if (isDetached())
380 return false;
381
382 return m_private->isSelectedOptionActive();
383 }
384
isVertical() const385 bool WebAXObject::isVertical() const
386 {
387 if (isDetached())
388 return 0;
389
390 return m_private->orientation() == AccessibilityOrientationVertical;
391 }
392
isVisible() const393 bool WebAXObject::isVisible() const
394 {
395 if (isDetached())
396 return 0;
397
398 return m_private->isVisible();
399 }
400
isVisited() const401 bool WebAXObject::isVisited() const
402 {
403 if (isDetached())
404 return 0;
405
406 return m_private->isVisited();
407 }
408
accessKey() const409 WebString WebAXObject::accessKey() const
410 {
411 if (isDetached())
412 return WebString();
413
414 return WebString(m_private->accessKey());
415 }
416
ariaHasPopup() const417 bool WebAXObject::ariaHasPopup() const
418 {
419 if (isDetached())
420 return 0;
421
422 return m_private->ariaHasPopup();
423 }
424
ariaLiveRegionAtomic() const425 bool WebAXObject::ariaLiveRegionAtomic() const
426 {
427 if (isDetached())
428 return 0;
429
430 return m_private->ariaLiveRegionAtomic();
431 }
432
ariaLiveRegionBusy() const433 bool WebAXObject::ariaLiveRegionBusy() const
434 {
435 if (isDetached())
436 return 0;
437
438 return m_private->ariaLiveRegionBusy();
439 }
440
ariaLiveRegionRelevant() const441 WebString WebAXObject::ariaLiveRegionRelevant() const
442 {
443 if (isDetached())
444 return WebString();
445
446 return m_private->ariaLiveRegionRelevant();
447 }
448
ariaLiveRegionStatus() const449 WebString WebAXObject::ariaLiveRegionStatus() const
450 {
451 if (isDetached())
452 return WebString();
453
454 return m_private->ariaLiveRegionStatus();
455 }
456
boundingBoxRect() const457 WebRect WebAXObject::boundingBoxRect() const
458 {
459 if (isDetached())
460 return WebRect();
461
462 return pixelSnappedIntRect(m_private->elementRect());
463 }
464
canvasHasFallbackContent() const465 bool WebAXObject::canvasHasFallbackContent() const
466 {
467 if (isDetached())
468 return false;
469
470 return m_private->canvasHasFallbackContent();
471 }
472
clickPoint() const473 WebPoint WebAXObject::clickPoint() const
474 {
475 if (isDetached())
476 return WebPoint();
477
478 return WebPoint(m_private->clickPoint());
479 }
480
colorValue(int & r,int & g,int & b) const481 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
estimatedLoadingProgress() const489 double WebAXObject::estimatedLoadingProgress() const
490 {
491 if (isDetached())
492 return 0.0;
493
494 return m_private->estimatedLoadingProgress();
495 }
496
helpText() const497 WebString WebAXObject::helpText() const
498 {
499 if (isDetached())
500 return WebString();
501
502 return m_private->helpText();
503 }
504
headingLevel() const505 int WebAXObject::headingLevel() const
506 {
507 if (isDetached())
508 return 0;
509
510 return m_private->headingLevel();
511 }
512
hierarchicalLevel() const513 int WebAXObject::hierarchicalLevel() const
514 {
515 if (isDetached())
516 return 0;
517
518 return m_private->hierarchicalLevel();
519 }
520
hitTest(const WebPoint & point) const521 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
keyboardShortcut() const538 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
performDefaultAction() const568 bool WebAXObject::performDefaultAction() const
569 {
570 if (isDetached())
571 return false;
572
573 return m_private->performDefaultAction();
574 }
575
increment() const576 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
decrement() const588 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
press() const600 bool WebAXObject::press() const
601 {
602 if (isDetached())
603 return false;
604
605 return m_private->press();
606 }
607
role() const608 WebAXRole WebAXObject::role() const
609 {
610 if (isDetached())
611 return blink::WebAXRoleUnknown;
612
613 return static_cast<WebAXRole>(m_private->roleValue());
614 }
615
selectionEnd() const616 unsigned WebAXObject::selectionEnd() const
617 {
618 if (isDetached())
619 return 0;
620
621 return m_private->selectedTextRange().start + m_private->selectedTextRange().length;
622 }
623
selectionStart() const624 unsigned WebAXObject::selectionStart() const
625 {
626 if (isDetached())
627 return 0;
628
629 return m_private->selectedTextRange().start;
630 }
631
selectionEndLineNumber() const632 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
selectionStartLineNumber() const644 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
setFocused(bool on) const656 void WebAXObject::setFocused(bool on) const
657 {
658 if (!isDetached())
659 m_private->setFocused(on);
660 }
661
setSelectedTextRange(int selectionStart,int selectionEnd) const662 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
stringValue() const670 WebString WebAXObject::stringValue() const
671 {
672 if (isDetached())
673 return WebString();
674
675 return m_private->stringValue();
676 }
677
title() const678 WebString WebAXObject::title() const
679 {
680 if (isDetached())
681 return WebString();
682
683 return m_private->title();
684 }
685
titleUIElement() const686 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
url() const697 WebURL WebAXObject::url() const
698 {
699 if (isDetached())
700 return WebURL();
701
702 return m_private->url();
703 }
704
supportsRangeValue() const705 bool WebAXObject::supportsRangeValue() const
706 {
707 if (isDetached())
708 return false;
709
710 return m_private->supportsRangeValue();
711 }
712
valueDescription() const713 WebString WebAXObject::valueDescription() const
714 {
715 if (isDetached())
716 return WebString();
717
718 return m_private->valueDescription();
719 }
720
valueForRange() const721 float WebAXObject::valueForRange() const
722 {
723 if (isDetached())
724 return 0.0;
725
726 return m_private->valueForRange();
727 }
728
maxValueForRange() const729 float WebAXObject::maxValueForRange() const
730 {
731 if (isDetached())
732 return 0.0;
733
734 return m_private->maxValueForRange();
735 }
736
minValueForRange() const737 float WebAXObject::minValueForRange() const
738 {
739 if (isDetached())
740 return 0.0;
741
742 return m_private->minValueForRange();
743 }
744
node() const745 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
document() const757 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
hasComputedStyle() const769 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
computedStyleDisplay() const785 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
accessibilityIsIgnored() const805 bool WebAXObject::accessibilityIsIgnored() const
806 {
807 if (isDetached())
808 return false;
809
810 return m_private->accessibilityIsIgnored();
811 }
812
lineBreaks(WebVector<int> & result) const813 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
columnCount() const830 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
rowCount() const841 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
cellForColumnAndRow(unsigned column,unsigned row) const852 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
headerContainerObject() const864 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
rowAtIndex(unsigned rowIndex) const875 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
columnAtIndex(unsigned columnIndex) const890 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
rowIndex() const905 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
rowHeader() const916 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
columnIndex() const927 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
columnHeader() const938 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
cellColumnIndex() const949 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
cellColumnSpan() const962 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
cellRowIndex() const975 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
cellRowSpan() const988 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
textDirection() const1001 WebAXTextDirection WebAXObject::textDirection() const
1002 {
1003 if (isDetached())
1004 return WebAXTextDirectionLR;
1005
1006 return static_cast<WebAXTextDirection>(m_private->textDirection());
1007 }
1008
characterOffsets(WebVector<int> & offsets) const1009 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
wordBoundaries(WebVector<int> & starts,WebVector<int> & ends) const1024 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
scrollToMakeVisible() const1042 void WebAXObject::scrollToMakeVisible() const
1043 {
1044 if (!isDetached())
1045 m_private->scrollToMakeVisible();
1046 }
1047
scrollToMakeVisibleWithSubFocus(const WebRect & subfocus) const1048 void WebAXObject::scrollToMakeVisibleWithSubFocus(const WebRect& subfocus) const
1049 {
1050 if (!isDetached())
1051 m_private->scrollToMakeVisibleWithSubFocus(subfocus);
1052 }
1053
scrollToGlobalPoint(const WebPoint & point) const1054 void WebAXObject::scrollToGlobalPoint(const WebPoint& point) const
1055 {
1056 if (!isDetached())
1057 m_private->scrollToGlobalPoint(point);
1058 }
1059
WebAXObject(const WTF::PassRefPtr<WebCore::AXObject> & object)1060 WebAXObject::WebAXObject(const WTF::PassRefPtr<WebCore::AXObject>& object)
1061 : m_private(object)
1062 {
1063 }
1064
operator =(const WTF::PassRefPtr<WebCore::AXObject> & object)1065 WebAXObject& WebAXObject::operator=(const WTF::PassRefPtr<WebCore::AXObject>& object)
1066 {
1067 m_private = object;
1068 return *this;
1069 }
1070
operator WTF::PassRefPtr<WebCore::AXObject>() const1071 WebAXObject::operator WTF::PassRefPtr<WebCore::AXObject>() const
1072 {
1073 return m_private.get();
1074 }
1075
1076 } // namespace blink
1077