2 * Copyright (C) 2009 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
32 #include "WebAXObject.h"
34 #include "HTMLNames.h"
35 #include "WebDocument.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"
56 using namespace WebCore;
60 void WebAXObject::reset()
65 void WebAXObject::assign(const blink::WebAXObject& other)
67 m_private = other.m_private;
70 bool WebAXObject::equals(const WebAXObject& n) const
72 return m_private.get() == n.m_private.get();
76 void WebAXObject::enableAccessibility()
78 AXObjectCache::enableAccessibility();
82 bool WebAXObject::accessibilityEnabled()
84 return AXObjectCache::accessibilityEnabled();
88 void WebAXObject::enableInlineTextBoxAccessibility()
90 AXObjectCache::setInlineTextBoxAccessibility(true);
93 void WebAXObject::startCachingComputedObjectAttributesUntilTreeMutates()
95 m_private->axObjectCache()->startCachingComputedObjectAttributesUntilTreeMutates();
98 void WebAXObject::stopCachingComputedObjectAttributes()
100 m_private->axObjectCache()->stopCachingComputedObjectAttributes();
103 bool WebAXObject::isDetached() const
105 if (m_private.isNull())
108 return m_private->isDetached();
111 int WebAXObject::axID() const
116 return m_private->axObjectID();
119 bool WebAXObject::updateBackingStoreAndCheckValidity()
122 m_private->updateBackingStore();
123 return !isDetached();
126 WebString WebAXObject::accessibilityDescription() const
131 return m_private->accessibilityDescription();
134 WebString WebAXObject::actionVerb() const
139 return m_private->actionVerb();
142 bool WebAXObject::canDecrement() const
147 return m_private->isSlider();
150 bool WebAXObject::canIncrement() const
155 return m_private->isSlider();
158 bool WebAXObject::canPress() const
163 return m_private->actionElement() || m_private->isButton() || m_private->isMenuRelated();
166 bool WebAXObject::canSetFocusAttribute() const
171 return m_private->canSetFocusAttribute();
174 bool WebAXObject::canSetValueAttribute() const
179 return m_private->canSetValueAttribute();
182 unsigned WebAXObject::childCount() const
187 return m_private->children().size();
190 WebAXObject WebAXObject::childAt(unsigned index) const
193 return WebAXObject();
195 if (m_private->children().size() <= index)
196 return WebAXObject();
198 return WebAXObject(m_private->children()[index]);
201 WebAXObject WebAXObject::parentObject() const
204 return WebAXObject();
206 return WebAXObject(m_private->parentObject());
209 bool WebAXObject::canSetSelectedAttribute() const
214 return m_private->canSetSelectedAttribute();
217 bool WebAXObject::isAnchor() const
222 return m_private->isAnchor();
225 bool WebAXObject::isAriaReadOnly() const
230 return equalIgnoringCase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true");
233 bool WebAXObject::isButtonStateMixed() const
238 return m_private->checkboxOrRadioValue() == ButtonStateMixed;
241 bool WebAXObject::isChecked() const
246 return m_private->isChecked();
249 bool WebAXObject::isClickable() const
254 return m_private->isClickable();
257 bool WebAXObject::isCollapsed() const
262 return m_private->isCollapsed();
265 bool WebAXObject::isControl() const
270 return m_private->isControl();
273 bool WebAXObject::isEnabled() const
278 return m_private->isEnabled();
281 bool WebAXObject::isFocused() const
286 return m_private->isFocused();
289 bool WebAXObject::isHovered() const
294 return m_private->isHovered();
297 bool WebAXObject::isIndeterminate() const
302 return m_private->isIndeterminate();
305 bool WebAXObject::isLinked() const
310 return m_private->isLinked();
313 bool WebAXObject::isLoaded() const
318 return m_private->isLoaded();
321 bool WebAXObject::isMultiSelectable() const
326 return m_private->isMultiSelectable();
329 bool WebAXObject::isOffScreen() const
334 return m_private->isOffScreen();
337 bool WebAXObject::isPasswordField() const
342 return m_private->isPasswordField();
345 bool WebAXObject::isPressed() const
350 return m_private->isPressed();
353 bool WebAXObject::isReadOnly() const
358 return m_private->isReadOnly();
361 bool WebAXObject::isRequired() const
366 return m_private->isRequired();
369 bool WebAXObject::isSelected() const
374 return m_private->isSelected();
377 bool WebAXObject::isSelectedOptionActive() const
382 return m_private->isSelectedOptionActive();
385 bool WebAXObject::isVertical() const
390 return m_private->orientation() == AccessibilityOrientationVertical;
393 bool WebAXObject::isVisible() const
398 return m_private->isVisible();
401 bool WebAXObject::isVisited() const
406 return m_private->isVisited();
409 WebString WebAXObject::accessKey() const
414 return WebString(m_private->accessKey());
417 WebAXObject WebAXObject::ariaActiveDescendant() const
420 return WebAXObject();
422 return WebAXObject(m_private->activeDescendant());
425 bool WebAXObject::ariaControls(WebVector<WebAXObject>& controlsElements) const
430 AXObject::AccessibilityChildrenVector controls;
431 m_private->ariaControlsElements(controls);
433 WebVector<WebAXObject> result(controls.size());
434 for (size_t i = 0; i < controls.size(); i++)
435 result[i] = WebAXObject(controls[i]);
436 controlsElements.swap(result);
441 bool WebAXObject::ariaDescribedby(WebVector<WebAXObject>& describedbyElements) const
446 AXObject::AccessibilityChildrenVector describedby;
447 m_private->ariaDescribedbyElements(describedby);
449 WebVector<WebAXObject> result(describedby.size());
450 for (size_t i = 0; i < describedby.size(); i++)
451 result[i] = WebAXObject(describedby[i]);
452 describedbyElements.swap(result);
457 bool WebAXObject::ariaHasPopup() const
462 return m_private->ariaHasPopup();
465 bool WebAXObject::ariaFlowTo(WebVector<WebAXObject>& flowToElements) const
470 AXObject::AccessibilityChildrenVector flowTo;
471 m_private->ariaFlowToElements(flowTo);
473 WebVector<WebAXObject> result(flowTo.size());
474 for (size_t i = 0; i < flowTo.size(); i++)
475 result[i] = WebAXObject(flowTo[i]);
476 flowToElements.swap(result);
481 bool WebAXObject::ariaLabelledby(WebVector<WebAXObject>& labelledbyElements) const
486 AXObject::AccessibilityChildrenVector labelledby;
487 m_private->ariaLabelledbyElements(labelledby);
489 WebVector<WebAXObject> result(labelledby.size());
490 for (size_t i = 0; i < labelledby.size(); i++)
491 result[i] = WebAXObject(labelledby[i]);
492 labelledbyElements.swap(result);
497 bool WebAXObject::ariaLiveRegionAtomic() const
502 return m_private->ariaLiveRegionAtomic();
505 bool WebAXObject::ariaLiveRegionBusy() const
510 return m_private->ariaLiveRegionBusy();
513 WebString WebAXObject::ariaLiveRegionRelevant() const
518 return m_private->ariaLiveRegionRelevant();
521 WebString WebAXObject::ariaLiveRegionStatus() const
526 return m_private->ariaLiveRegionStatus();
529 bool WebAXObject::ariaOwns(WebVector<WebAXObject>& ownsElements) const
534 AXObject::AccessibilityChildrenVector owns;
535 m_private->ariaOwnsElements(owns);
537 WebVector<WebAXObject> result(owns.size());
538 for (size_t i = 0; i < owns.size(); i++)
539 result[i] = WebAXObject(owns[i]);
540 ownsElements.swap(result);
545 WebRect WebAXObject::boundingBoxRect() const
550 return pixelSnappedIntRect(m_private->elementRect());
553 bool WebAXObject::canvasHasFallbackContent() const
558 return m_private->canvasHasFallbackContent();
561 WebPoint WebAXObject::clickPoint() const
566 return WebPoint(m_private->clickPoint());
569 void WebAXObject::colorValue(int& r, int& g, int& b) const
574 m_private->colorValue(r, g, b);
577 double WebAXObject::estimatedLoadingProgress() const
582 return m_private->estimatedLoadingProgress();
585 WebString WebAXObject::helpText() const
590 return m_private->helpText();
593 int WebAXObject::headingLevel() const
598 return m_private->headingLevel();
601 int WebAXObject::hierarchicalLevel() const
606 return m_private->hierarchicalLevel();
609 WebAXObject WebAXObject::hitTest(const WebPoint& point) const
612 return WebAXObject();
614 IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
615 RefPtr<AXObject> hit = m_private->accessibilityHitTest(contentsPoint);
618 return WebAXObject(hit);
620 if (m_private->elementRect().contains(contentsPoint))
623 return WebAXObject();
626 WebString WebAXObject::keyboardShortcut() const
631 String accessKey = m_private->accessKey();
632 if (accessKey.isNull())
635 DEFINE_STATIC_LOCAL(String, modifierString, ());
636 if (modifierString.isNull()) {
637 unsigned modifiers = EventHandler::accessKeyModifiers();
638 // Follow the same order as Mozilla MSAA implementation:
639 // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
640 // should not be localized and defines the separator as "+".
641 StringBuilder modifierStringBuilder;
642 if (modifiers & PlatformEvent::CtrlKey)
643 modifierStringBuilder.appendLiteral("Ctrl+");
644 if (modifiers & PlatformEvent::AltKey)
645 modifierStringBuilder.appendLiteral("Alt+");
646 if (modifiers & PlatformEvent::ShiftKey)
647 modifierStringBuilder.appendLiteral("Shift+");
648 if (modifiers & PlatformEvent::MetaKey)
649 modifierStringBuilder.appendLiteral("Win+");
650 modifierString = modifierStringBuilder.toString();
653 return String(modifierString + accessKey);
656 bool WebAXObject::performDefaultAction() const
661 return m_private->performDefaultAction();
664 bool WebAXObject::increment() const
669 if (canIncrement()) {
670 m_private->increment();
676 bool WebAXObject::decrement() const
681 if (canDecrement()) {
682 m_private->decrement();
688 bool WebAXObject::press() const
693 return m_private->press();
696 WebAXRole WebAXObject::role() const
699 return blink::WebAXRoleUnknown;
701 return static_cast<WebAXRole>(m_private->roleValue());
704 unsigned WebAXObject::selectionEnd() const
709 return m_private->selectedTextRange().start + m_private->selectedTextRange().length;
712 unsigned WebAXObject::selectionStart() const
717 return m_private->selectedTextRange().start;
720 unsigned WebAXObject::selectionEndLineNumber() const
725 VisiblePosition position = m_private->visiblePositionForIndex(selectionEnd());
726 int lineNumber = m_private->lineForPosition(position);
732 unsigned WebAXObject::selectionStartLineNumber() const
737 VisiblePosition position = m_private->visiblePositionForIndex(selectionStart());
738 int lineNumber = m_private->lineForPosition(position);
744 void WebAXObject::setFocused(bool on) const
747 m_private->setFocused(on);
750 void WebAXObject::setSelectedTextRange(int selectionStart, int selectionEnd) const
755 m_private->setSelectedTextRange(AXObject::PlainTextRange(selectionStart, selectionEnd - selectionStart));
758 WebString WebAXObject::stringValue() const
763 return m_private->stringValue();
766 WebString WebAXObject::title() const
771 return m_private->title();
774 WebAXObject WebAXObject::titleUIElement() const
777 return WebAXObject();
779 if (!m_private->exposesTitleUIElement())
780 return WebAXObject();
782 return WebAXObject(m_private->titleUIElement());
785 WebURL WebAXObject::url() const
790 return m_private->url();
793 bool WebAXObject::supportsRangeValue() const
798 return m_private->supportsRangeValue();
801 WebString WebAXObject::valueDescription() const
806 return m_private->valueDescription();
809 float WebAXObject::valueForRange() const
814 return m_private->valueForRange();
817 float WebAXObject::maxValueForRange() const
822 return m_private->maxValueForRange();
825 float WebAXObject::minValueForRange() const
830 return m_private->minValueForRange();
833 WebNode WebAXObject::node() const
838 Node* node = m_private->node();
842 return WebNode(node);
845 WebDocument WebAXObject::document() const
848 return WebDocument();
850 Document* document = m_private->document();
852 return WebDocument();
854 return WebDocument(document);
857 bool WebAXObject::hasComputedStyle() const
862 Document* document = m_private->document();
864 document->updateRenderTreeIfNeeded();
866 Node* node = m_private->node();
870 return node->computedStyle();
873 WebString WebAXObject::computedStyleDisplay() const
878 Document* document = m_private->document();
880 document->updateRenderTreeIfNeeded();
882 Node* node = m_private->node();
886 RenderStyle* renderStyle = node->computedStyle();
890 return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue());
893 bool WebAXObject::accessibilityIsIgnored() const
898 return m_private->accessibilityIsIgnored();
901 bool WebAXObject::lineBreaks(WebVector<int>& result) const
906 Vector<int> lineBreaksVector;
907 m_private->lineBreaks(lineBreaksVector);
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);
918 unsigned WebAXObject::columnCount() const
923 if (!m_private->isAXTable())
926 return toAXTable(m_private.get())->columnCount();
929 unsigned WebAXObject::rowCount() const
934 if (!m_private->isAXTable())
937 return toAXTable(m_private.get())->rowCount();
940 WebAXObject WebAXObject::cellForColumnAndRow(unsigned column, unsigned row) const
943 return WebAXObject();
945 if (!m_private->isAXTable())
946 return WebAXObject();
948 WebCore::AXTableCell* cell = toAXTable(m_private.get())->cellForColumnAndRow(column, row);
949 return WebAXObject(static_cast<WebCore::AXObject*>(cell));
952 WebAXObject WebAXObject::headerContainerObject() const
955 return WebAXObject();
957 if (!m_private->isAXTable())
958 return WebAXObject();
960 return WebAXObject(toAXTable(m_private.get())->headerContainer());
963 WebAXObject WebAXObject::rowAtIndex(unsigned rowIndex) const
966 return WebAXObject();
968 if (!m_private->isAXTable())
969 return WebAXObject();
971 const AXObject::AccessibilityChildrenVector& rows = toAXTable(m_private.get())->rows();
972 if (rowIndex < rows.size())
973 return WebAXObject(rows[rowIndex]);
975 return WebAXObject();
978 WebAXObject WebAXObject::columnAtIndex(unsigned columnIndex) const
981 return WebAXObject();
983 if (!m_private->isAXTable())
984 return WebAXObject();
986 const AXObject::AccessibilityChildrenVector& columns = toAXTable(m_private.get())->columns();
987 if (columnIndex < columns.size())
988 return WebAXObject(columns[columnIndex]);
990 return WebAXObject();
993 unsigned WebAXObject::rowIndex() const
998 if (!m_private->isTableRow())
1001 return WebCore::toAXTableRow(m_private.get())->rowIndex();
1004 WebAXObject WebAXObject::rowHeader() const
1007 return WebAXObject();
1009 if (!m_private->isTableRow())
1010 return WebAXObject();
1012 return WebAXObject(WebCore::toAXTableRow(m_private.get())->headerObject());
1015 unsigned WebAXObject::columnIndex() const
1020 if (m_private->roleValue() != ColumnRole)
1023 return WebCore::toAXTableColumn(m_private.get())->columnIndex();
1026 WebAXObject WebAXObject::columnHeader() const
1029 return WebAXObject();
1031 if (m_private->roleValue() != ColumnRole)
1032 return WebAXObject();
1034 return WebAXObject(WebCore::toAXTableColumn(m_private.get())->headerObject());
1037 unsigned WebAXObject::cellColumnIndex() const
1042 if (!m_private->isTableCell())
1045 pair<unsigned, unsigned> columnRange;
1046 WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange);
1047 return columnRange.first;
1050 unsigned WebAXObject::cellColumnSpan() const
1055 if (!m_private->isTableCell())
1058 pair<unsigned, unsigned> columnRange;
1059 WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange);
1060 return columnRange.second;
1063 unsigned WebAXObject::cellRowIndex() const
1068 if (!m_private->isTableCell())
1071 pair<unsigned, unsigned> rowRange;
1072 WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange);
1073 return rowRange.first;
1076 unsigned WebAXObject::cellRowSpan() const
1081 if (!m_private->isTableCell())
1084 pair<unsigned, unsigned> rowRange;
1085 WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange);
1086 return rowRange.second;
1089 WebAXTextDirection WebAXObject::textDirection() const
1092 return WebAXTextDirectionLR;
1094 return static_cast<WebAXTextDirection>(m_private->textDirection());
1097 void WebAXObject::characterOffsets(WebVector<int>& offsets) const
1102 Vector<int> offsetsVector;
1103 m_private->textCharacterOffsets(offsetsVector);
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);
1112 void WebAXObject::wordBoundaries(WebVector<int>& starts, WebVector<int>& ends) const
1117 Vector<AXObject::PlainTextRange> words;
1118 m_private->wordBoundaries(words);
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;
1126 starts.swap(startsWebVector);
1127 ends.swap(endsWebVector);
1130 void WebAXObject::scrollToMakeVisible() const
1133 m_private->scrollToMakeVisible();
1136 void WebAXObject::scrollToMakeVisibleWithSubFocus(const WebRect& subfocus) const
1139 m_private->scrollToMakeVisibleWithSubFocus(subfocus);
1142 void WebAXObject::scrollToGlobalPoint(const WebPoint& point) const
1145 m_private->scrollToGlobalPoint(point);
1148 WebAXObject::WebAXObject(const WTF::PassRefPtr<WebCore::AXObject>& object)
1153 WebAXObject& WebAXObject::operator=(const WTF::PassRefPtr<WebCore::AXObject>& object)
1159 WebAXObject::operator WTF::PassRefPtr<WebCore::AXObject>() const
1161 return m_private.get();
1164 } // namespace blink