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 "AccessibilityObject.h"
35 #include "AccessibilityTable.h"
36 #include "AccessibilityTableCell.h"
37 #include "CSSPrimitiveValueMappings.h"
39 #include "EventHandler.h"
40 #include "FrameView.h"
41 #include "HTMLNames.h"
43 #include "PlatformKeyboardEvent.h"
44 #include "RenderStyle.h"
45 #include "UserGestureIndicator.h"
46 #include "WebDocument.h"
50 #include "WebString.h"
53 using namespace WebCore;
57 void WebAccessibilityObject::reset()
62 void WebAccessibilityObject::assign(const WebKit::WebAccessibilityObject& other)
64 m_private = other.m_private;
67 bool WebAccessibilityObject::equals(const WebAccessibilityObject& n) const
69 return (m_private.get() == n.m_private.get());
72 WebString WebAccessibilityObject::accessibilityDescription() const
74 if (m_private.isNull())
77 m_private->updateBackingStore();
78 return m_private->accessibilityDescription();
81 WebString WebAccessibilityObject::actionVerb() const
83 if (m_private.isNull())
86 m_private->updateBackingStore();
87 return m_private->actionVerb();
90 bool WebAccessibilityObject::canSetFocusAttribute() const
92 if (m_private.isNull())
95 m_private->updateBackingStore();
96 return m_private->canSetFocusAttribute();
99 bool WebAccessibilityObject::canSetValueAttribute() const
101 if (m_private.isNull())
104 m_private->updateBackingStore();
105 return m_private->canSetValueAttribute();
108 bool WebAccessibilityObject::isValid() const
110 if (m_private.isNull())
113 m_private->updateBackingStore();
114 return m_private->axObjectID();
117 unsigned WebAccessibilityObject::childCount() const
119 if (m_private.isNull())
122 m_private->updateBackingStore();
123 return m_private->children().size();
126 WebAccessibilityObject WebAccessibilityObject::childAt(unsigned index) const
128 if (m_private.isNull())
129 return WebAccessibilityObject();
131 m_private->updateBackingStore();
132 if (m_private->children().size() <= index)
133 return WebAccessibilityObject();
135 return WebAccessibilityObject(m_private->children()[index]);
138 WebAccessibilityObject WebAccessibilityObject::firstChild() const
140 if (m_private.isNull())
141 return WebAccessibilityObject();
143 m_private->updateBackingStore();
144 return WebAccessibilityObject(m_private->firstChild());
147 WebAccessibilityObject WebAccessibilityObject::focusedChild() const
149 if (m_private.isNull())
150 return WebAccessibilityObject();
152 m_private->updateBackingStore();
153 RefPtr<AccessibilityObject> focused = m_private->focusedUIElement();
154 if (m_private.get() == focused.get() || m_private.get() == focused->parentObject())
155 return WebAccessibilityObject(focused);
157 return WebAccessibilityObject();
160 WebAccessibilityObject WebAccessibilityObject::lastChild() const
162 if (m_private.isNull())
163 return WebAccessibilityObject();
165 m_private->updateBackingStore();
166 return WebAccessibilityObject(m_private->lastChild());
170 WebAccessibilityObject WebAccessibilityObject::nextSibling() const
172 if (m_private.isNull())
173 return WebAccessibilityObject();
175 m_private->updateBackingStore();
176 return WebAccessibilityObject(m_private->nextSibling());
179 WebAccessibilityObject WebAccessibilityObject::parentObject() const
181 if (m_private.isNull())
182 return WebAccessibilityObject();
184 m_private->updateBackingStore();
185 return WebAccessibilityObject(m_private->parentObject());
189 WebAccessibilityObject WebAccessibilityObject::previousSibling() const
191 if (m_private.isNull())
192 return WebAccessibilityObject();
194 m_private->updateBackingStore();
195 return WebAccessibilityObject(m_private->previousSibling());
198 bool WebAccessibilityObject::canSetSelectedAttribute() const
200 if (m_private.isNull())
203 m_private->updateBackingStore();
204 return m_private->canSetSelectedAttribute();
207 bool WebAccessibilityObject::isAnchor() const
209 if (m_private.isNull())
212 m_private->updateBackingStore();
213 return m_private->isAnchor();
216 bool WebAccessibilityObject::isAriaReadOnly() const
218 if (m_private.isNull())
221 m_private->updateBackingStore();
222 return equalIgnoringCase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true");
225 bool WebAccessibilityObject::isButtonStateMixed() const
227 if (m_private.isNull())
230 m_private->updateBackingStore();
231 return m_private->checkboxOrRadioValue() == ButtonStateMixed;
234 bool WebAccessibilityObject::isChecked() const
236 if (m_private.isNull())
239 m_private->updateBackingStore();
240 return m_private->isChecked();
243 bool WebAccessibilityObject::isCollapsed() const
245 if (m_private.isNull())
248 m_private->updateBackingStore();
249 return m_private->isCollapsed();
252 bool WebAccessibilityObject::isControl() const
254 if (m_private.isNull())
257 m_private->updateBackingStore();
258 return m_private->isControl();
261 bool WebAccessibilityObject::isEnabled() const
263 if (m_private.isNull())
266 m_private->updateBackingStore();
267 return m_private->isEnabled();
270 bool WebAccessibilityObject::isFocused() const
272 if (m_private.isNull())
275 m_private->updateBackingStore();
276 return m_private->isFocused();
279 bool WebAccessibilityObject::isHovered() const
281 if (m_private.isNull())
284 m_private->updateBackingStore();
285 return m_private->isHovered();
288 bool WebAccessibilityObject::isIndeterminate() const
290 if (m_private.isNull())
293 m_private->updateBackingStore();
294 return m_private->isIndeterminate();
297 bool WebAccessibilityObject::isLinked() const
299 if (m_private.isNull())
302 m_private->updateBackingStore();
303 return m_private->isLinked();
306 bool WebAccessibilityObject::isLoaded() const
308 if (m_private.isNull())
311 m_private->updateBackingStore();
312 return m_private->isLoaded();
315 bool WebAccessibilityObject::isMultiSelectable() const
317 if (m_private.isNull())
320 m_private->updateBackingStore();
321 return m_private->isMultiSelectable();
324 bool WebAccessibilityObject::isOffScreen() const
326 if (m_private.isNull())
329 m_private->updateBackingStore();
330 return m_private->isOffScreen();
333 bool WebAccessibilityObject::isPasswordField() const
335 if (m_private.isNull())
338 m_private->updateBackingStore();
339 return m_private->isPasswordField();
342 bool WebAccessibilityObject::isPressed() const
344 if (m_private.isNull())
347 m_private->updateBackingStore();
348 return m_private->isPressed();
351 bool WebAccessibilityObject::isReadOnly() const
353 if (m_private.isNull())
356 m_private->updateBackingStore();
357 return m_private->isReadOnly();
360 bool WebAccessibilityObject::isRequired() const
362 if (m_private.isNull())
365 m_private->updateBackingStore();
366 return m_private->isRequired();
369 bool WebAccessibilityObject::isSelected() const
371 if (m_private.isNull())
374 m_private->updateBackingStore();
375 return m_private->isSelected();
378 bool WebAccessibilityObject::isVertical() const
380 if (m_private.isNull())
383 m_private->updateBackingStore();
384 return m_private->orientation() == AccessibilityOrientationVertical;
387 bool WebAccessibilityObject::isVisible() const
389 if (m_private.isNull())
392 m_private->updateBackingStore();
393 return m_private->isVisible();
396 bool WebAccessibilityObject::isVisited() const
398 if (m_private.isNull())
401 m_private->updateBackingStore();
402 return m_private->isVisited();
405 WebString WebAccessibilityObject::accessKey() const
407 if (m_private.isNull())
410 m_private->updateBackingStore();
411 return WebString(m_private->accessKey());
414 bool WebAccessibilityObject::ariaHasPopup() const
416 if (m_private.isNull())
419 m_private->updateBackingStore();
420 return m_private->ariaHasPopup();
423 bool WebAccessibilityObject::ariaLiveRegionAtomic() const
425 if (m_private.isNull())
428 m_private->updateBackingStore();
429 return m_private->ariaLiveRegionAtomic();
432 bool WebAccessibilityObject::ariaLiveRegionBusy() const
434 if (m_private.isNull())
437 m_private->updateBackingStore();
438 return m_private->ariaLiveRegionBusy();
441 WebString WebAccessibilityObject::ariaLiveRegionRelevant() const
443 if (m_private.isNull())
446 m_private->updateBackingStore();
447 return m_private->ariaLiveRegionRelevant();
450 WebString WebAccessibilityObject::ariaLiveRegionStatus() const
452 if (m_private.isNull())
455 m_private->updateBackingStore();
456 return m_private->ariaLiveRegionStatus();
459 WebRect WebAccessibilityObject::boundingBoxRect() const
461 if (m_private.isNull())
464 m_private->updateBackingStore();
465 return m_private->boundingBoxRect();
468 double WebAccessibilityObject::estimatedLoadingProgress() const
470 if (m_private.isNull())
473 m_private->updateBackingStore();
474 return m_private->estimatedLoadingProgress();
477 WebString WebAccessibilityObject::helpText() const
479 if (m_private.isNull())
482 m_private->updateBackingStore();
483 return m_private->helpText();
486 int WebAccessibilityObject::headingLevel() const
488 if (m_private.isNull())
491 m_private->updateBackingStore();
492 return m_private->headingLevel();
495 int WebAccessibilityObject::hierarchicalLevel() const
497 if (m_private.isNull())
500 m_private->updateBackingStore();
501 return m_private->hierarchicalLevel();
504 WebAccessibilityObject WebAccessibilityObject::hitTest(const WebPoint& point) const
506 if (m_private.isNull())
507 return WebAccessibilityObject();
509 m_private->updateBackingStore();
510 IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
511 RefPtr<AccessibilityObject> hit = m_private->accessibilityHitTest(contentsPoint);
514 return WebAccessibilityObject(hit);
516 if (m_private->boundingBoxRect().contains(contentsPoint))
519 return WebAccessibilityObject();
522 WebString WebAccessibilityObject::keyboardShortcut() const
524 if (m_private.isNull())
527 m_private->updateBackingStore();
528 String accessKey = m_private->accessKey();
529 if (accessKey.isNull())
532 static String modifierString;
533 if (modifierString.isNull()) {
534 unsigned modifiers = EventHandler::accessKeyModifiers();
535 // Follow the same order as Mozilla MSAA implementation:
536 // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
537 // should not be localized and defines the separator as "+".
538 if (modifiers & PlatformKeyboardEvent::CtrlKey)
539 modifierString += "Ctrl+";
540 if (modifiers & PlatformKeyboardEvent::AltKey)
541 modifierString += "Alt+";
542 if (modifiers & PlatformKeyboardEvent::ShiftKey)
543 modifierString += "Shift+";
544 if (modifiers & PlatformKeyboardEvent::MetaKey)
545 modifierString += "Win+";
548 return String(modifierString + accessKey);
551 bool WebAccessibilityObject::performDefaultAction() const
553 if (m_private.isNull())
556 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
558 m_private->updateBackingStore();
559 return m_private->performDefaultAction();
562 WebAccessibilityRole WebAccessibilityObject::roleValue() const
564 if (m_private.isNull())
565 return WebKit::WebAccessibilityRoleUnknown;
567 m_private->updateBackingStore();
568 return static_cast<WebAccessibilityRole>(m_private->roleValue());
571 unsigned WebAccessibilityObject::selectionEnd() const
573 if (m_private.isNull())
576 m_private->updateBackingStore();
577 return m_private->selectedTextRange().start + m_private->selectedTextRange().length;
580 unsigned WebAccessibilityObject::selectionStart() const
582 if (m_private.isNull())
585 m_private->updateBackingStore();
586 return m_private->selectedTextRange().start;
589 void WebAccessibilityObject::setFocused(bool on) const
591 if (!m_private.isNull())
592 m_private->setFocused(on);
595 WebString WebAccessibilityObject::stringValue() const
597 if (m_private.isNull())
600 m_private->updateBackingStore();
601 return m_private->stringValue();
604 WebString WebAccessibilityObject::title() const
606 if (m_private.isNull())
609 m_private->updateBackingStore();
610 return m_private->title();
613 WebURL WebAccessibilityObject::url() const
615 if (m_private.isNull())
618 m_private->updateBackingStore();
619 return m_private->url();
622 WebString WebAccessibilityObject::valueDescription() const
624 if (m_private.isNull())
627 m_private->updateBackingStore();
628 return m_private->valueDescription();
631 float WebAccessibilityObject::valueForRange() const
633 if (m_private.isNull())
636 m_private->updateBackingStore();
637 return m_private->valueForRange();
640 float WebAccessibilityObject::maxValueForRange() const
642 if (m_private.isNull())
645 m_private->updateBackingStore();
646 return m_private->maxValueForRange();
649 float WebAccessibilityObject::minValueForRange() const
651 if (m_private.isNull())
654 m_private->updateBackingStore();
655 return m_private->minValueForRange();
658 WebNode WebAccessibilityObject::node() const
660 if (m_private.isNull())
663 m_private->updateBackingStore();
665 Node* node = m_private->node();
669 return WebNode(node);
672 WebDocument WebAccessibilityObject::document() const
674 if (m_private.isNull())
675 return WebDocument();
677 m_private->updateBackingStore();
679 Document* document = m_private->document();
681 return WebDocument();
683 return WebDocument(document);
686 bool WebAccessibilityObject::hasComputedStyle() const
688 if (m_private.isNull())
691 Document* document = m_private->document();
693 document->updateStyleIfNeeded();
695 Node* node = m_private->node();
699 return node->computedStyle();
702 WebString WebAccessibilityObject::computedStyleDisplay() const
704 if (m_private.isNull())
707 Document* document = m_private->document();
709 document->updateStyleIfNeeded();
711 Node* node = m_private->node();
715 RenderStyle* renderStyle = node->computedStyle();
719 return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue());
722 bool WebAccessibilityObject::accessibilityIsIgnored() const
724 if (m_private.isNull())
727 m_private->updateBackingStore();
728 return m_private->accessibilityIsIgnored();
731 bool WebAccessibilityObject::lineBreaks(WebVector<int>& result) const
733 if (m_private.isNull())
736 m_private->updateBackingStore();
737 int textLength = m_private->textLength();
741 VisiblePosition pos = m_private->visiblePositionForIndex(textLength);
742 int lineBreakCount = m_private->lineForPosition(pos);
746 WebVector<int> lineBreaks(static_cast<size_t>(lineBreakCount));
747 for (int i = 0; i < lineBreakCount; i++) {
748 PlainTextRange range = m_private->doAXRangeForLine(i);
749 lineBreaks[i] = range.start + range.length;
751 result.swap(lineBreaks);
755 unsigned WebAccessibilityObject::columnCount() const
757 if (m_private.isNull())
760 m_private->updateBackingStore();
761 if (!m_private->isAccessibilityTable())
764 return static_cast<WebCore::AccessibilityTable*>(m_private.get())->columnCount();
767 unsigned WebAccessibilityObject::rowCount() const
769 if (m_private.isNull())
772 m_private->updateBackingStore();
773 if (!m_private->isAccessibilityTable())
776 return static_cast<WebCore::AccessibilityTable*>(m_private.get())->rowCount();
779 WebAccessibilityObject WebAccessibilityObject::cellForColumnAndRow(unsigned column, unsigned row) const
781 m_private->updateBackingStore();
782 if (!m_private->isAccessibilityTable())
783 return WebAccessibilityObject();
785 WebCore::AccessibilityTableCell* cell = static_cast<WebCore::AccessibilityTable*>(m_private.get())->cellForColumnAndRow(column, row);
786 return WebAccessibilityObject(static_cast<WebCore::AccessibilityObject*>(cell));
789 unsigned WebAccessibilityObject::cellColumnIndex() const
791 m_private->updateBackingStore();
792 if (!m_private->isTableCell())
795 pair<int, int> columnRange;
796 static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->columnIndexRange(columnRange);
797 return columnRange.first;
800 unsigned WebAccessibilityObject::cellColumnSpan() const
802 m_private->updateBackingStore();
803 if (!m_private->isTableCell())
806 pair<int, int> columnRange;
807 static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->columnIndexRange(columnRange);
808 return columnRange.second;
811 unsigned WebAccessibilityObject::cellRowIndex() const
813 m_private->updateBackingStore();
814 if (!m_private->isTableCell())
817 pair<int, int> rowRange;
818 static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->rowIndexRange(rowRange);
819 return rowRange.first;
822 unsigned WebAccessibilityObject::cellRowSpan() const
824 m_private->updateBackingStore();
825 if (!m_private->isTableCell())
828 pair<int, int> rowRange;
829 static_cast<WebCore::AccessibilityTableCell*>(m_private.get())->rowIndexRange(rowRange);
830 return rowRange.second;
833 WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
838 WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
844 WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const
846 return m_private.get();
849 } // namespace WebKit