2 * Copyright (C) 2008, 2009, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nuanti Ltd.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "core/editing/VisiblePosition.h"
34 #include "platform/geometry/FloatQuad.h"
35 #include "platform/geometry/LayoutRect.h"
36 #include "wtf/Forward.h"
37 #include "wtf/RefPtr.h"
38 #include "wtf/Vector.h"
43 class AXObjectCacheImpl;
52 typedef unsigned AXID;
54 enum AccessibilityRole {
77 DescriptionListDetailRole,
79 DescriptionListTermRole,
83 DisclosureTriangleRole,
123 MenuItemCheckBoxRole,
137 ProgressIndicatorRole,
165 TableHeaderContainerRole,
177 UserInterfaceTooltipRole,
183 enum AccessibilityTextSource {
194 enum AccessibilityState {
203 AXIndeterminateState,
206 AXMultiselectableState,
218 struct AccessibilityText {
220 AccessibilityTextSource textSource;
221 RefPtr<AXObject> textElement;
223 AccessibilityText(const String& t, const AccessibilityTextSource& s)
228 AccessibilityText(const String& t, const AccessibilityTextSource& s, const RefPtr<AXObject> element)
231 , textElement(element)
235 enum AccessibilityOrientation {
236 AccessibilityOrientationVertical,
237 AccessibilityOrientationHorizontal,
240 enum AXObjectInclusion {
246 enum AccessibilityButtonState {
252 enum AccessibilityTextDirection {
253 AccessibilityTextDirectionLeftToRight,
254 AccessibilityTextDirectionRightToLeft,
255 AccessibilityTextDirectionTopToBottom,
256 AccessibilityTextDirectionBottomToTop
259 enum AccessibilityExpanded {
260 ExpandedUndefined = 0,
265 class AXObject : public RefCounted<AXObject> {
267 typedef Vector<RefPtr<AXObject> > AccessibilityChildrenVector;
269 struct PlainTextRange {
279 PlainTextRange(unsigned s, unsigned l)
284 bool isNull() const { return !start && !length; }
293 // After constructing an AXObject, it must be given a
294 // unique ID, then added to AXObjectCacheImpl, and finally init() must
296 void setAXObjectID(AXID axObjectID) { m_id = axObjectID; }
297 virtual void init() { }
299 // When the corresponding WebCore object that this AXObject
300 // wraps is deleted, it must be detached.
301 virtual void detach();
302 virtual bool isDetached() const;
304 // If the parent of this object is known, this can be faster than using computeParent().
305 virtual void setParent(AXObject* parent) { m_parent = parent; }
307 // The AXObjectCacheImpl that owns this object, and its unique ID within this cache.
308 AXObjectCacheImpl* axObjectCache() const;
309 AXID axObjectID() const { return m_id; }
311 // Determine subclass type.
312 virtual bool isAXNodeObject() const { return false; }
313 virtual bool isAXRenderObject() const { return false; }
314 virtual bool isAXScrollbar() const { return false; }
315 virtual bool isAXScrollView() const { return false; }
316 virtual bool isAXSVGRoot() const { return false; }
318 // Check object role or purpose.
319 virtual AccessibilityRole roleValue() const { return m_role; }
320 bool isARIATextControl() const;
321 virtual bool isARIATreeGridRow() const { return false; }
322 virtual bool isAXTable() const { return false; }
323 virtual bool isAnchor() const { return false; }
324 virtual bool isAttachment() const { return false; }
325 bool isButton() const;
326 bool isCanvas() const { return roleValue() == CanvasRole; }
327 bool isCheckbox() const { return roleValue() == CheckBoxRole; }
328 bool isCheckboxOrRadio() const { return isCheckbox() || isRadioButton(); }
329 bool isColorWell() const { return roleValue() == ColorWellRole; }
330 bool isComboBox() const { return roleValue() == ComboBoxRole; }
331 virtual bool isControl() const { return false; }
332 virtual bool isDataTable() const { return false; }
333 virtual bool isEmbeddedObject() const { return false; }
334 virtual bool isFieldset() const { return false; }
335 virtual bool isFileUploadButton() const { return false; }
336 virtual bool isHeading() const { return false; }
337 virtual bool isImage() const { return false; }
338 virtual bool isImageMapLink() const { return false; }
339 virtual bool isInputImage() const { return false; }
340 bool isLandmarkRelated() const;
341 virtual bool isLink() const { return false; }
342 virtual bool isList() const { return false; }
343 bool isListItem() const { return roleValue() == ListItemRole; }
344 virtual bool isListBoxOption() const { return false; }
345 virtual bool isMenu() const { return false; }
346 virtual bool isMenuButton() const { return false; }
347 virtual bool isMenuList() const { return false; }
348 virtual bool isMenuListOption() const { return false; }
349 virtual bool isMenuListPopup() const { return false; }
350 bool isMenuRelated() const;
351 virtual bool isMockObject() const { return false; }
352 virtual bool isNativeSpinButton() const { return false; }
353 virtual bool isNativeTextControl() const { return false; } // input or textarea
354 virtual bool isNonNativeTextControl() const { return false; } // contenteditable or role=textbox
355 virtual bool isPasswordField() const { return false; }
356 virtual bool isPasswordFieldAndShouldHideValue() const;
357 virtual bool isProgressIndicator() const { return false; }
358 bool isRadioButton() const { return roleValue() == RadioButtonRole; }
359 bool isScrollbar() const { return roleValue() == ScrollBarRole; }
360 virtual bool isSlider() const { return false; }
361 virtual bool isSpinButton() const { return roleValue() == SpinButtonRole; }
362 virtual bool isSpinButtonPart() const { return false; }
363 bool isTabItem() const { return roleValue() == TabRole; }
364 virtual bool isTableCell() const { return false; }
365 virtual bool isTableRow() const { return false; }
366 virtual bool isTableCol() const { return false; }
367 bool isTextControl() const;
368 bool isTree() const { return roleValue() == TreeRole; }
369 bool isTreeItem() const { return roleValue() == TreeItemRole; }
370 bool isWebArea() const { return roleValue() == WebAreaRole; }
372 // Check object state.
373 virtual bool isChecked() const { return false; }
374 virtual bool isClickable() const;
375 virtual bool isCollapsed() const { return false; }
376 virtual bool isEnabled() const { return false; }
377 virtual AccessibilityExpanded isExpanded() const { return ExpandedUndefined; }
378 virtual bool isFocused() const { return false; }
379 virtual bool isHovered() const { return false; }
380 virtual bool isIndeterminate() const { return false; }
381 virtual bool isLinked() const { return false; }
382 virtual bool isLoaded() const { return false; }
383 virtual bool isMultiSelectable() const { return false; }
384 virtual bool isOffScreen() const { return false; }
385 virtual bool isPressed() const { return false; }
386 virtual bool isReadOnly() const { return false; }
387 virtual bool isRequired() const { return false; }
388 virtual bool isSelected() const { return false; }
389 virtual bool isSelectedOptionActive() const { return false; }
390 virtual bool isVisible() const { return true; }
391 virtual bool isVisited() const { return false; }
393 // Check whether certain properties can be modified.
394 virtual bool canSetFocusAttribute() const { return false; }
395 virtual bool canSetValueAttribute() const { return false; }
396 virtual bool canSetSelectedAttribute() const { return false; }
398 // Whether objects are ignored, i.e. not included in the tree.
399 bool accessibilityIsIgnored() const;
400 bool accessibilityIsIgnoredByDefault() const;
401 AXObjectInclusion accessibilityPlatformIncludesObject() const;
402 virtual AXObjectInclusion defaultObjectInclusion() const;
403 bool isInertOrAriaHidden() const;
404 bool lastKnownIsIgnoredValue();
405 void setLastKnownIsIgnoredValue(bool);
407 // Properties of static elements.
408 virtual const AtomicString& accessKey() const { return nullAtom; }
409 virtual bool canvasHasFallbackContent() const { return false; }
410 virtual bool exposesTitleUIElement() const { return true; }
411 virtual int headingLevel() const { return 0; }
412 // 1-based, to match the aria-level spec.
413 virtual unsigned hierarchicalLevel() const { return 0; }
414 virtual AccessibilityOrientation orientation() const;
415 virtual String text() const { return String(); }
416 virtual int textLength() const { return 0; }
417 virtual AXObject* titleUIElement() const { return 0; }
418 virtual KURL url() const { return KURL(); }
420 // Load inline text boxes for just this node, even if
421 // settings->inlineTextBoxAccessibilityEnabled() is false.
422 virtual void loadInlineTextBoxes() { }
424 // For an inline text box.
425 virtual AccessibilityTextDirection textDirection() const { return AccessibilityTextDirectionLeftToRight; }
426 // The integer horizontal pixel offset of each character in the string; negative values for RTL.
427 virtual void textCharacterOffsets(Vector<int>&) const { }
428 // The start and end character offset of each word in the inline text box.
429 virtual void wordBoundaries(Vector<PlainTextRange>& words) const { }
431 // Properties of interactive elements.
432 virtual String actionVerb() const;
433 virtual AccessibilityButtonState checkboxOrRadioValue() const;
434 virtual void colorValue(int& r, int& g, int& b) const { r = 0; g = 0; b = 0; }
435 virtual String valueDescription() const { return String(); }
436 virtual float valueForRange() const { return 0.0f; }
437 virtual float maxValueForRange() const { return 0.0f; }
438 virtual float minValueForRange() const { return 0.0f; }
439 virtual String stringValue() const { return String(); }
440 virtual const AtomicString& textInputType() const { return nullAtom; }
443 virtual AXObject* activeDescendant() const { return 0; }
444 virtual String ariaDescribedByAttribute() const { return String(); }
445 virtual void ariaFlowToElements(AccessibilityChildrenVector&) const { }
446 virtual void ariaControlsElements(AccessibilityChildrenVector&) const { }
447 virtual void ariaDescribedbyElements(AccessibilityChildrenVector& describedby) const { };
448 virtual void ariaLabelledbyElements(AccessibilityChildrenVector& labelledby) const { };
449 virtual void ariaOwnsElements(AccessibilityChildrenVector& owns) const { };
450 virtual bool ariaHasPopup() const { return false; }
451 bool ariaIsMultiline() const;
452 virtual String ariaLabeledByAttribute() const { return String(); }
453 bool ariaPressedIsPresent() const;
454 virtual AccessibilityRole ariaRoleAttribute() const { return UnknownRole; }
455 virtual bool ariaRoleHasPresentationalChildren() const { return false; }
456 virtual bool isARIAGrabbed() { return false; }
457 virtual bool isPresentationalChildOfAriaRole() const { return false; }
458 virtual bool shouldFocusActiveDescendant() const { return false; }
459 bool supportsARIAAttributes() const;
460 virtual bool supportsARIADragging() const { return false; }
461 virtual bool supportsARIADropping() const { return false; }
462 virtual bool supportsARIAFlowTo() const { return false; }
463 virtual bool supportsARIAOwns() const { return false; }
464 bool supportsRangeValue() const;
467 // Used by an ARIA tree to get all its rows.
468 void ariaTreeRows(AccessibilityChildrenVector&);
470 // ARIA live-region features.
471 bool isLiveRegion() const;
472 const AXObject* liveRegionRoot() const;
473 virtual const AtomicString& liveRegionStatus() const { return nullAtom; }
474 virtual const AtomicString& liveRegionRelevant() const { return nullAtom; }
475 virtual bool liveRegionAtomic() const { return false; }
476 virtual bool liveRegionBusy() const { return false; }
478 const AtomicString& containerLiveRegionStatus() const;
479 const AtomicString& containerLiveRegionRelevant() const;
480 bool containerLiveRegionAtomic() const;
481 bool containerLiveRegionBusy() const;
483 // Accessibility Text.
484 virtual String textUnderElement() const { return String(); }
486 // Accessibility Text - (To be deprecated).
487 virtual String accessibilityDescription() const { return String(); }
488 virtual String title() const { return String(); }
489 virtual String helpText() const { return String(); }
491 // Location and click point in frame-relative coordinates.
492 virtual LayoutRect elementRect() const { return m_explicitElementRect; }
493 void setElementRect(LayoutRect r) { m_explicitElementRect = r; }
494 virtual void markCachedElementRectDirty() const;
495 virtual IntPoint clickPoint();
498 // Called on the root AX object to return the deepest available element.
499 virtual AXObject* accessibilityHitTest(const IntPoint&) const { return 0; }
500 // Called on the AX object after the render tree determines which is the right AXRenderObject.
501 virtual AXObject* elementAccessibilityHitTest(const IntPoint&) const;
503 // High-level accessibility tree access. Other modules should only use these functions.
504 const AccessibilityChildrenVector& children();
505 AXObject* parentObject() const;
506 AXObject* parentObjectIfExists() const;
507 virtual AXObject* computeParent() const = 0;
508 virtual AXObject* computeParentIfExists() const { return 0; }
509 AXObject* cachedParentObject() const { return m_parent; }
510 AXObject* parentObjectUnignored() const;
512 // Low-level accessibility tree exploration, only for use within the accessibility module.
513 virtual AXObject* firstChild() const { return 0; }
514 virtual AXObject* nextSibling() const { return 0; }
515 static AXObject* firstAccessibleObjectFromNode(const Node*);
516 virtual void addChildren() { }
517 virtual bool canHaveChildren() const { return true; }
518 bool hasChildren() const { return m_haveChildren; }
519 virtual void updateChildrenIfNecessary();
520 virtual bool needsToUpdateChildren() const { return false; }
521 virtual void setNeedsToUpdateChildren() { }
522 virtual void clearChildren();
523 virtual void detachFromParent() { m_parent = 0; }
524 virtual AXObject* observableObject() const { return 0; }
525 virtual AXObject* scrollBar(AccessibilityOrientation) { return 0; }
527 // Properties of the object's owning document or page.
528 virtual double estimatedLoadingProgress() const { return 0; }
529 AXObject* focusedUIElement() const;
531 // DOM and Render tree access.
532 virtual Node* node() const { return 0; }
533 virtual RenderObject* renderer() const { return 0; }
534 virtual Document* document() const;
535 virtual FrameView* documentFrameView() const;
536 virtual Element* anchorElement() const { return 0; }
537 virtual Element* actionElement() const { return 0; }
538 virtual Widget* widgetForAttachmentView() const { return 0; }
539 String language() const;
540 bool hasAttribute(const QualifiedName&) const;
541 const AtomicString& getAttribute(const QualifiedName&) const;
544 virtual PlainTextRange selectedTextRange() const { return PlainTextRange(); }
546 // Modify or take an action on an object.
547 virtual void increment() { }
548 virtual void decrement() { }
549 bool performDefaultAction() const { return press(); }
550 virtual bool press() const;
551 // Make this object visible by scrolling as many nested scrollable views as needed.
552 void scrollToMakeVisible() const;
553 // Same, but if the whole object can't be made visible, try for this subrect, in local coordinates.
554 void scrollToMakeVisibleWithSubFocus(const IntRect&) const;
555 // Scroll this object to a given point in global coordinates of the top-level window.
556 void scrollToGlobalPoint(const IntPoint&) const;
557 virtual void setFocused(bool) { }
558 virtual void setSelected(bool) { }
559 void setSelectedText(const String&) { }
560 virtual void setSelectedTextRange(const PlainTextRange&) { }
561 virtual void setValue(const String&) { }
562 virtual void setValue(float) { }
564 // Notifications that this object may have changed.
565 virtual void childrenChanged() { }
566 virtual void handleActiveDescendantChanged() { }
567 virtual void handleAriaExpandedChanged() { }
568 void notifyIfIgnoredValueChanged();
569 virtual void selectionChanged();
570 virtual void textChanged() { }
571 virtual void updateAccessibilityRole() { }
573 // Text metrics. Most of these should be deprecated, needs major cleanup.
574 virtual VisiblePosition visiblePositionForIndex(int) const { return VisiblePosition(); }
575 int lineForPosition(const VisiblePosition&) const;
576 virtual int index(const VisiblePosition&) const { return -1; }
577 virtual void lineBreaks(Vector<int>&) const { }
579 // Static helper functions.
580 static bool isARIAControl(AccessibilityRole);
581 static bool isARIAInput(AccessibilityRole);
582 static AccessibilityRole ariaRoleToWebCoreRole(const String&);
583 static IntRect boundingBoxForQuads(RenderObject*, const Vector<FloatQuad>&);
587 AccessibilityChildrenVector m_children;
588 mutable bool m_haveChildren;
589 AccessibilityRole m_role;
590 AXObjectInclusion m_lastKnownIsIgnoredValue;
591 LayoutRect m_explicitElementRect;
593 virtual bool computeAccessibilityIsIgnored() const { return true; }
595 // If this object itself scrolls, return its ScrollableArea.
596 virtual ScrollableArea* getScrollableAreaIfScrollable() const { return 0; }
597 virtual void scrollTo(const IntPoint&) const { }
599 AccessibilityRole buttonRoleType() const;
601 bool allowsTextRanges() const { return isTextControl(); }
602 unsigned getLengthForTextRange() const { return text().length(); }
606 mutable AXObject* m_parent;
608 // The following cached attribute values (the ones starting with m_cached*)
609 // are only valid if m_lastModificationCount matches AXObjectCacheImpl::modificationCount().
610 mutable int m_lastModificationCount;
611 mutable bool m_cachedIsIgnored;
612 mutable const AXObject* m_cachedLiveRegionRoot;
614 // Updates the cached attribute values. This may be recursive, so to prevent deadlocks,
615 // functions called here may only search up the tree (ancestors), not down.
616 void updateCachedAttributeValuesIfNeeded() const;
619 #define DEFINE_AX_OBJECT_TYPE_CASTS(thisType, predicate) \
620 DEFINE_TYPE_CASTS(thisType, AXObject, object, object->predicate, object.predicate)