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 "WebAccessibilityObject.h"
34 #include "AXObjectCache.h"
35 #include "AccessibilityObject.h"
36 #include "AccessibilityTable.h"
37 #include "AccessibilityTableCell.h"
38 #include "CSSPrimitiveValueMappings.h"
40 #include "EventHandler.h"
41 #include "FrameView.h"
42 #include "HTMLNames.h"
44 #include "PlatformKeyboardEvent.h"
45 #include "RenderStyle.h"
46 #include "UserGestureIndicator.h"
47 #include "WebDocument.h"
51 #include "WebString.h"
54 using namespace WebCore;
58 void WebAccessibilityObject::reset()
63 void WebAccessibilityObject::assign(const WebKit::WebAccessibilityObject& other)
65 m_private = other.m_private;
68 bool WebAccessibilityObject::equals(const WebAccessibilityObject& n) const
70 return (m_private.get() == n.m_private.get());
74 void WebAccessibilityObject::enableAccessibility()
76 AXObjectCache::enableAccessibility();
80 bool WebAccessibilityObject::accessibilityEnabled()
82 return AXObjectCache::accessibilityEnabled();
85 int WebAccessibilityObject::axID() const
87 if (m_private.isNull())
90 m_private->updateBackingStore();
91 return m_private->axObjectID();
94 WebString WebAccessibilityObject::accessibilityDescription() const
96 if (m_private.isNull())
99 m_private->updateBackingStore();
100 return m_private->accessibilityDescription();
103 WebString WebAccessibilityObject::actionVerb() const
105 if (m_private.isNull())
108 m_private->updateBackingStore();
109 return m_private->actionVerb();
112 bool WebAccessibilityObject::canSetFocusAttribute() const
114 if (m_private.isNull())
117 m_private->updateBackingStore();
118 return m_private->canSetFocusAttribute();
121 bool WebAccessibilityObject::canSetValueAttribute() const
123 if (m_private.isNull())
126 m_private->updateBackingStore();
127 return m_private->canSetValueAttribute();
130 bool WebAccessibilityObject::isValid() const
132 if (m_private.isNull())
135 m_private->updateBackingStore();
136 return m_private->axObjectID();
139 unsigned WebAccessibilityObject::childCount() const
141 if (m_private.isNull())
144 m_private->updateBackingStore();
145 return m_private->children().size();
148 WebAccessibilityObject WebAccessibilityObject::childAt(unsigned index) const
150 if (m_private.isNull())
151 return WebAccessibilityObject();
153 m_private->updateBackingStore();
154 if (m_private->children().size() <= index)
155 return WebAccessibilityObject();
157 return WebAccessibilityObject(m_private->children()[index]);
160 WebAccessibilityObject WebAccessibilityObject::firstChild() const
162 if (m_private.isNull())
163 return WebAccessibilityObject();
165 m_private->updateBackingStore();
166 return WebAccessibilityObject(m_private->firstChild());
169 WebAccessibilityObject WebAccessibilityObject::focusedChild() const
171 if (m_private.isNull())
172 return WebAccessibilityObject();
174 m_private->updateBackingStore();
175 RefPtr<AccessibilityObject> focused = m_private->focusedUIElement();
176 if (m_private.get() == focused.get() || m_private.get() == focused->parentObject())
177 return WebAccessibilityObject(focused);
179 return WebAccessibilityObject();
182 WebAccessibilityObject WebAccessibilityObject::lastChild() const
184 if (m_private.isNull())
185 return WebAccessibilityObject();
187 m_private->updateBackingStore();
188 return WebAccessibilityObject(m_private->lastChild());
192 WebAccessibilityObject WebAccessibilityObject::nextSibling() const
194 if (m_private.isNull())
195 return WebAccessibilityObject();
197 m_private->updateBackingStore();
198 return WebAccessibilityObject(m_private->nextSibling());
201 WebAccessibilityObject WebAccessibilityObject::parentObject() const
203 if (m_private.isNull())
204 return WebAccessibilityObject();
206 m_private->updateBackingStore();
207 return WebAccessibilityObject(m_private->parentObject());
211 WebAccessibilityObject WebAccessibilityObject::previousSibling() const
213 if (m_private.isNull())
214 return WebAccessibilityObject();
216 m_private->updateBackingStore();
217 return WebAccessibilityObject(m_private->previousSibling());
220 bool WebAccessibilityObject::canSetSelectedAttribute() const
222 if (m_private.isNull())
225 m_private->updateBackingStore();
226 return m_private->canSetSelectedAttribute();
229 bool WebAccessibilityObject::isAnchor() const
231 if (m_private.isNull())
234 m_private->updateBackingStore();
235 return m_private->isAnchor();
238 bool WebAccessibilityObject::isAriaReadOnly() const
240 if (m_private.isNull())
243 m_private->updateBackingStore();
244 return equalIgnoringCase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true");
247 bool WebAccessibilityObject::isButtonStateMixed() const
249 if (m_private.isNull())
252 m_private->updateBackingStore();
253 return m_private->checkboxOrRadioValue() == ButtonStateMixed;
256 bool WebAccessibilityObject::isChecked() const
258 if (m_private.isNull())
261 m_private->updateBackingStore();
262 return m_private->isChecked();
265 bool WebAccessibilityObject::isCollapsed() const
267 if (m_private.isNull())
270 m_private->updateBackingStore();
271 return m_private->isCollapsed();
274 bool WebAccessibilityObject::isControl() const
276 if (m_private.isNull())
279 m_private->updateBackingStore();
280 return m_private->isControl();
283 bool WebAccessibilityObject::isEnabled() const
285 if (m_private.isNull())
288 m_private->updateBackingStore();
289 return m_private->isEnabled();
292 bool WebAccessibilityObject::isFocused() const
294 if (m_private.isNull())
297 m_private->updateBackingStore();
298 return m_private->isFocused();
301 bool WebAccessibilityObject::isHovered() const
303 if (m_private.isNull())
306 m_private->updateBackingStore();
307 return m_private->isHovered();
310 bool WebAccessibilityObject::isIndeterminate() const
312 if (m_private.isNull())
315 m_private->updateBackingStore();
316 return m_private->isIndeterminate();
319 bool WebAccessibilityObject::isLinked() const
321 if (m_private.isNull())
324 m_private->updateBackingStore();
325 return m_private->isLinked();
328 bool WebAccessibilityObject::isLoaded() const
330 if (m_private.isNull())
333 m_private->updateBackingStore();
334 return m_private->isLoaded();
337 bool WebAccessibilityObject::isMultiSelectable() const
339 if (m_private.isNull())
342 m_private->updateBackingStore();
343 return m_private->isMultiSelectable();
346 bool WebAccessibilityObject::isOffScreen() const
348 if (m_private.isNull())
351 m_private->updateBackingStore();
352 return m_private->isOffScreen();
355 bool WebAccessibilityObject::isPasswordField() const
357 if (m_private.isNull())
360 m_private->updateBackingStore();
361 return m_private->isPasswordField();
364 bool WebAccessibilityObject::isPressed() const
366 if (m_private.isNull())
369 m_private->updateBackingStore();
370 return m_private->isPressed();
373 bool WebAccessibilityObject::isReadOnly() const
375 if (m_private.isNull())
378 m_private->updateBackingStore();
379 return m_private->isReadOnly();
382 bool WebAccessibilityObject::isRequired() const
384 if (m_private.isNull())
387 m_private->updateBackingStore();
388 return m_private->isRequired();
391 bool WebAccessibilityObject::isSelected() const
393 if (m_private.isNull())
396 m_private->updateBackingStore();
397 return m_private->isSelected();
400 bool WebAccessibilityObject::isSelectedOptionActive() const
402 if (m_private.isNull())
405 m_private->updateBackingStore();
406 return m_private->isSelectedOptionActive();
409 bool WebAccessibilityObject::isVertical() const
411 if (m_private.isNull())
414 m_private->updateBackingStore();
415 return m_private->orientation() == AccessibilityOrientationVertical;
418 bool WebAccessibilityObject::isVisible() const
420 if (m_private.isNull())
423 m_private->updateBackingStore();
424 return m_private->isVisible();
427 bool WebAccessibilityObject::isVisited() const
429 if (m_private.isNull())
432 m_private->updateBackingStore();
433 return m_private->isVisited();
436 WebString WebAccessibilityObject::accessKey() const
438 if (m_private.isNull())
441 m_private->updateBackingStore();
442 return WebString(m_private->accessKey());
445 bool WebAccessibilityObject::ariaHasPopup() const
447 if (m_private.isNull())
450 m_private->updateBackingStore();
451 return m_private->ariaHasPopup();
454 bool WebAccessibilityObject::ariaLiveRegionAtomic() const
456 if (m_private.isNull())
459 m_private->updateBackingStore();
460 return m_private->ariaLiveRegionAtomic();
463 bool WebAccessibilityObject::ariaLiveRegionBusy() const
465 if (m_private.isNull())
468 m_private->updateBackingStore();
469 return m_private->ariaLiveRegionBusy();
472 WebString WebAccessibilityObject::ariaLiveRegionRelevant() const
474 if (m_private.isNull())
477 m_private->updateBackingStore();
478 return m_private->ariaLiveRegionRelevant();
481 WebString WebAccessibilityObject::ariaLiveRegionStatus() const
483 if (m_private.isNull())
486 m_private->updateBackingStore();
487 return m_private->ariaLiveRegionStatus();
490 WebRect WebAccessibilityObject::boundingBoxRect() const
492 if (m_private.isNull())
495 m_private->updateBackingStore();
496 return m_private->boundingBoxRect();
499 double WebAccessibilityObject::estimatedLoadingProgress() const
501 if (m_private.isNull())
504 m_private->updateBackingStore();
505 return m_private->estimatedLoadingProgress();
508 WebString WebAccessibilityObject::helpText() const
510 if (m_private.isNull())
513 m_private->updateBackingStore();
514 return m_private->helpText();
517 int WebAccessibilityObject::headingLevel() const
519 if (m_private.isNull())
522 m_private->updateBackingStore();
523 return m_private->headingLevel();
526 int WebAccessibilityObject::hierarchicalLevel() const
528 if (m_private.isNull())
531 m_private->updateBackingStore();
532 return m_private->hierarchicalLevel();
535 WebAccessibilityObject WebAccessibilityObject::hitTest(const WebPoint& point) const
537 if (m_private.isNull())
538 return WebAccessibilityObject();
540 m_private->updateBackingStore();
541 IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
542 RefPtr<AccessibilityObject> hit = m_private->accessibilityHitTest(contentsPoint);
545 return WebAccessibilityObject(hit);
547 if (m_private->boundingBoxRect().contains(contentsPoint))
550 return WebAccessibilityObject();
553 WebString WebAccessibilityObject::keyboardShortcut() const
555 if (m_private.isNull())
558 m_private->updateBackingStore();
559 String accessKey = m_private->accessKey();
560 if (accessKey.isNull())
563 DEFINE_STATIC_LOCAL(String, modifierString, ());
564 if (modifierString.isNull()) {
565 unsigned modifiers = EventHandler::accessKeyModifiers();
566 // Follow the same order as Mozilla MSAA implementation:
567 // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
568 // should not be localized and defines the separator as "+".
569 if (modifiers & PlatformKeyboardEvent::CtrlKey)
570 modifierString += "Ctrl+";
571 if (modifiers & PlatformKeyboardEvent::AltKey)
572 modifierString += "Alt+";
573 if (modifiers & PlatformKeyboardEvent::ShiftKey)
574 modifierString += "Shift+";
575 if (modifiers & PlatformKeyboardEvent::MetaKey)
576 modifierString += "Win+";
579 return String(modifierString + accessKey);
582 bool WebAccessibilityObject::performDefaultAction() const
584 if (m_private.isNull())
587 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
589 m_private->updateBackingStore();
590 return m_private->performDefaultAction();
593 WebAccessibilityRole WebAccessibilityObject::roleValue() const
595 if (m_private.isNull())
596 return WebKit::WebAccessibilityRoleUnknown;
598 m_private->updateBackingStore();
599 return static_cast<WebAccessibilityRole>(m_private->roleValue());
602 unsigned WebAccessibilityObject::selectionEnd() const
604 if (m_private.isNull())
607 m_private->updateBackingStore();
608 return m_private->selectedTextRange().start + m_private->selectedTextRange().length;
611 unsigned WebAccessibilityObject::selectionStart() const
613 if (m_private.isNull())
616 m_private->updateBackingStore();
617 return m_private->selectedTextRange().start;
620 void WebAccessibilityObject::setFocused(bool on) const
622 if (!m_private.isNull())
623 m_private->setFocused(on);
626 WebString WebAccessibilityObject::stringValue() const
628 if (m_private.isNull())
631 m_private->updateBackingStore();
632 return m_private->stringValue();
635 WebString WebAccessibilityObject::title() const
637 if (m_private.isNull())
640 m_private->updateBackingStore();
641 return m_private->title();
644 WebAccessibilityObject WebAccessibilityObject::titleUIElement() const
646 if (m_private.isNull())
647 return WebAccessibilityObject();
649 m_private->updateBackingStore();
650 return WebAccessibilityObject(m_private->titleUIElement());
653 WebURL WebAccessibilityObject::url() const
655 if (m_private.isNull())
658 m_private->updateBackingStore();
659 return m_private->url();
662 WebString WebAccessibilityObject::valueDescription() const
664 if (m_private.isNull())
667 m_private->updateBackingStore();
668 return m_private->valueDescription();
671 float WebAccessibilityObject::valueForRange() const
673 if (m_private.isNull())
676 m_private->updateBackingStore();
677 return m_private->valueForRange();
680 float WebAccessibilityObject::maxValueForRange() const
682 if (m_private.isNull())
685 m_private->updateBackingStore();
686 return m_private->maxValueForRange();
689 float WebAccessibilityObject::minValueForRange() const
691 if (m_private.isNull())
694 m_private->updateBackingStore();
695 return m_private->minValueForRange();
698 WebNode WebAccessibilityObject::node() const
700 if (m_private.isNull())
703 m_private->updateBackingStore();
705 Node* node = m_private->node();
709 return WebNode(node);
712 WebDocument WebAccessibilityObject::document() const
714 if (m_private.isNull())
715 return WebDocument();
717 m_private->updateBackingStore();
719 Document* document = m_private->document();
721 return WebDocument();
723 return WebDocument(document);
726 bool WebAccessibilityObject::hasComputedStyle() const
728 if (m_private.isNull())
731 Document* document = m_private->document();
733 document->updateStyleIfNeeded();
735 Node* node = m_private->node();
739 return node->computedStyle();
742 WebString WebAccessibilityObject::computedStyleDisplay() const
744 if (m_private.isNull())
747 Document* document = m_private->document();
749 document->updateStyleIfNeeded();
751 Node* node = m_private->node();
755 RenderStyle* renderStyle = node->computedStyle();
759 return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue());
762 bool WebAccessibilityObject::accessibilityIsIgnored() const
764 if (m_private.isNull())
767 m_private->updateBackingStore();
768 return m_private->accessibilityIsIgnored();
771 bool WebAccessibilityObject::lineBreaks(WebVector<int>& result) const
773 if (m_private.isNull())
776 m_private->updateBackingStore();
777 int textLength = m_private->textLength();
781 VisiblePosition pos = m_private->visiblePositionForIndex(textLength);
782 int lineBreakCount = m_private->lineForPosition(pos);
783 if (lineBreakCount <= 0)
786 WebVector<int> lineBreaks(static_cast<size_t>(lineBreakCount));
787 for (int i = 0; i < lineBreakCount; i++) {
788 PlainTextRange range = m_private->doAXRangeForLine(i);
789 lineBreaks[i] = range.start + range.length;
791 result.swap(lineBreaks);
795 unsigned WebAccessibilityObject::columnCount() const
797 if (m_private.isNull())
800 m_private->updateBackingStore();
801 if (!m_private->isAccessibilityTable())
804 return static_cast<WebCore::AccessibilityTable*>(m_private.get())->columnCount();
807 unsigned WebAccessibilityObject::rowCount() const
809 if (m_private.isNull())
812 m_private->updateBackingStore();
813 if (!m_private->isAccessibilityTable())
816 return static_cast<WebCore::AccessibilityTable*>(m_private.get())->rowCount();
819 WebAccessibilityObject WebAccessibilityObject::cellForColumnAndRow(unsigned column, unsigned row) const
821 m_private->updateBackingStore();
822 if (!m_private->isAccessibilityTable())
823 return WebAccessibilityObject();
825 WebCore::AccessibilityTableCell* cell = static_cast<WebCore::AccessibilityTable*>(m_private.get())->cellForColumnAndRow(column, row);
826 return WebAccessibilityObject(static_cast<WebCore::AccessibilityObject*>(cell));
829 unsigned WebAccessibilityObject::cellColumnIndex() const
831 m_private->updateBackingStore();
832 if (!m_private->isTableCell())
835 pair<int, int> columnRange;
836 static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->columnIndexRange(columnRange);
837 return columnRange.first;
840 unsigned WebAccessibilityObject::cellColumnSpan() const
842 m_private->updateBackingStore();
843 if (!m_private->isTableCell())
846 pair<int, int> columnRange;
847 static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->columnIndexRange(columnRange);
848 return columnRange.second;
851 unsigned WebAccessibilityObject::cellRowIndex() const
853 m_private->updateBackingStore();
854 if (!m_private->isTableCell())
857 pair<int, int> rowRange;
858 static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->rowIndexRange(rowRange);
859 return rowRange.first;
862 unsigned WebAccessibilityObject::cellRowSpan() const
864 m_private->updateBackingStore();
865 if (!m_private->isTableCell())
868 pair<int, int> rowRange;
869 static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->rowIndexRange(rowRange);
870 return rowRange.second;
873 WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
878 WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
884 WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const
886 return m_private.get();
889 } // namespace WebKit