1 /* 2 * Copyright (C) 2008, 2009, 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Nuanti Ltd. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 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. 17 * 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. 28 */ 29 30 #ifndef AccessibilityObject_h 31 #define AccessibilityObject_h 32 33 #include "core/editing/TextIterator.h" 34 #include "core/editing/VisiblePosition.h" 35 #include "core/platform/graphics/FloatQuad.h" 36 #include "core/platform/graphics/LayoutRect.h" 37 #include "wtf/Forward.h" 38 #include "wtf/RefPtr.h" 39 #include "wtf/Vector.h" 40 41 namespace WebCore { 42 43 class AccessibilityObject; 44 class AXObjectCache; 45 class Element; 46 class Frame; 47 class FrameView; 48 class HTMLAnchorElement; 49 class HTMLAreaElement; 50 class IntPoint; 51 class IntSize; 52 class Node; 53 class Page; 54 class RenderObject; 55 class RenderListItem; 56 class ScrollableArea; 57 class VisibleSelection; 58 class Widget; 59 60 typedef unsigned AXID; 61 62 enum AccessibilityRole { 63 AnnotationRole = 1, 64 ApplicationRole, 65 ApplicationAlertRole, 66 ApplicationAlertDialogRole, 67 ApplicationDialogRole, 68 ApplicationLogRole, 69 ApplicationMarqueeRole, 70 ApplicationStatusRole, 71 ApplicationTimerRole, 72 BrowserRole, 73 BusyIndicatorRole, 74 ButtonRole, 75 CanvasRole, 76 CellRole, 77 CheckBoxRole, 78 ColorWellRole, 79 ColumnRole, 80 ColumnHeaderRole, 81 ComboBoxRole, 82 DefinitionRole, 83 DescriptionListTermRole, 84 DescriptionListDetailRole, 85 DirectoryRole, 86 DisclosureTriangleRole, 87 DivRole, 88 DocumentRole, 89 DocumentArticleRole, 90 DocumentMathRole, 91 DocumentNoteRole, 92 DocumentRegionRole, 93 DrawerRole, 94 EditableTextRole, 95 FooterRole, 96 FormRole, 97 GridRole, 98 GroupRole, 99 GrowAreaRole, 100 HeadingRole, 101 HelpTagRole, 102 HorizontalRuleRole, 103 IgnoredRole, 104 ImageRole, 105 ImageMapRole, 106 ImageMapLinkRole, 107 IncrementorRole, 108 LabelRole, 109 LandmarkApplicationRole, 110 LandmarkBannerRole, 111 LandmarkComplementaryRole, 112 LandmarkContentInfoRole, 113 LandmarkMainRole, 114 LandmarkNavigationRole, 115 LandmarkSearchRole, 116 LegendRole, 117 LinkRole, 118 ListRole, 119 ListBoxRole, 120 ListBoxOptionRole, 121 ListItemRole, 122 ListMarkerRole, 123 MathElementRole, 124 MatteRole, 125 MenuRole, 126 MenuBarRole, 127 MenuButtonRole, 128 MenuItemRole, 129 MenuListPopupRole, 130 MenuListOptionRole, 131 OutlineRole, 132 ParagraphRole, 133 PopUpButtonRole, 134 PresentationalRole, 135 ProgressIndicatorRole, 136 RadioButtonRole, 137 RadioGroupRole, 138 RowHeaderRole, 139 RowRole, 140 RulerRole, 141 RulerMarkerRole, 142 ScrollAreaRole, 143 ScrollBarRole, 144 SeamlessWebAreaRole, 145 SheetRole, 146 SliderRole, 147 SliderThumbRole, 148 SpinButtonRole, 149 SpinButtonPartRole, 150 SplitGroupRole, 151 SplitterRole, 152 StaticTextRole, 153 SystemWideRole, 154 SVGRootRole, 155 TabGroupRole, 156 TabListRole, 157 TabPanelRole, 158 TabRole, 159 TableRole, 160 TableHeaderContainerRole, 161 TextAreaRole, 162 TreeRole, 163 TreeGridRole, 164 TreeItemRole, 165 TextFieldRole, 166 ToggleButtonRole, 167 ToolbarRole, 168 UnknownRole, 169 UserInterfaceTooltipRole, 170 ValueIndicatorRole, 171 WebAreaRole, 172 WebCoreLinkRole, 173 WindowRole, 174 }; 175 176 enum AccessibilityTextSource { 177 AlternativeText, 178 ChildrenText, 179 SummaryText, 180 HelpText, 181 VisibleText, 182 TitleTagText, 183 PlaceholderText, 184 LabelByElementText, 185 }; 186 187 struct AccessibilityText { 188 String text; 189 AccessibilityTextSource textSource; 190 RefPtr<AccessibilityObject> textElement; 191 192 AccessibilityText(const String& t, const AccessibilityTextSource& s) 193 : text(t) 194 , textSource(s) 195 { } 196 197 AccessibilityText(const String& t, const AccessibilityTextSource& s, const RefPtr<AccessibilityObject> element) 198 : text(t) 199 , textSource(s) 200 , textElement(element) 201 { } 202 }; 203 204 enum AccessibilityOrientation { 205 AccessibilityOrientationVertical, 206 AccessibilityOrientationHorizontal, 207 }; 208 209 enum AccessibilityObjectInclusion { 210 IncludeObject, 211 IgnoreObject, 212 DefaultBehavior, 213 }; 214 215 enum AccessibilityButtonState { 216 ButtonStateOff = 0, 217 ButtonStateOn, 218 ButtonStateMixed, 219 }; 220 221 struct VisiblePositionRange { 222 223 VisiblePosition start; 224 VisiblePosition end; 225 226 VisiblePositionRange() {} 227 228 VisiblePositionRange(const VisiblePosition& s, const VisiblePosition& e) 229 : start(s) 230 , end(e) 231 { } 232 233 bool isNull() const { return start.isNull() || end.isNull(); } 234 }; 235 236 struct PlainTextRange { 237 238 unsigned start; 239 unsigned length; 240 241 PlainTextRange() 242 : start(0) 243 , length(0) 244 { } 245 246 PlainTextRange(unsigned s, unsigned l) 247 : start(s) 248 , length(l) 249 { } 250 251 bool isNull() const { return !start && !length; } 252 }; 253 254 class AccessibilityObject : public RefCounted<AccessibilityObject> { 255 public: 256 typedef Vector<RefPtr<AccessibilityObject> > AccessibilityChildrenVector; 257 258 protected: 259 AccessibilityObject(); 260 261 public: 262 virtual ~AccessibilityObject(); 263 264 // After constructing an AccessibilityObject, it must be given a 265 // unique ID, then added to AXObjectCache, and finally init() must 266 // be called last. 267 void setAXObjectID(AXID axObjectID) { m_id = axObjectID; } 268 virtual void init() { } 269 270 // When the corresponding WebCore object that this AccessibilityObject 271 // wraps is deleted, it must be detached. 272 virtual void detach(); 273 virtual bool isDetached() const; 274 275 // The AXObjectCache that owns this object, and its unique ID within this cache. 276 AXObjectCache* axObjectCache() const; 277 AXID axObjectID() const { return m_id; } 278 279 // Lays out the page so that the accessibility tree is based on up-to-date information. 280 void updateBackingStore(); 281 282 // Determine subclass type. 283 virtual bool isAccessibilityNodeObject() const { return false; } 284 virtual bool isAccessibilityRenderObject() const { return false; } 285 virtual bool isAccessibilityScrollbar() const { return false; } 286 virtual bool isAccessibilityScrollView() const { return false; } 287 virtual bool isAccessibilitySVGRoot() const { return false; } 288 289 // Check object role or purpose. 290 virtual AccessibilityRole roleValue() const { return m_role; } 291 bool isARIATextControl() const; 292 virtual bool isARIATreeGridRow() const { return false; } 293 virtual bool isAccessibilityTable() const { return false; } 294 virtual bool isAnchor() const { return false; } 295 virtual bool isAttachment() const { return false; } 296 bool isButton() const; 297 bool isCanvas() const { return roleValue() == CanvasRole; } 298 bool isCheckbox() const { return roleValue() == CheckBoxRole; } 299 bool isCheckboxOrRadio() const { return isCheckbox() || isRadioButton(); } 300 bool isColorWell() const { return roleValue() == ColorWellRole; } 301 bool isComboBox() const { return roleValue() == ComboBoxRole; } 302 virtual bool isControl() const { return false; } 303 virtual bool isDataTable() const { return false; } 304 virtual bool isFieldset() const { return false; } 305 virtual bool isFileUploadButton() const { return false; } 306 virtual bool isHeading() const { return false; } 307 virtual bool isImage() const { return false; } 308 virtual bool isImageMapLink() const { return false; } 309 virtual bool isInputImage() const { return false; } 310 virtual bool isLink() const { return false; } 311 virtual bool isList() const { return false; } 312 bool isListItem() const { return roleValue() == ListItemRole; } 313 virtual bool isMenu() const { return false; } 314 virtual bool isMenuButton() const { return false; } 315 virtual bool isMenuList() const { return false; } 316 virtual bool isMenuListOption() const { return false; } 317 virtual bool isMenuListPopup() const { return false; } 318 bool isMenuRelated() const; 319 virtual bool isMockObject() const { return false; } 320 virtual bool isNativeSpinButton() const { return false; } 321 virtual bool isNativeTextControl() const { return false; } // input or textarea 322 virtual bool isNonNativeTextControl() const { return false; } // contenteditable or role=textbox 323 virtual bool isPasswordField() const { return false; } 324 virtual bool isProgressIndicator() const { return false; } 325 bool isRadioButton() const { return roleValue() == RadioButtonRole; } 326 bool isScrollbar() const { return roleValue() == ScrollBarRole; } 327 bool isSeamlessWebArea() const { return roleValue() == SeamlessWebAreaRole; } 328 virtual bool isSlider() const { return false; } 329 virtual bool isSpinButton() const { return roleValue() == SpinButtonRole; } 330 virtual bool isSpinButtonPart() const { return false; } 331 bool isTabItem() const { return roleValue() == TabRole; } 332 virtual bool isTableCell() const { return false; } 333 virtual bool isTableRow() const { return false; } 334 bool isTextControl() const; 335 bool isTree() const { return roleValue() == TreeRole; } 336 bool isTreeItem() const { return roleValue() == TreeItemRole; } 337 bool isWebArea() const { return roleValue() == WebAreaRole; } 338 339 // Check object state. 340 virtual bool isChecked() const { return false; } 341 virtual bool isCollapsed() const { return false; } 342 virtual bool isEnabled() const { return false; } 343 bool isExpanded() const; 344 virtual bool isFocused() const { return false; } 345 virtual bool isHovered() const { return false; } 346 virtual bool isIndeterminate() const { return false; } 347 virtual bool isLinked() const { return false; } 348 virtual bool isLoaded() const { return false; } 349 virtual bool isMultiSelectable() const { return false; } 350 virtual bool isOffScreen() const { return false; } 351 virtual bool isPressed() const { return false; } 352 virtual bool isReadOnly() const { return false; } 353 virtual bool isRequired() const { return false; } 354 virtual bool isSelected() const { return false; } 355 virtual bool isSelectedOptionActive() const { return false; } 356 virtual bool isVisible() const { return true; } 357 virtual bool isVisited() const { return false; } 358 359 // Check whether certain properties can be modified. 360 virtual bool canSetFocusAttribute() const { return false; } 361 virtual bool canSetValueAttribute() const { return false; } 362 virtual bool canSetSelectedAttribute() const { return false; } 363 virtual bool canSetSelectedChildrenAttribute() const { return false; } 364 365 // Whether objects are ignored, i.e. not included in the tree. 366 bool accessibilityIsIgnored() const; 367 bool accessibilityIsIgnoredByDefault() const; 368 AccessibilityObjectInclusion accessibilityPlatformIncludesObject() const; 369 virtual AccessibilityObjectInclusion defaultObjectInclusion() const; 370 bool lastKnownIsIgnoredValue(); 371 void setLastKnownIsIgnoredValue(bool); 372 373 // Properties of static elements. 374 virtual const AtomicString& accessKey() const { return nullAtom; } 375 virtual bool canvasHasFallbackContent() const { return false; } 376 virtual bool exposesTitleUIElement() const { return true; } 377 virtual int headingLevel() const { return 0; } 378 // 1-based, to match the aria-level spec. 379 virtual unsigned hierarchicalLevel() const { return 0; } 380 virtual AccessibilityOrientation orientation() const; 381 virtual int tableLevel() const { return 0; } 382 virtual String text() const { return String(); } 383 virtual int textLength() const { return 0; } 384 virtual AccessibilityObject* titleUIElement() const { return 0; } 385 virtual KURL url() const { return KURL(); } 386 387 // Properties of interactive elements. 388 virtual String actionVerb() const; 389 virtual AccessibilityButtonState checkboxOrRadioValue() const; 390 virtual void colorValue(int& r, int& g, int& b) const { r = 0; g = 0; b = 0; } 391 virtual String valueDescription() const { return String(); } 392 virtual float valueForRange() const { return 0.0f; } 393 virtual float maxValueForRange() const { return 0.0f; } 394 virtual float minValueForRange() const { return 0.0f; } 395 const AtomicString& placeholderValue() const; 396 virtual void selectedChildren(AccessibilityChildrenVector&) { } 397 virtual String stringValue() const { return String(); } 398 399 // ARIA attributes. 400 virtual AccessibilityObject* activeDescendant() const { return 0; } 401 virtual String ariaDescribedByAttribute() const { return String(); } 402 virtual void ariaFlowToElements(AccessibilityChildrenVector&) const { } 403 virtual bool ariaHasPopup() const { return false; } 404 bool ariaIsMultiline() const; 405 virtual String ariaLabeledByAttribute() const { return String(); } 406 bool ariaPressedIsPresent() const; 407 virtual AccessibilityRole ariaRoleAttribute() const { return UnknownRole; } 408 virtual bool ariaRoleHasPresentationalChildren() const { return false; } 409 const AtomicString& invalidStatus() const; 410 virtual bool isARIAGrabbed() { return false; } 411 virtual bool isPresentationalChildOfAriaRole() const { return false; } 412 virtual bool shouldFocusActiveDescendant() const { return false; } 413 bool supportsARIAAttributes() const; 414 virtual bool supportsARIADragging() const { return false; } 415 virtual bool supportsARIADropping() const { return false; } 416 virtual bool supportsARIAFlowTo() const { return false; } 417 virtual bool supportsARIAOwns() const { return false; } 418 bool supportsRangeValue() const; 419 420 // ARIA trees. 421 // Used by an ARIA tree to get all its rows. 422 void ariaTreeRows(AccessibilityChildrenVector&); 423 424 // ARIA live-region features. 425 bool supportsARIALiveRegion() const; 426 virtual const AtomicString& ariaLiveRegionStatus() const { return nullAtom; } 427 virtual const AtomicString& ariaLiveRegionRelevant() const { return nullAtom; } 428 virtual bool ariaLiveRegionAtomic() const { return false; } 429 virtual bool ariaLiveRegionBusy() const { return false; } 430 431 // Accessibility Text. 432 virtual void accessibilityText(Vector<AccessibilityText>&) { }; 433 virtual String textUnderElement() const { return String(); } 434 435 // Accessibility Text - (To be deprecated). 436 virtual String accessibilityDescription() const { return String(); } 437 virtual String title() const { return String(); } 438 virtual String helpText() const { return String(); } 439 440 // Location and click point in frame-relative coordinates. 441 virtual LayoutRect elementRect() const { return m_explicitElementRect; } 442 void setElementRect(LayoutRect r) { m_explicitElementRect = r; } 443 virtual void markCachedElementRectDirty() const; 444 virtual IntPoint clickPoint(); 445 446 // Hit testing. 447 // Called on the root AX object to return the deepest available element. 448 virtual AccessibilityObject* accessibilityHitTest(const IntPoint&) const { return 0; } 449 // Called on the AX object after the render tree determines which is the right AccessibilityRenderObject. 450 virtual AccessibilityObject* elementAccessibilityHitTest(const IntPoint&) const; 451 452 // High-level accessibility tree access. Other modules should only use these functions. 453 const AccessibilityChildrenVector& children(); 454 virtual AccessibilityObject* parentObject() const = 0; 455 AccessibilityObject* parentObjectUnignored() const; 456 virtual AccessibilityObject* parentObjectIfExists() const { return 0; } 457 458 // Low-level accessibility tree exploration, only for use within the accessibility module. 459 virtual AccessibilityObject* firstChild() const { return 0; } 460 virtual AccessibilityObject* nextSibling() const { return 0; } 461 static AccessibilityObject* firstAccessibleObjectFromNode(const Node*); 462 virtual void addChildren() { } 463 virtual bool canHaveChildren() const { return true; } 464 bool hasChildren() const { return m_haveChildren; } 465 virtual void updateChildrenIfNecessary(); 466 virtual void setNeedsToUpdateChildren() { } 467 virtual void clearChildren(); 468 virtual void detachFromParent() { } 469 virtual AccessibilityObject* observableObject() const { return 0; } 470 virtual AccessibilityObject* scrollBar(AccessibilityOrientation) { return 0; } 471 472 // Properties of the object's owning document or page. 473 virtual double estimatedLoadingProgress() const { return 0; } 474 AccessibilityObject* focusedUIElement() const; 475 476 // DOM and Render tree access. 477 virtual Node* node() const { return 0; } 478 virtual RenderObject* renderer() const { return 0; } 479 virtual Document* document() const; 480 virtual FrameView* documentFrameView() const; 481 virtual Element* anchorElement() const { return 0; } 482 virtual Element* actionElement() const { return 0; } 483 virtual Widget* widgetForAttachmentView() const { return 0; } 484 Page* page() const; 485 String language() const; 486 bool hasAttribute(const QualifiedName&) const; 487 const AtomicString& getAttribute(const QualifiedName&) const; 488 489 // Selected text. 490 TextIteratorBehavior textIteratorBehaviorForTextRange() const; 491 virtual PlainTextRange selectedTextRange() const { return PlainTextRange(); } 492 unsigned selectionStart() const { return selectedTextRange().start; } 493 unsigned selectionEnd() const { return selectedTextRange().length; } 494 virtual String selectedText() const { return String(); } 495 496 // Modify or take an action on an object. 497 virtual void increment() { } 498 virtual void decrement() { } 499 bool performDefaultAction() const { return press(); } 500 virtual bool press() const; 501 // Make this object visible by scrolling as many nested scrollable views as needed. 502 void scrollToMakeVisible() const; 503 // Same, but if the whole object can't be made visible, try for this subrect, in local coordinates. 504 void scrollToMakeVisibleWithSubFocus(const IntRect&) const; 505 // Scroll this object to a given point in global coordinates of the top-level window. 506 void scrollToGlobalPoint(const IntPoint&) const; 507 virtual void setFocused(bool) { } 508 virtual void setSelected(bool) { } 509 void setSelectedText(const String&) { } 510 virtual void setSelectedTextRange(const PlainTextRange&) { } 511 virtual void setValue(const String&) { } 512 virtual void setValue(float) { } 513 514 // Notifications that this object may have changed. 515 virtual void childrenChanged() { } 516 virtual void handleActiveDescendantChanged() { } 517 virtual void handleAriaExpandedChanged() { } 518 void notifyIfIgnoredValueChanged(); 519 virtual void selectionChanged(); 520 virtual void textChanged() { } 521 virtual void updateAccessibilityRole() { } 522 523 // Text metrics. Most of these should be deprecated, needs major cleanup. 524 virtual VisiblePositionRange visiblePositionRange() const { return VisiblePositionRange(); } 525 virtual IntRect boundsForVisiblePositionRange(const VisiblePositionRange&) const { return IntRect(); } 526 virtual VisiblePosition visiblePositionForIndex(int) const { return VisiblePosition(); } 527 int lineForPosition(const VisiblePosition&) const; 528 virtual int index(const VisiblePosition&) const { return -1; } 529 virtual void lineBreaks(Vector<int>&) const { } 530 531 // Static helper functions. 532 static bool isARIAControl(AccessibilityRole); 533 static bool isARIAInput(AccessibilityRole); 534 static AccessibilityRole ariaRoleToWebCoreRole(const String&); 535 static IntRect boundingBoxForQuads(RenderObject*, const Vector<FloatQuad>&); 536 537 protected: 538 AXID m_id; 539 AccessibilityChildrenVector m_children; 540 mutable bool m_haveChildren; 541 AccessibilityRole m_role; 542 AccessibilityObjectInclusion m_lastKnownIsIgnoredValue; 543 LayoutRect m_explicitElementRect; 544 545 virtual bool computeAccessibilityIsIgnored() const { return true; } 546 547 // If this object itself scrolls, return its ScrollableArea. 548 virtual ScrollableArea* getScrollableAreaIfScrollable() const { return 0; } 549 virtual void scrollTo(const IntPoint&) const { } 550 551 AccessibilityRole buttonRoleType() const; 552 bool ariaIsHidden() const; 553 554 bool allowsTextRanges() const { return isTextControl(); } 555 unsigned getLengthForTextRange() const { return text().length(); } 556 557 bool m_detached; 558 }; 559 560 #if !HAVE(ACCESSIBILITY) 561 inline const AccessibilityObject::AccessibilityChildrenVector& AccessibilityObject::children() { return m_children; } 562 inline String AccessibilityObject::actionVerb() const { return emptyString(); } 563 inline int AccessibilityObject::lineForPosition(const VisiblePosition&) const { return -1; } 564 inline void AccessibilityObject::updateBackingStore() { } 565 #endif 566 567 } // namespace WebCore 568 569 #endif // AccessibilityObject_h 570