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 WebKit::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 bool WebAXObject::ariaHasPopup() const
422 return m_private->ariaHasPopup();
425 bool WebAXObject::ariaLiveRegionAtomic() const
430 return m_private->ariaLiveRegionAtomic();
433 bool WebAXObject::ariaLiveRegionBusy() const
438 return m_private->ariaLiveRegionBusy();
441 WebString WebAXObject::ariaLiveRegionRelevant() const
446 return m_private->ariaLiveRegionRelevant();
449 WebString WebAXObject::ariaLiveRegionStatus() const
454 return m_private->ariaLiveRegionStatus();
457 WebRect WebAXObject::boundingBoxRect() const
462 return pixelSnappedIntRect(m_private->elementRect());
465 bool WebAXObject::canvasHasFallbackContent() const
470 return m_private->canvasHasFallbackContent();
473 WebPoint WebAXObject::clickPoint() const
478 return WebPoint(m_private->clickPoint());
481 void WebAXObject::colorValue(int& r, int& g, int& b) const
486 m_private->colorValue(r, g, b);
489 double WebAXObject::estimatedLoadingProgress() const
494 return m_private->estimatedLoadingProgress();
497 WebString WebAXObject::helpText() const
502 return m_private->helpText();
505 int WebAXObject::headingLevel() const
510 return m_private->headingLevel();
513 int WebAXObject::hierarchicalLevel() const
518 return m_private->hierarchicalLevel();
521 WebAXObject WebAXObject::hitTest(const WebPoint& point) const
524 return WebAXObject();
526 IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
527 RefPtr<AXObject> hit = m_private->accessibilityHitTest(contentsPoint);
530 return WebAXObject(hit);
532 if (m_private->elementRect().contains(contentsPoint))
535 return WebAXObject();
538 WebString WebAXObject::keyboardShortcut() const
543 String accessKey = m_private->accessKey();
544 if (accessKey.isNull())
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();
565 return String(modifierString + accessKey);
568 bool WebAXObject::performDefaultAction() const
573 return m_private->performDefaultAction();
576 bool WebAXObject::increment() const
581 if (canIncrement()) {
582 m_private->increment();
588 bool WebAXObject::decrement() const
593 if (canDecrement()) {
594 m_private->decrement();
600 bool WebAXObject::press() const
605 return m_private->press();
608 WebAXRole WebAXObject::role() const
611 return WebKit::WebAXRoleUnknown;
613 return static_cast<WebAXRole>(m_private->roleValue());
616 unsigned WebAXObject::selectionEnd() const
621 return m_private->selectedTextRange().start + m_private->selectedTextRange().length;
624 unsigned WebAXObject::selectionStart() const
629 return m_private->selectedTextRange().start;
632 unsigned WebAXObject::selectionEndLineNumber() const
637 VisiblePosition position = m_private->visiblePositionForIndex(selectionEnd());
638 int lineNumber = m_private->lineForPosition(position);
644 unsigned WebAXObject::selectionStartLineNumber() const
649 VisiblePosition position = m_private->visiblePositionForIndex(selectionStart());
650 int lineNumber = m_private->lineForPosition(position);
656 void WebAXObject::setFocused(bool on) const
659 m_private->setFocused(on);
662 void WebAXObject::setSelectedTextRange(int selectionStart, int selectionEnd) const
667 m_private->setSelectedTextRange(AXObject::PlainTextRange(selectionStart, selectionEnd - selectionStart));
670 WebString WebAXObject::stringValue() const
675 return m_private->stringValue();
678 WebString WebAXObject::title() const
683 return m_private->title();
686 WebAXObject WebAXObject::titleUIElement() const
689 return WebAXObject();
691 if (!m_private->exposesTitleUIElement())
692 return WebAXObject();
694 return WebAXObject(m_private->titleUIElement());
697 WebURL WebAXObject::url() const
702 return m_private->url();
705 bool WebAXObject::supportsRangeValue() const
710 return m_private->supportsRangeValue();
713 WebString WebAXObject::valueDescription() const
718 return m_private->valueDescription();
721 float WebAXObject::valueForRange() const
726 return m_private->valueForRange();
729 float WebAXObject::maxValueForRange() const
734 return m_private->maxValueForRange();
737 float WebAXObject::minValueForRange() const
742 return m_private->minValueForRange();
745 WebNode WebAXObject::node() const
750 Node* node = m_private->node();
754 return WebNode(node);
757 WebDocument WebAXObject::document() const
760 return WebDocument();
762 Document* document = m_private->document();
764 return WebDocument();
766 return WebDocument(document);
769 bool WebAXObject::hasComputedStyle() const
774 Document* document = m_private->document();
776 document->updateStyleIfNeeded();
778 Node* node = m_private->node();
782 return node->computedStyle();
785 WebString WebAXObject::computedStyleDisplay() const
790 Document* document = m_private->document();
792 document->updateStyleIfNeeded();
794 Node* node = m_private->node();
798 RenderStyle* renderStyle = node->computedStyle();
802 return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue());
805 bool WebAXObject::accessibilityIsIgnored() const
810 return m_private->accessibilityIsIgnored();
813 bool WebAXObject::lineBreaks(WebVector<int>& result) const
818 Vector<int> lineBreaksVector;
819 m_private->lineBreaks(lineBreaksVector);
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);
830 unsigned WebAXObject::columnCount() const
835 if (!m_private->isAXTable())
838 return toAXTable(m_private.get())->columnCount();
841 unsigned WebAXObject::rowCount() const
846 if (!m_private->isAXTable())
849 return toAXTable(m_private.get())->rowCount();
852 WebAXObject WebAXObject::cellForColumnAndRow(unsigned column, unsigned row) const
855 return WebAXObject();
857 if (!m_private->isAXTable())
858 return WebAXObject();
860 WebCore::AXTableCell* cell = toAXTable(m_private.get())->cellForColumnAndRow(column, row);
861 return WebAXObject(static_cast<WebCore::AXObject*>(cell));
864 WebAXObject WebAXObject::headerContainerObject() const
867 return WebAXObject();
869 if (!m_private->isAXTable())
870 return WebAXObject();
872 return WebAXObject(toAXTable(m_private.get())->headerContainer());
875 WebAXObject WebAXObject::rowAtIndex(unsigned rowIndex) const
878 return WebAXObject();
880 if (!m_private->isAXTable())
881 return WebAXObject();
883 const AXObject::AccessibilityChildrenVector& rows = toAXTable(m_private.get())->rows();
884 if (rowIndex < rows.size())
885 return WebAXObject(rows[rowIndex]);
887 return WebAXObject();
890 WebAXObject WebAXObject::columnAtIndex(unsigned columnIndex) const
893 return WebAXObject();
895 if (!m_private->isAXTable())
896 return WebAXObject();
898 const AXObject::AccessibilityChildrenVector& columns = toAXTable(m_private.get())->columns();
899 if (columnIndex < columns.size())
900 return WebAXObject(columns[columnIndex]);
902 return WebAXObject();
905 unsigned WebAXObject::rowIndex() const
910 if (!m_private->isTableRow())
913 return WebCore::toAXTableRow(m_private.get())->rowIndex();
916 WebAXObject WebAXObject::rowHeader() const
919 return WebAXObject();
921 if (!m_private->isTableRow())
922 return WebAXObject();
924 return WebAXObject(WebCore::toAXTableRow(m_private.get())->headerObject());
927 unsigned WebAXObject::columnIndex() const
932 if (m_private->roleValue() != ColumnRole)
935 return WebCore::toAXTableColumn(m_private.get())->columnIndex();
938 WebAXObject WebAXObject::columnHeader() const
941 return WebAXObject();
943 if (m_private->roleValue() != ColumnRole)
944 return WebAXObject();
946 return WebAXObject(WebCore::toAXTableColumn(m_private.get())->headerObject());
949 unsigned WebAXObject::cellColumnIndex() const
954 if (!m_private->isTableCell())
957 pair<unsigned, unsigned> columnRange;
958 WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange);
959 return columnRange.first;
962 unsigned WebAXObject::cellColumnSpan() const
967 if (!m_private->isTableCell())
970 pair<unsigned, unsigned> columnRange;
971 WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange);
972 return columnRange.second;
975 unsigned WebAXObject::cellRowIndex() const
980 if (!m_private->isTableCell())
983 pair<unsigned, unsigned> rowRange;
984 WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange);
985 return rowRange.first;
988 unsigned WebAXObject::cellRowSpan() const
993 if (!m_private->isTableCell())
996 pair<unsigned, unsigned> rowRange;
997 WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange);
998 return rowRange.second;
1001 WebAXTextDirection WebAXObject::textDirection() const
1004 return WebAXTextDirectionLR;
1006 return static_cast<WebAXTextDirection>(m_private->textDirection());
1009 void WebAXObject::characterOffsets(WebVector<int>& offsets) const
1014 Vector<int> offsetsVector;
1015 m_private->textCharacterOffsets(offsetsVector);
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);
1024 void WebAXObject::wordBoundaries(WebVector<int>& starts, WebVector<int>& ends) const
1029 Vector<AXObject::PlainTextRange> words;
1030 m_private->wordBoundaries(words);
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;
1038 starts.swap(startsWebVector);
1039 ends.swap(endsWebVector);
1042 void WebAXObject::scrollToMakeVisible() const
1045 m_private->scrollToMakeVisible();
1048 void WebAXObject::scrollToMakeVisibleWithSubFocus(const WebRect& subfocus) const
1051 m_private->scrollToMakeVisibleWithSubFocus(subfocus);
1054 void WebAXObject::scrollToGlobalPoint(const WebPoint& point) const
1057 m_private->scrollToGlobalPoint(point);
1060 WebAXObject::WebAXObject(const WTF::PassRefPtr<WebCore::AXObject>& object)
1065 WebAXObject& WebAXObject::operator=(const WTF::PassRefPtr<WebCore::AXObject>& object)
1071 WebAXObject::operator WTF::PassRefPtr<WebCore::AXObject>() const
1073 return m_private.get();
1076 } // namespace WebKit