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