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"
47 class HTMLAnchorElement;
48 class HTMLAreaElement;
56 class VisibleSelection;
59 typedef unsigned AXID;
61 enum AccessibilityRole {
81 DescriptionListDetailRole,
82 DescriptionListTermRole,
85 DisclosureTriangleRole,
132 ProgressIndicatorRole,
160 TableHeaderContainerRole,
171 UserInterfaceTooltipRole,
177 enum AccessibilityTextSource {
188 enum AccessibilityState {
198 AXIndeterminateState,
201 AXMultiselectableState,
213 struct AccessibilityText {
215 AccessibilityTextSource textSource;
216 RefPtr<AXObject> textElement;
218 AccessibilityText(const String& t, const AccessibilityTextSource& s)
223 AccessibilityText(const String& t, const AccessibilityTextSource& s, const RefPtr<AXObject> element)
226 , textElement(element)
230 enum AccessibilityOrientation {
231 AccessibilityOrientationVertical,
232 AccessibilityOrientationHorizontal,
235 enum AXObjectInclusion {
241 enum AccessibilityButtonState {
247 enum AccessibilityTextDirection {
248 AccessibilityTextDirectionLeftToRight,
249 AccessibilityTextDirectionRightToLeft,
250 AccessibilityTextDirectionTopToBottom,
251 AccessibilityTextDirectionBottomToTop
254 class AXObject : public RefCounted<AXObject> {
256 typedef Vector<RefPtr<AXObject> > AccessibilityChildrenVector;
258 struct PlainTextRange {
268 PlainTextRange(unsigned s, unsigned l)
273 bool isNull() const { return !start && !length; }
282 // After constructing an AXObject, it must be given a
283 // unique ID, then added to AXObjectCache, and finally init() must
285 void setAXObjectID(AXID axObjectID) { m_id = axObjectID; }
286 virtual void init() { }
288 // When the corresponding WebCore object that this AXObject
289 // wraps is deleted, it must be detached.
290 virtual void detach();
291 virtual bool isDetached() const;
293 // The AXObjectCache that owns this object, and its unique ID within this cache.
294 AXObjectCache* axObjectCache() const;
295 AXID axObjectID() const { return m_id; }
297 // Determine subclass type.
298 virtual bool isAXNodeObject() const { return false; }
299 virtual bool isAXRenderObject() const { return false; }
300 virtual bool isAXScrollbar() const { return false; }
301 virtual bool isAXScrollView() const { return false; }
302 virtual bool isAXSVGRoot() const { return false; }
304 // Check object role or purpose.
305 virtual AccessibilityRole roleValue() const { return m_role; }
306 bool isARIATextControl() const;
307 virtual bool isARIATreeGridRow() const { return false; }
308 virtual bool isAXTable() const { return false; }
309 virtual bool isAnchor() const { return false; }
310 virtual bool isAttachment() const { return false; }
311 bool isButton() const;
312 bool isCanvas() const { return roleValue() == CanvasRole; }
313 bool isCheckbox() const { return roleValue() == CheckBoxRole; }
314 bool isCheckboxOrRadio() const { return isCheckbox() || isRadioButton(); }
315 bool isColorWell() const { return roleValue() == ColorWellRole; }
316 bool isComboBox() const { return roleValue() == ComboBoxRole; }
317 virtual bool isControl() const { return false; }
318 virtual bool isDataTable() const { return false; }
319 virtual bool isEmbeddedObject() const { return false; }
320 virtual bool isFieldset() const { return false; }
321 virtual bool isFileUploadButton() const { return false; }
322 virtual bool isHeading() const { return false; }
323 virtual bool isImage() const { return false; }
324 virtual bool isImageMapLink() const { return false; }
325 virtual bool isInputImage() const { return false; }
326 bool isLandmarkRelated() const;
327 virtual bool isLink() const { return false; }
328 virtual bool isList() const { return false; }
329 bool isListItem() const { return roleValue() == ListItemRole; }
330 virtual bool isListBoxOption() const { return false; }
331 virtual bool isMenu() const { return false; }
332 virtual bool isMenuButton() const { return false; }
333 virtual bool isMenuList() const { return false; }
334 virtual bool isMenuListOption() const { return false; }
335 virtual bool isMenuListPopup() const { return false; }
336 bool isMenuRelated() const;
337 virtual bool isMockObject() const { return false; }
338 virtual bool isNativeSpinButton() const { return false; }
339 virtual bool isNativeTextControl() const { return false; } // input or textarea
340 virtual bool isNonNativeTextControl() const { return false; } // contenteditable or role=textbox
341 virtual bool isPasswordField() const { return false; }
342 virtual bool isProgressIndicator() const { return false; }
343 bool isRadioButton() const { return roleValue() == RadioButtonRole; }
344 bool isScrollbar() const { return roleValue() == ScrollBarRole; }
345 virtual bool isSlider() const { return false; }
346 virtual bool isSpinButton() const { return roleValue() == SpinButtonRole; }
347 virtual bool isSpinButtonPart() const { return false; }
348 bool isTabItem() const { return roleValue() == TabRole; }
349 virtual bool isTableCell() const { return false; }
350 virtual bool isTableRow() const { return false; }
351 virtual bool isTableCol() const { return false; }
352 bool isTextControl() const;
353 bool isTree() const { return roleValue() == TreeRole; }
354 bool isTreeItem() const { return roleValue() == TreeItemRole; }
355 bool isWebArea() const { return roleValue() == WebAreaRole; }
357 // Check object state.
358 virtual bool isChecked() const { return false; }
359 virtual bool isClickable() const;
360 virtual bool isCollapsed() const { return false; }
361 virtual bool isEnabled() const { return false; }
362 bool isExpanded() const;
363 virtual bool isFocused() const { return false; }
364 virtual bool isHovered() const { return false; }
365 virtual bool isIndeterminate() const { return false; }
366 virtual bool isLinked() const { return false; }
367 virtual bool isLoaded() const { return false; }
368 virtual bool isMultiSelectable() const { return false; }
369 virtual bool isOffScreen() const { return false; }
370 virtual bool isPressed() const { return false; }
371 virtual bool isReadOnly() const { return false; }
372 virtual bool isRequired() const { return false; }
373 virtual bool isSelected() const { return false; }
374 virtual bool isSelectedOptionActive() const { return false; }
375 virtual bool isVisible() const { return true; }
376 virtual bool isVisited() const { return false; }
378 // Check whether certain properties can be modified.
379 virtual bool canSetFocusAttribute() const { return false; }
380 virtual bool canSetValueAttribute() const { return false; }
381 virtual bool canSetSelectedAttribute() const { return false; }
383 // Whether objects are ignored, i.e. not included in the tree.
384 bool accessibilityIsIgnored() const;
385 bool accessibilityIsIgnoredByDefault() const;
386 AXObjectInclusion accessibilityPlatformIncludesObject() const;
387 virtual AXObjectInclusion defaultObjectInclusion() const;
388 bool isInertOrAriaHidden() const;
389 bool lastKnownIsIgnoredValue();
390 void setLastKnownIsIgnoredValue(bool);
392 // Properties of static elements.
393 virtual const AtomicString& accessKey() const { return nullAtom; }
394 virtual bool canvasHasFallbackContent() const { return false; }
395 virtual bool exposesTitleUIElement() const { return true; }
396 virtual int headingLevel() const { return 0; }
397 // 1-based, to match the aria-level spec.
398 virtual unsigned hierarchicalLevel() const { return 0; }
399 virtual AccessibilityOrientation orientation() const;
400 virtual String text() const { return String(); }
401 virtual int textLength() const { return 0; }
402 virtual AXObject* titleUIElement() const { return 0; }
403 virtual KURL url() const { return KURL(); }
405 // For an inline text box.
406 virtual AccessibilityTextDirection textDirection() const { return AccessibilityTextDirectionLeftToRight; }
407 // The integer horizontal pixel offset of each character in the string; negative values for RTL.
408 virtual void textCharacterOffsets(Vector<int>&) const { }
409 // The start and end character offset of each word in the inline text box.
410 virtual void wordBoundaries(Vector<PlainTextRange>& words) const { }
412 // Properties of interactive elements.
413 virtual String actionVerb() const;
414 virtual AccessibilityButtonState checkboxOrRadioValue() const;
415 virtual void colorValue(int& r, int& g, int& b) const { r = 0; g = 0; b = 0; }
416 virtual String valueDescription() const { return String(); }
417 virtual float valueForRange() const { return 0.0f; }
418 virtual float maxValueForRange() const { return 0.0f; }
419 virtual float minValueForRange() const { return 0.0f; }
420 virtual String stringValue() const { return String(); }
423 virtual AXObject* activeDescendant() const { return 0; }
424 virtual String ariaDescribedByAttribute() const { return String(); }
425 virtual void ariaFlowToElements(AccessibilityChildrenVector&) const { }
426 virtual void ariaControlsElements(AccessibilityChildrenVector&) const { }
427 virtual void ariaDescribedbyElements(AccessibilityChildrenVector& describedby) const { };
428 virtual void ariaLabelledbyElements(AccessibilityChildrenVector& labelledby) const { };
429 virtual void ariaOwnsElements(AccessibilityChildrenVector& owns) const { };
430 virtual bool ariaHasPopup() const { return false; }
431 bool ariaIsMultiline() const;
432 virtual String ariaLabeledByAttribute() const { return String(); }
433 bool ariaPressedIsPresent() const;
434 virtual AccessibilityRole ariaRoleAttribute() const { return UnknownRole; }
435 virtual bool ariaRoleHasPresentationalChildren() const { return false; }
436 virtual bool isARIAGrabbed() { return false; }
437 virtual bool isPresentationalChildOfAriaRole() const { return false; }
438 virtual bool shouldFocusActiveDescendant() const { return false; }
439 bool supportsARIAAttributes() const;
440 virtual bool supportsARIADragging() const { return false; }
441 virtual bool supportsARIADropping() const { return false; }
442 virtual bool supportsARIAFlowTo() const { return false; }
443 virtual bool supportsARIAOwns() const { return false; }
444 bool supportsRangeValue() const;
447 // Used by an ARIA tree to get all its rows.
448 void ariaTreeRows(AccessibilityChildrenVector&);
450 // ARIA live-region features.
451 bool supportsARIALiveRegion() const;
452 virtual const AtomicString& ariaLiveRegionStatus() const { return nullAtom; }
453 virtual const AtomicString& ariaLiveRegionRelevant() const { return nullAtom; }
454 virtual bool ariaLiveRegionAtomic() const { return false; }
455 virtual bool ariaLiveRegionBusy() const { return false; }
457 // Accessibility Text.
458 virtual String textUnderElement() const { return String(); }
460 // Accessibility Text - (To be deprecated).
461 virtual String accessibilityDescription() const { return String(); }
462 virtual String title() const { return String(); }
463 virtual String helpText() const { return String(); }
465 // Location and click point in frame-relative coordinates.
466 virtual LayoutRect elementRect() const { return m_explicitElementRect; }
467 void setElementRect(LayoutRect r) { m_explicitElementRect = r; }
468 virtual void markCachedElementRectDirty() const;
469 virtual IntPoint clickPoint();
472 // Called on the root AX object to return the deepest available element.
473 virtual AXObject* accessibilityHitTest(const IntPoint&) const { return 0; }
474 // Called on the AX object after the render tree determines which is the right AXRenderObject.
475 virtual AXObject* elementAccessibilityHitTest(const IntPoint&) const;
477 // High-level accessibility tree access. Other modules should only use these functions.
478 const AccessibilityChildrenVector& children();
479 virtual AXObject* parentObject() const = 0;
480 AXObject* parentObjectUnignored() const;
481 virtual AXObject* parentObjectIfExists() const { return 0; }
483 // Low-level accessibility tree exploration, only for use within the accessibility module.
484 virtual AXObject* firstChild() const { return 0; }
485 virtual AXObject* nextSibling() const { return 0; }
486 static AXObject* firstAccessibleObjectFromNode(const Node*);
487 virtual void addChildren() { }
488 virtual bool canHaveChildren() const { return true; }
489 bool hasChildren() const { return m_haveChildren; }
490 virtual void updateChildrenIfNecessary();
491 virtual bool needsToUpdateChildren() const { return false; }
492 virtual void setNeedsToUpdateChildren() { }
493 virtual void clearChildren();
494 virtual void detachFromParent() { }
495 virtual AXObject* observableObject() const { return 0; }
496 virtual AXObject* scrollBar(AccessibilityOrientation) { return 0; }
498 // Properties of the object's owning document or page.
499 virtual double estimatedLoadingProgress() const { return 0; }
500 AXObject* focusedUIElement() const;
502 // DOM and Render tree access.
503 virtual Node* node() const { return 0; }
504 virtual RenderObject* renderer() const { return 0; }
505 virtual Document* document() const;
506 virtual FrameView* documentFrameView() const;
507 virtual Element* anchorElement() const { return 0; }
508 virtual Element* actionElement() const { return 0; }
509 virtual Widget* widgetForAttachmentView() const { return 0; }
510 String language() const;
511 bool hasAttribute(const QualifiedName&) const;
512 const AtomicString& getAttribute(const QualifiedName&) const;
515 virtual PlainTextRange selectedTextRange() const { return PlainTextRange(); }
517 // Modify or take an action on an object.
518 virtual void increment() { }
519 virtual void decrement() { }
520 bool performDefaultAction() const { return press(); }
521 virtual bool press() const;
522 // Make this object visible by scrolling as many nested scrollable views as needed.
523 void scrollToMakeVisible() const;
524 // Same, but if the whole object can't be made visible, try for this subrect, in local coordinates.
525 void scrollToMakeVisibleWithSubFocus(const IntRect&) const;
526 // Scroll this object to a given point in global coordinates of the top-level window.
527 void scrollToGlobalPoint(const IntPoint&) const;
528 virtual void setFocused(bool) { }
529 virtual void setSelected(bool) { }
530 void setSelectedText(const String&) { }
531 virtual void setSelectedTextRange(const PlainTextRange&) { }
532 virtual void setValue(const String&) { }
533 virtual void setValue(float) { }
535 // Notifications that this object may have changed.
536 virtual void childrenChanged() { }
537 virtual void handleActiveDescendantChanged() { }
538 virtual void handleAriaExpandedChanged() { }
539 void notifyIfIgnoredValueChanged();
540 virtual void selectionChanged();
541 virtual void textChanged() { }
542 virtual void updateAccessibilityRole() { }
544 // Text metrics. Most of these should be deprecated, needs major cleanup.
545 virtual VisiblePosition visiblePositionForIndex(int) const { return VisiblePosition(); }
546 int lineForPosition(const VisiblePosition&) const;
547 virtual int index(const VisiblePosition&) const { return -1; }
548 virtual void lineBreaks(Vector<int>&) const { }
550 // Static helper functions.
551 static bool isARIAControl(AccessibilityRole);
552 static bool isARIAInput(AccessibilityRole);
553 static AccessibilityRole ariaRoleToWebCoreRole(const String&);
554 static IntRect boundingBoxForQuads(RenderObject*, const Vector<FloatQuad>&);
558 AccessibilityChildrenVector m_children;
559 mutable bool m_haveChildren;
560 AccessibilityRole m_role;
561 AXObjectInclusion m_lastKnownIsIgnoredValue;
562 LayoutRect m_explicitElementRect;
564 virtual bool computeAccessibilityIsIgnored() const { return true; }
566 // If this object itself scrolls, return its ScrollableArea.
567 virtual ScrollableArea* getScrollableAreaIfScrollable() const { return 0; }
568 virtual void scrollTo(const IntPoint&) const { }
570 AccessibilityRole buttonRoleType() const;
572 bool allowsTextRanges() const { return isTextControl(); }
573 unsigned getLengthForTextRange() const { return text().length(); }
578 #define DEFINE_AX_OBJECT_TYPE_CASTS(thisType, predicate) \
579 DEFINE_TYPE_CASTS(thisType, AXObject, object, object->predicate, object.predicate)