• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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