• 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 "public/web/WebAXObject.h"
33 
34 #include "core/HTMLNames.h"
35 #include "core/accessibility/AXObject.h"
36 #include "core/accessibility/AXObjectCache.h"
37 #include "core/accessibility/AXTable.h"
38 #include "core/accessibility/AXTableCell.h"
39 #include "core/accessibility/AXTableColumn.h"
40 #include "core/accessibility/AXTableRow.h"
41 #include "core/css/CSSPrimitiveValueMappings.h"
42 #include "core/dom/Document.h"
43 #include "core/dom/Node.h"
44 #include "core/frame/FrameView.h"
45 #include "core/page/EventHandler.h"
46 #include "core/rendering/RenderView.h"
47 #include "core/rendering/style/RenderStyle.h"
48 #include "platform/PlatformKeyboardEvent.h"
49 #include "public/platform/WebPoint.h"
50 #include "public/platform/WebRect.h"
51 #include "public/platform/WebString.h"
52 #include "public/platform/WebURL.h"
53 #include "public/web/WebDocument.h"
54 #include "public/web/WebNode.h"
55 #include "wtf/text/StringBuilder.h"
56 
57 namespace blink {
58 
59 #if ENABLE(ASSERT)
60 // It's not safe to call some WebAXObject APIs if a layout is pending.
61 // Clients should call updateLayoutAndCheckValidity first.
isLayoutClean(Document * document)62 static bool isLayoutClean(Document* document)
63 {
64     if (!document || !document->view())
65         return false;
66     return document->lifecycle().state() >= DocumentLifecycle::LayoutClean
67         || (document->lifecycle().state() == DocumentLifecycle::StyleClean && !document->view()->needsLayout());
68 }
69 #endif
70 
reset()71 void WebAXObject::reset()
72 {
73     m_private.reset();
74 }
75 
assign(const WebAXObject & other)76 void WebAXObject::assign(const WebAXObject& other)
77 {
78     m_private = other.m_private;
79 }
80 
equals(const WebAXObject & n) const81 bool WebAXObject::equals(const WebAXObject& n) const
82 {
83     return m_private.get() == n.m_private.get();
84 }
85 
isDetached() const86 bool WebAXObject::isDetached() const
87 {
88     if (m_private.isNull())
89         return true;
90 
91     return m_private->isDetached();
92 }
93 
axID() const94 int WebAXObject::axID() const
95 {
96     if (isDetached())
97         return -1;
98 
99     return m_private->axObjectID();
100 }
101 
updateLayoutAndCheckValidity()102 bool WebAXObject::updateLayoutAndCheckValidity()
103 {
104     if (!isDetached()) {
105         Document* document = m_private->document();
106         if (!document || !document->topDocument().view())
107             return false;
108         document->topDocument().view()->updateLayoutAndStyleIfNeededRecursive();
109     }
110 
111     // Doing a layout can cause this object to be invalid, so check again.
112     return !isDetached();
113 }
114 
updateBackingStoreAndCheckValidity()115 bool WebAXObject::updateBackingStoreAndCheckValidity()
116 {
117     return updateLayoutAndCheckValidity();
118 }
119 
accessibilityDescription() const120 WebString WebAXObject::accessibilityDescription() const
121 {
122     if (isDetached())
123         return WebString();
124 
125     ASSERT(isLayoutClean(m_private->document()));
126 
127     return m_private->accessibilityDescription();
128 }
129 
actionVerb() const130 WebString WebAXObject::actionVerb() const
131 {
132     if (isDetached())
133         return WebString();
134 
135     return m_private->actionVerb();
136 }
137 
canDecrement() const138 bool WebAXObject::canDecrement() const
139 {
140     if (isDetached())
141         return false;
142 
143     return m_private->isSlider();
144 }
145 
canIncrement() const146 bool WebAXObject::canIncrement() const
147 {
148     if (isDetached())
149         return false;
150 
151     return m_private->isSlider();
152 }
153 
canPress() const154 bool WebAXObject::canPress() const
155 {
156     if (isDetached())
157         return false;
158 
159     return m_private->actionElement() || m_private->isButton() || m_private->isMenuRelated();
160 }
161 
canSetFocusAttribute() const162 bool WebAXObject::canSetFocusAttribute() const
163 {
164     if (isDetached())
165         return false;
166 
167     return m_private->canSetFocusAttribute();
168 }
169 
canSetValueAttribute() const170 bool WebAXObject::canSetValueAttribute() const
171 {
172     if (isDetached())
173         return false;
174 
175     return m_private->canSetValueAttribute();
176 }
177 
childCount() const178 unsigned WebAXObject::childCount() const
179 {
180     if (isDetached())
181         return 0;
182 
183     return m_private->children().size();
184 }
185 
childAt(unsigned index) const186 WebAXObject WebAXObject::childAt(unsigned index) const
187 {
188     if (isDetached())
189         return WebAXObject();
190 
191     if (m_private->children().size() <= index)
192         return WebAXObject();
193 
194     return WebAXObject(m_private->children()[index]);
195 }
196 
parentObject() const197 WebAXObject WebAXObject::parentObject() const
198 {
199     if (isDetached())
200         return WebAXObject();
201 
202     return WebAXObject(m_private->parentObject());
203 }
204 
canSetSelectedAttribute() const205 bool WebAXObject::canSetSelectedAttribute() const
206 {
207     if (isDetached())
208         return 0;
209 
210     return m_private->canSetSelectedAttribute();
211 }
212 
isAnchor() const213 bool WebAXObject::isAnchor() const
214 {
215     if (isDetached())
216         return 0;
217 
218     return m_private->isAnchor();
219 }
220 
isAriaReadOnly() const221 bool WebAXObject::isAriaReadOnly() const
222 {
223     if (isDetached())
224         return 0;
225 
226     return equalIgnoringCase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true");
227 }
228 
isButtonStateMixed() const229 bool WebAXObject::isButtonStateMixed() const
230 {
231     if (isDetached())
232         return 0;
233 
234     return m_private->checkboxOrRadioValue() == ButtonStateMixed;
235 }
236 
isChecked() const237 bool WebAXObject::isChecked() const
238 {
239     if (isDetached())
240         return 0;
241 
242     return m_private->isChecked();
243 }
244 
isClickable() const245 bool WebAXObject::isClickable() const
246 {
247     if (isDetached())
248         return 0;
249 
250     return m_private->isClickable();
251 }
252 
isCollapsed() const253 bool WebAXObject::isCollapsed() const
254 {
255     if (isDetached())
256         return 0;
257 
258     return m_private->isCollapsed();
259 }
260 
isControl() const261 bool WebAXObject::isControl() const
262 {
263     if (isDetached())
264         return 0;
265 
266     return m_private->isControl();
267 }
268 
isEnabled() const269 bool WebAXObject::isEnabled() const
270 {
271     if (isDetached())
272         return 0;
273 
274     return m_private->isEnabled();
275 }
276 
isFocused() const277 bool WebAXObject::isFocused() const
278 {
279     if (isDetached())
280         return 0;
281 
282     return m_private->isFocused();
283 }
284 
isHovered() const285 bool WebAXObject::isHovered() const
286 {
287     if (isDetached())
288         return 0;
289 
290     return m_private->isHovered();
291 }
292 
isIndeterminate() const293 bool WebAXObject::isIndeterminate() const
294 {
295     if (isDetached())
296         return 0;
297 
298     return m_private->isIndeterminate();
299 }
300 
isLinked() const301 bool WebAXObject::isLinked() const
302 {
303     if (isDetached())
304         return 0;
305 
306     return m_private->isLinked();
307 }
308 
isLoaded() const309 bool WebAXObject::isLoaded() const
310 {
311     if (isDetached())
312         return 0;
313 
314     return m_private->isLoaded();
315 }
316 
isMultiSelectable() const317 bool WebAXObject::isMultiSelectable() const
318 {
319     if (isDetached())
320         return 0;
321 
322     return m_private->isMultiSelectable();
323 }
324 
isOffScreen() const325 bool WebAXObject::isOffScreen() const
326 {
327     if (isDetached())
328         return 0;
329 
330     return m_private->isOffScreen();
331 }
332 
isPasswordField() const333 bool WebAXObject::isPasswordField() const
334 {
335     if (isDetached())
336         return 0;
337 
338     return m_private->isPasswordField();
339 }
340 
isPressed() const341 bool WebAXObject::isPressed() const
342 {
343     if (isDetached())
344         return 0;
345 
346     return m_private->isPressed();
347 }
348 
isReadOnly() const349 bool WebAXObject::isReadOnly() const
350 {
351     if (isDetached())
352         return 0;
353 
354     return m_private->isReadOnly();
355 }
356 
isRequired() const357 bool WebAXObject::isRequired() const
358 {
359     if (isDetached())
360         return 0;
361 
362     return m_private->isRequired();
363 }
364 
isSelected() const365 bool WebAXObject::isSelected() const
366 {
367     if (isDetached())
368         return 0;
369 
370     return m_private->isSelected();
371 }
372 
isSelectedOptionActive() const373 bool WebAXObject::isSelectedOptionActive() const
374 {
375     if (isDetached())
376         return false;
377 
378     return m_private->isSelectedOptionActive();
379 }
380 
isVertical() const381 bool WebAXObject::isVertical() const
382 {
383     if (isDetached())
384         return 0;
385 
386     return m_private->orientation() == AccessibilityOrientationVertical;
387 }
388 
isVisible() const389 bool WebAXObject::isVisible() const
390 {
391     if (isDetached())
392         return 0;
393 
394     return m_private->isVisible();
395 }
396 
isVisited() const397 bool WebAXObject::isVisited() const
398 {
399     if (isDetached())
400         return 0;
401 
402     return m_private->isVisited();
403 }
404 
accessKey() const405 WebString WebAXObject::accessKey() const
406 {
407     if (isDetached())
408         return WebString();
409 
410     return WebString(m_private->accessKey());
411 }
412 
ariaActiveDescendant() const413 WebAXObject WebAXObject::ariaActiveDescendant() const
414 {
415     if (isDetached())
416         return WebAXObject();
417 
418     return WebAXObject(m_private->activeDescendant());
419 }
420 
ariaControls(WebVector<WebAXObject> & controlsElements) const421 bool WebAXObject::ariaControls(WebVector<WebAXObject>& controlsElements) const
422 {
423     if (isDetached())
424         return false;
425 
426     AXObject::AccessibilityChildrenVector controls;
427     m_private->ariaControlsElements(controls);
428 
429     WebVector<WebAXObject> result(controls.size());
430     for (size_t i = 0; i < controls.size(); i++)
431         result[i] = WebAXObject(controls[i]);
432     controlsElements.swap(result);
433 
434     return true;
435 }
436 
ariaDescribedby(WebVector<WebAXObject> & describedbyElements) const437 bool WebAXObject::ariaDescribedby(WebVector<WebAXObject>& describedbyElements) const
438 {
439     if (isDetached())
440         return false;
441 
442     AXObject::AccessibilityChildrenVector describedby;
443     m_private->ariaDescribedbyElements(describedby);
444 
445     WebVector<WebAXObject> result(describedby.size());
446     for (size_t i = 0; i < describedby.size(); i++)
447         result[i] = WebAXObject(describedby[i]);
448     describedbyElements.swap(result);
449 
450     return true;
451 }
452 
ariaHasPopup() const453 bool WebAXObject::ariaHasPopup() const
454 {
455     if (isDetached())
456         return 0;
457 
458     return m_private->ariaHasPopup();
459 }
460 
ariaFlowTo(WebVector<WebAXObject> & flowToElements) const461 bool WebAXObject::ariaFlowTo(WebVector<WebAXObject>& flowToElements) const
462 {
463     if (isDetached())
464         return false;
465 
466     AXObject::AccessibilityChildrenVector flowTo;
467     m_private->ariaFlowToElements(flowTo);
468 
469     WebVector<WebAXObject> result(flowTo.size());
470     for (size_t i = 0; i < flowTo.size(); i++)
471         result[i] = WebAXObject(flowTo[i]);
472     flowToElements.swap(result);
473 
474     return true;
475 }
476 
ariaLabelledby(WebVector<WebAXObject> & labelledbyElements) const477 bool WebAXObject::ariaLabelledby(WebVector<WebAXObject>& labelledbyElements) const
478 {
479     if (isDetached())
480         return false;
481 
482     AXObject::AccessibilityChildrenVector labelledby;
483     m_private->ariaLabelledbyElements(labelledby);
484 
485     WebVector<WebAXObject> result(labelledby.size());
486     for (size_t i = 0; i < labelledby.size(); i++)
487         result[i] = WebAXObject(labelledby[i]);
488     labelledbyElements.swap(result);
489 
490     return true;
491 }
492 
ariaLiveRegionAtomic() const493 bool WebAXObject::ariaLiveRegionAtomic() const
494 {
495     if (isDetached())
496         return 0;
497 
498     return m_private->ariaLiveRegionAtomic();
499 }
500 
ariaLiveRegionBusy() const501 bool WebAXObject::ariaLiveRegionBusy() const
502 {
503     if (isDetached())
504         return 0;
505 
506     return m_private->ariaLiveRegionBusy();
507 }
508 
ariaLiveRegionRelevant() const509 WebString WebAXObject::ariaLiveRegionRelevant() const
510 {
511     if (isDetached())
512         return WebString();
513 
514     return m_private->ariaLiveRegionRelevant();
515 }
516 
ariaLiveRegionStatus() const517 WebString WebAXObject::ariaLiveRegionStatus() const
518 {
519     if (isDetached())
520         return WebString();
521 
522     return m_private->ariaLiveRegionStatus();
523 }
524 
ariaOwns(WebVector<WebAXObject> & ownsElements) const525 bool WebAXObject::ariaOwns(WebVector<WebAXObject>& ownsElements) const
526 {
527     if (isDetached())
528         return false;
529 
530     AXObject::AccessibilityChildrenVector owns;
531     m_private->ariaOwnsElements(owns);
532 
533     WebVector<WebAXObject> result(owns.size());
534     for (size_t i = 0; i < owns.size(); i++)
535         result[i] = WebAXObject(owns[i]);
536     ownsElements.swap(result);
537 
538     return true;
539 }
540 
boundingBoxRect() const541 WebRect WebAXObject::boundingBoxRect() const
542 {
543     if (isDetached())
544         return WebRect();
545 
546     ASSERT(isLayoutClean(m_private->document()));
547 
548     return pixelSnappedIntRect(m_private->elementRect());
549 }
550 
canvasHasFallbackContent() const551 bool WebAXObject::canvasHasFallbackContent() const
552 {
553     if (isDetached())
554         return false;
555 
556     return m_private->canvasHasFallbackContent();
557 }
558 
clickPoint() const559 WebPoint WebAXObject::clickPoint() const
560 {
561     if (isDetached())
562         return WebPoint();
563 
564     return WebPoint(m_private->clickPoint());
565 }
566 
colorValue(int & r,int & g,int & b) const567 void WebAXObject::colorValue(int& r, int& g, int& b) const
568 {
569     if (isDetached())
570         return;
571 
572     m_private->colorValue(r, g, b);
573 }
574 
estimatedLoadingProgress() const575 double WebAXObject::estimatedLoadingProgress() const
576 {
577     if (isDetached())
578         return 0.0;
579 
580     return m_private->estimatedLoadingProgress();
581 }
582 
helpText() const583 WebString WebAXObject::helpText() const
584 {
585     if (isDetached())
586         return WebString();
587 
588     return m_private->helpText();
589 }
590 
headingLevel() const591 int WebAXObject::headingLevel() const
592 {
593     if (isDetached())
594         return 0;
595 
596     return m_private->headingLevel();
597 }
598 
hierarchicalLevel() const599 int WebAXObject::hierarchicalLevel() const
600 {
601     if (isDetached())
602         return 0;
603 
604     return m_private->hierarchicalLevel();
605 }
606 
hitTest(const WebPoint & point) const607 WebAXObject WebAXObject::hitTest(const WebPoint& point) const
608 {
609     if (isDetached())
610         return WebAXObject();
611 
612     IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
613     RefPtr<AXObject> hit = m_private->accessibilityHitTest(contentsPoint);
614 
615     if (hit)
616         return WebAXObject(hit);
617 
618     if (m_private->elementRect().contains(contentsPoint))
619         return *this;
620 
621     return WebAXObject();
622 }
623 
keyboardShortcut() const624 WebString WebAXObject::keyboardShortcut() const
625 {
626     if (isDetached())
627         return WebString();
628 
629     String accessKey = m_private->accessKey();
630     if (accessKey.isNull())
631         return WebString();
632 
633     DEFINE_STATIC_LOCAL(String, modifierString, ());
634     if (modifierString.isNull()) {
635         unsigned modifiers = EventHandler::accessKeyModifiers();
636         // Follow the same order as Mozilla MSAA implementation:
637         // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
638         // should not be localized and defines the separator as "+".
639         StringBuilder modifierStringBuilder;
640         if (modifiers & PlatformEvent::CtrlKey)
641             modifierStringBuilder.appendLiteral("Ctrl+");
642         if (modifiers & PlatformEvent::AltKey)
643             modifierStringBuilder.appendLiteral("Alt+");
644         if (modifiers & PlatformEvent::ShiftKey)
645             modifierStringBuilder.appendLiteral("Shift+");
646         if (modifiers & PlatformEvent::MetaKey)
647             modifierStringBuilder.appendLiteral("Win+");
648         modifierString = modifierStringBuilder.toString();
649     }
650 
651     return String(modifierString + accessKey);
652 }
653 
performDefaultAction() const654 bool WebAXObject::performDefaultAction() const
655 {
656     if (isDetached())
657         return false;
658 
659     return m_private->performDefaultAction();
660 }
661 
increment() const662 bool WebAXObject::increment() const
663 {
664     if (isDetached())
665         return false;
666 
667     if (canIncrement()) {
668         m_private->increment();
669         return true;
670     }
671     return false;
672 }
673 
decrement() const674 bool WebAXObject::decrement() const
675 {
676     if (isDetached())
677         return false;
678 
679     if (canDecrement()) {
680         m_private->decrement();
681         return true;
682     }
683     return false;
684 }
685 
press() const686 bool WebAXObject::press() const
687 {
688     if (isDetached())
689         return false;
690 
691     return m_private->press();
692 }
693 
role() const694 WebAXRole WebAXObject::role() const
695 {
696     if (isDetached())
697         return WebAXRoleUnknown;
698 
699     return static_cast<WebAXRole>(m_private->roleValue());
700 }
701 
selectionEnd() const702 unsigned WebAXObject::selectionEnd() const
703 {
704     if (isDetached())
705         return 0;
706 
707     return m_private->selectedTextRange().start + m_private->selectedTextRange().length;
708 }
709 
selectionStart() const710 unsigned WebAXObject::selectionStart() const
711 {
712     if (isDetached())
713         return 0;
714 
715     return m_private->selectedTextRange().start;
716 }
717 
selectionEndLineNumber() const718 unsigned WebAXObject::selectionEndLineNumber() const
719 {
720     if (isDetached())
721         return 0;
722 
723     VisiblePosition position = m_private->visiblePositionForIndex(selectionEnd());
724     int lineNumber = m_private->lineForPosition(position);
725     if (lineNumber < 0)
726         return 0;
727     return lineNumber;
728 }
729 
selectionStartLineNumber() const730 unsigned WebAXObject::selectionStartLineNumber() const
731 {
732     if (isDetached())
733         return 0;
734 
735     VisiblePosition position = m_private->visiblePositionForIndex(selectionStart());
736     int lineNumber = m_private->lineForPosition(position);
737     if (lineNumber < 0)
738         return 0;
739     return lineNumber;
740 }
741 
setFocused(bool on) const742 void WebAXObject::setFocused(bool on) const
743 {
744     if (!isDetached())
745         m_private->setFocused(on);
746 }
747 
setSelectedTextRange(int selectionStart,int selectionEnd) const748 void WebAXObject::setSelectedTextRange(int selectionStart, int selectionEnd) const
749 {
750     if (isDetached())
751         return;
752 
753     m_private->setSelectedTextRange(AXObject::PlainTextRange(selectionStart, selectionEnd - selectionStart));
754 }
755 
stringValue() const756 WebString WebAXObject::stringValue() const
757 {
758     if (isDetached())
759         return WebString();
760 
761     return m_private->stringValue();
762 }
763 
title() const764 WebString WebAXObject::title() const
765 {
766     if (isDetached())
767         return WebString();
768 
769     ASSERT(isLayoutClean(m_private->document()));
770 
771     return m_private->title();
772 }
773 
titleUIElement() const774 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 
url() const785 WebURL WebAXObject::url() const
786 {
787     if (isDetached())
788         return WebURL();
789 
790     return m_private->url();
791 }
792 
supportsRangeValue() const793 bool WebAXObject::supportsRangeValue() const
794 {
795     if (isDetached())
796         return false;
797 
798     return m_private->supportsRangeValue();
799 }
800 
valueDescription() const801 WebString WebAXObject::valueDescription() const
802 {
803     if (isDetached())
804         return WebString();
805 
806     return m_private->valueDescription();
807 }
808 
valueForRange() const809 float WebAXObject::valueForRange() const
810 {
811     if (isDetached())
812         return 0.0;
813 
814     return m_private->valueForRange();
815 }
816 
maxValueForRange() const817 float WebAXObject::maxValueForRange() const
818 {
819     if (isDetached())
820         return 0.0;
821 
822     return m_private->maxValueForRange();
823 }
824 
minValueForRange() const825 float WebAXObject::minValueForRange() const
826 {
827     if (isDetached())
828         return 0.0;
829 
830     return m_private->minValueForRange();
831 }
832 
node() const833 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 
document() const845 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 
hasComputedStyle() const857 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 
computedStyleDisplay() const873 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 
accessibilityIsIgnored() const893 bool WebAXObject::accessibilityIsIgnored() const
894 {
895     if (isDetached())
896         return false;
897 
898     return m_private->accessibilityIsIgnored();
899 }
900 
lineBreaks(WebVector<int> & result) const901 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 
columnCount() const918 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 
rowCount() const929 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 
cellForColumnAndRow(unsigned column,unsigned row) const940 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     AXTableCell* cell = toAXTable(m_private.get())->cellForColumnAndRow(column, row);
949     return WebAXObject(static_cast<AXObject*>(cell));
950 }
951 
headerContainerObject() const952 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 
rowAtIndex(unsigned rowIndex) const963 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 
columnAtIndex(unsigned columnIndex) const978 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 
rowIndex() const993 unsigned WebAXObject::rowIndex() const
994 {
995     if (isDetached())
996         return 0;
997 
998     if (!m_private->isTableRow())
999         return 0;
1000 
1001     return toAXTableRow(m_private.get())->rowIndex();
1002 }
1003 
rowHeader() const1004 WebAXObject WebAXObject::rowHeader() const
1005 {
1006     if (isDetached())
1007         return WebAXObject();
1008 
1009     if (!m_private->isTableRow())
1010         return WebAXObject();
1011 
1012     return WebAXObject(toAXTableRow(m_private.get())->headerObject());
1013 }
1014 
columnIndex() const1015 unsigned WebAXObject::columnIndex() const
1016 {
1017     if (isDetached())
1018         return 0;
1019 
1020     if (m_private->roleValue() != ColumnRole)
1021         return 0;
1022 
1023     return toAXTableColumn(m_private.get())->columnIndex();
1024 }
1025 
columnHeader() const1026 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(toAXTableColumn(m_private.get())->headerObject());
1035 }
1036 
cellColumnIndex() const1037 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     toAXTableCell(m_private.get())->columnIndexRange(columnRange);
1047     return columnRange.first;
1048 }
1049 
cellColumnSpan() const1050 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     toAXTableCell(m_private.get())->columnIndexRange(columnRange);
1060     return columnRange.second;
1061 }
1062 
cellRowIndex() const1063 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     toAXTableCell(m_private.get())->rowIndexRange(rowRange);
1073     return rowRange.first;
1074 }
1075 
cellRowSpan() const1076 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     toAXTableCell(m_private.get())->rowIndexRange(rowRange);
1086     return rowRange.second;
1087 }
1088 
textDirection() const1089 WebAXTextDirection WebAXObject::textDirection() const
1090 {
1091     if (isDetached())
1092         return WebAXTextDirectionLR;
1093 
1094     return static_cast<WebAXTextDirection>(m_private->textDirection());
1095 }
1096 
characterOffsets(WebVector<int> & offsets) const1097 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 
wordBoundaries(WebVector<int> & starts,WebVector<int> & ends) const1112 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 
scrollToMakeVisible() const1130 void WebAXObject::scrollToMakeVisible() const
1131 {
1132     if (!isDetached())
1133         m_private->scrollToMakeVisible();
1134 }
1135 
scrollToMakeVisibleWithSubFocus(const WebRect & subfocus) const1136 void WebAXObject::scrollToMakeVisibleWithSubFocus(const WebRect& subfocus) const
1137 {
1138     if (!isDetached())
1139         m_private->scrollToMakeVisibleWithSubFocus(subfocus);
1140 }
1141 
scrollToGlobalPoint(const WebPoint & point) const1142 void WebAXObject::scrollToGlobalPoint(const WebPoint& point) const
1143 {
1144     if (!isDetached())
1145         m_private->scrollToGlobalPoint(point);
1146 }
1147 
WebAXObject(const WTF::PassRefPtr<AXObject> & object)1148 WebAXObject::WebAXObject(const WTF::PassRefPtr<AXObject>& object)
1149     : m_private(object)
1150 {
1151 }
1152 
operator =(const WTF::PassRefPtr<AXObject> & object)1153 WebAXObject& WebAXObject::operator=(const WTF::PassRefPtr<AXObject>& object)
1154 {
1155     m_private = object;
1156     return *this;
1157 }
1158 
operator WTF::PassRefPtr<AXObject>() const1159 WebAXObject::operator WTF::PassRefPtr<AXObject>() const
1160 {
1161     return m_private.get();
1162 }
1163 
1164 } // namespace blink
1165