blob: f94ffcb98b34e2d46ba400481662a1ac74ba5c09 [file] [log] [blame]
/*
* Copyright (C) 2008, 2009, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nuanti Ltd.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AXObjectImpl_h
#define AXObjectImpl_h
#include "core/dom/AXObject.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/markers/DocumentMarker.h"
#include "core/inspector/protocol/Accessibility.h"
#include "modules/ModulesExport.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/LayoutRect.h"
#include "platform/graphics/Color.h"
#include "platform/wtf/Forward.h"
#include "platform/wtf/Vector.h"
class SkMatrix44;
namespace blink {
class AXObjectImpl;
class AXObjectCacheImpl;
class Element;
class FrameView;
class IntPoint;
class Node;
class LayoutObject;
class ScrollableArea;
enum class AOMBooleanProperty;
enum class AOMStringProperty;
enum class AOMUIntProperty;
enum class AOMIntProperty;
enum class AOMFloatProperty;
typedef unsigned AXID;
enum AccessibilityTextSource {
kAlternativeText,
kChildrenText,
kSummaryText,
kHelpText,
kVisibleText,
kTitleTagText,
kPlaceholderText,
kLabelByElementText,
};
class AccessibilityText final
: public GarbageCollectedFinalized<AccessibilityText> {
WTF_MAKE_NONCOPYABLE(AccessibilityText);
public:
DEFINE_INLINE_TRACE() { visitor->Trace(text_element_); }
private:
AccessibilityText(const String& text,
const AccessibilityTextSource& source,
AXObjectImpl* element)
: text_(text), text_element_(element) {}
String text_;
Member<AXObjectImpl> text_element_;
};
enum AXObjectInclusion {
kIncludeObject,
kIgnoreObject,
kDefaultBehavior,
};
enum AccessibilityButtonState {
kButtonStateOff = 0,
kButtonStateOn,
kButtonStateMixed,
};
enum AccessibilityOptionalBool {
kOptionalBoolUndefined = 0,
kOptionalBoolTrue,
kOptionalBoolFalse
};
enum TextUnderElementMode {
kTextUnderElementAll,
kTextUnderElementAny // If the text is unimportant, just whether or not it's
// present
};
enum class AXBoolAttribute {};
class AXSparseAttributeClient {
public:
virtual void AddBoolAttribute(AXBoolAttribute, bool) = 0;
virtual void AddStringAttribute(AXStringAttribute, const String&) = 0;
virtual void AddObjectAttribute(AXObjectAttribute, AXObjectImpl&) = 0;
virtual void AddObjectVectorAttribute(AXObjectVectorAttribute,
HeapVector<Member<AXObjectImpl>>&) = 0;
};
// The potential native HTML-based text (name, description or placeholder)
// sources for an element. See
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation
enum AXTextFromNativeHTML {
kAXTextFromNativeHTMLUninitialized = -1,
kAXTextFromNativeHTMLFigcaption,
kAXTextFromNativeHTMLLabel,
kAXTextFromNativeHTMLLabelFor,
kAXTextFromNativeHTMLLabelWrapped,
kAXTextFromNativeHTMLLegend,
kAXTextFromNativeHTMLTableCaption,
kAXTextFromNativeHTMLTitleElement,
};
enum AXIgnoredReason {
kAXActiveModalDialog,
kAXAncestorDisallowsChild,
kAXAncestorIsLeafNode,
kAXAriaHiddenElement,
kAXAriaHiddenSubtree,
kAXEmptyAlt,
kAXEmptyText,
kAXInertElement,
kAXInertSubtree,
kAXInheritsPresentation,
kAXLabelContainer,
kAXLabelFor,
kAXNotRendered,
kAXNotVisible,
kAXPresentationalRole,
kAXProbablyPresentational,
kAXStaticTextUsedAsNameFor,
kAXUninteresting
};
class IgnoredReason {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
AXIgnoredReason reason;
Member<const AXObjectImpl> related_object;
explicit IgnoredReason(AXIgnoredReason reason)
: reason(reason), related_object(nullptr) {}
IgnoredReason(AXIgnoredReason r, const AXObjectImpl* obj)
: reason(r), related_object(obj) {}
DEFINE_INLINE_TRACE() { visitor->Trace(related_object); }
};
class NameSourceRelatedObject
: public GarbageCollectedFinalized<NameSourceRelatedObject> {
WTF_MAKE_NONCOPYABLE(NameSourceRelatedObject);
public:
WeakMember<AXObjectImpl> object;
String text;
NameSourceRelatedObject(AXObjectImpl* object, String text)
: object(object), text(text) {}
DEFINE_INLINE_TRACE() { visitor->Trace(object); }
};
typedef HeapVector<Member<NameSourceRelatedObject>> AXRelatedObjectVector;
class NameSource {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
String text;
bool superseded = false;
bool invalid = false;
AXNameFrom type = kAXNameFromUninitialized;
const QualifiedName& attribute;
AtomicString attribute_value;
AXTextFromNativeHTML native_source = kAXTextFromNativeHTMLUninitialized;
AXRelatedObjectVector related_objects;
NameSource(bool superseded, const QualifiedName& attr)
: superseded(superseded), attribute(attr) {}
explicit NameSource(bool superseded)
: superseded(superseded), attribute(QualifiedName::Null()) {}
DEFINE_INLINE_TRACE() { visitor->Trace(related_objects); }
};
class DescriptionSource {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
String text;
bool superseded = false;
bool invalid = false;
AXDescriptionFrom type = kAXDescriptionFromUninitialized;
const QualifiedName& attribute;
AtomicString attribute_value;
AXTextFromNativeHTML native_source = kAXTextFromNativeHTMLUninitialized;
AXRelatedObjectVector related_objects;
DescriptionSource(bool superseded, const QualifiedName& attr)
: superseded(superseded), attribute(attr) {}
explicit DescriptionSource(bool superseded)
: superseded(superseded), attribute(QualifiedName::Null()) {}
DEFINE_INLINE_TRACE() { visitor->Trace(related_objects); }
};
} // namespace blink
WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::IgnoredReason);
WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::NameSource);
WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::DescriptionSource);
namespace blink {
class MODULES_EXPORT AXObjectImpl
: public GarbageCollectedFinalized<AXObjectImpl>,
public AXObject {
WTF_MAKE_NONCOPYABLE(AXObjectImpl);
public:
typedef HeapVector<Member<AXObjectImpl>> AXObjectVector;
struct AXRange {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
// The deepest descendant in which the range starts.
// (nullptr means the current object.)
Persistent<AXObjectImpl> anchor_object;
// The number of characters and child objects in the anchor object
// before the range starts.
int anchor_offset;
// When the same character offset could correspond to two possible
// cursor positions, upstream means it's on the previous line rather
// than the next line.
TextAffinity anchor_affinity;
// The deepest descendant in which the range ends.
// (nullptr means the current object.)
Persistent<AXObjectImpl> focus_object;
// The number of characters and child objects in the focus object
// before the range ends.
int focus_offset;
// When the same character offset could correspond to two possible
// cursor positions, upstream means it's on the previous line rather
// than the next line.
TextAffinity focus_affinity;
AXRange()
: anchor_object(nullptr),
anchor_offset(-1),
anchor_affinity(TextAffinity::kUpstream),
focus_object(nullptr),
focus_offset(-1),
focus_affinity(TextAffinity::kDownstream) {}
AXRange(int start_offset, int end_offset)
: anchor_object(nullptr),
anchor_offset(start_offset),
anchor_affinity(TextAffinity::kUpstream),
focus_object(nullptr),
focus_offset(end_offset),
focus_affinity(TextAffinity::kDownstream) {}
AXRange(AXObjectImpl* anchor_object,
int anchor_offset,
TextAffinity anchor_affinity,
AXObjectImpl* focus_object,
int focus_offset,
TextAffinity focus_affinity)
: anchor_object(anchor_object),
anchor_offset(anchor_offset),
anchor_affinity(anchor_affinity),
focus_object(focus_object),
focus_offset(focus_offset),
focus_affinity(focus_affinity) {}
bool IsValid() const {
return ((anchor_object && focus_object) ||
(!anchor_object && !focus_object)) &&
anchor_offset >= 0 && focus_offset >= 0;
}
// Determines if the range only refers to text offsets under the current
// object.
bool IsSimple() const {
return anchor_object == focus_object || !anchor_object || !focus_object;
}
};
protected:
AXObjectImpl(AXObjectCacheImpl&);
public:
virtual ~AXObjectImpl();
DECLARE_VIRTUAL_TRACE();
static unsigned NumberOfLiveAXObjects() { return number_of_live_ax_objects_; }
// After constructing an AXObjectImpl, it must be given a
// unique ID, then added to AXObjectCacheImpl, and finally init() must
// be called last.
void SetAXObjectID(AXID ax_object_id) { id_ = ax_object_id; }
virtual void Init() {}
// When the corresponding WebCore object that this AXObjectImpl
// wraps is deleted, it must be detached.
virtual void Detach();
virtual bool IsDetached() const;
// If the parent of this object is known, this can be faster than using
// computeParent().
virtual void SetParent(AXObjectImpl* parent) { parent_ = parent; }
// The AXObjectCacheImpl that owns this object, and its unique ID within this
// cache.
AXObjectCacheImpl& AxObjectCache() const {
DCHECK(ax_object_cache_);
return *ax_object_cache_;
}
AXID AxObjectID() const { return id_; }
// Wrappers that retrieve either an Accessibility Object Model property,
// or the equivalent ARIA attribute, in that order.
const AtomicString& GetAOMPropertyOrARIAAttribute(AOMStringProperty) const;
bool HasAOMPropertyOrARIAAttribute(AOMBooleanProperty, bool& result) const;
bool AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty) const;
bool AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty) const;
bool HasAOMPropertyOrARIAAttribute(AOMUIntProperty, uint32_t& result) const;
bool HasAOMPropertyOrARIAAttribute(AOMIntProperty, int32_t& result) const;
bool HasAOMPropertyOrARIAAttribute(AOMFloatProperty, float& result) const;
virtual void GetSparseAXAttributes(AXSparseAttributeClient&) const {}
// Determine subclass type.
virtual bool IsAXNodeObject() const { return false; }
virtual bool IsAXLayoutObject() const { return false; }
virtual bool IsAXInlineTextBox() const { return false; }
virtual bool IsAXListBox() const { return false; }
virtual bool IsAXListBoxOption() const { return false; }
virtual bool IsAXRadioInput() const { return false; }
virtual bool IsAXSVGRoot() const { return false; }
// Check object role or purpose.
virtual AccessibilityRole RoleValue() const { return role_; }
bool IsARIATextControl() const;
virtual bool IsARIATreeGridRow() const { return false; }
virtual bool IsAXTable() const { return false; }
virtual bool IsAnchor() const { return false; }
bool IsButton() const;
bool IsCheckable() const;
bool IsCanvas() const { return RoleValue() == kCanvasRole; }
bool IsCheckbox() const { return RoleValue() == kCheckBoxRole; }
bool IsCheckboxOrRadio() const { return IsCheckbox() || IsRadioButton(); }
bool IsColorWell() const { return RoleValue() == kColorWellRole; }
bool IsComboBox() const { return RoleValue() == kComboBoxRole; }
virtual bool IsControl() const { return false; }
virtual bool IsDataTable() const { return false; }
virtual bool IsEmbeddedObject() const { return false; }
virtual bool IsFieldset() const { return false; }
virtual bool IsHeading() const { return false; }
virtual bool IsImage() const { return false; }
virtual bool IsImageMapLink() const { return false; }
virtual bool IsInputImage() const { return false; }
bool IsLandmarkRelated() const;
virtual bool IsLink() const { return false; }
virtual bool IsInPageLinkTarget() const { return false; }
virtual bool IsList() const { return false; }
virtual bool IsMenu() const { return false; }
virtual bool IsMenuButton() const { return false; }
virtual bool IsMenuList() const { return false; }
virtual bool IsMenuListOption() const { return false; }
virtual bool IsMenuListPopup() const { return false; }
bool IsMenuRelated() const;
virtual bool IsMeter() const { return false; }
virtual bool IsMockObject() const { return false; }
virtual bool IsNativeSpinButton() const { return false; }
virtual bool IsNativeTextControl() const {
return false;
} // input or textarea
virtual bool IsNonNativeTextControl() const {
return false;
} // contenteditable or role=textbox
virtual bool IsPasswordField() const { return false; }
virtual bool IsPasswordFieldAndShouldHideValue() const;
bool IsPresentational() const {
return RoleValue() == kNoneRole || RoleValue() == kPresentationalRole;
}
virtual bool IsProgressIndicator() const { return false; }
bool IsRadioButton() const { return RoleValue() == kRadioButtonRole; }
bool IsRange() const {
return RoleValue() == kProgressIndicatorRole ||
RoleValue() == kScrollBarRole || RoleValue() == kSliderRole ||
RoleValue() == kSpinButtonRole || IsMoveableSplitter();
}
bool IsScrollbar() const { return RoleValue() == kScrollBarRole; }
virtual bool IsSlider() const { return false; }
virtual bool IsNativeSlider() const { return false; }
virtual bool IsMoveableSplitter() const { return false; }
virtual bool IsSpinButton() const { return RoleValue() == kSpinButtonRole; }
virtual bool IsSpinButtonPart() const { return false; }
bool IsTabItem() const { return RoleValue() == kTabRole; }
virtual bool IsTableCell() const { return false; }
virtual bool IsTableRow() const { return false; }
virtual bool IsTextControl() const { return false; }
virtual bool IsTableCol() const { return false; }
bool IsTree() const { return RoleValue() == kTreeRole; }
bool IsWebArea() const { return RoleValue() == kWebAreaRole; }
// Check object state.
virtual bool IsClickable() const;
virtual bool IsCollapsed() const { return false; }
virtual bool IsEnabled() const { return false; }
virtual AccessibilityExpanded IsExpanded() const {
return kExpandedUndefined;
}
virtual bool IsFocused() const { return false; }
virtual bool IsHovered() const { return false; }
virtual bool IsLinked() const { return false; }
virtual bool IsLoaded() const { return false; }
virtual bool IsModal() const { return false; }
virtual bool IsMultiSelectable() const { return false; }
virtual bool IsOffScreen() const { return false; }
virtual bool IsPressed() const { return false; }
virtual bool IsReadOnly() const { return false; }
virtual bool IsRequired() const { return false; }
virtual bool IsSelected() const { return false; }
virtual bool IsSelectedOptionActive() const { return false; }
virtual bool IsVisible() const { return true; }
virtual bool IsVisited() const { return false; }
// Check whether certain properties can be modified.
virtual bool CanSetFocusAttribute() const { return false; }
virtual bool CanSetValueAttribute() const { return false; }
virtual bool CanSetSelectedAttribute() const { return false; }
// Whether objects are ignored, i.e. not included in the tree.
bool AccessibilityIsIgnored();
typedef HeapVector<IgnoredReason> IgnoredReasons;
virtual bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const {
return true;
}
bool AccessibilityIsIgnoredByDefault(IgnoredReasons* = nullptr) const;
AXObjectInclusion AccessibilityPlatformIncludesObject() const;
virtual AXObjectInclusion DefaultObjectInclusion(
IgnoredReasons* = nullptr) const;
bool IsInertOrAriaHidden() const;
const AXObjectImpl* AriaHiddenRoot() const;
bool ComputeIsInertOrAriaHidden(IgnoredReasons* = nullptr) const;
bool IsDescendantOfLeafNode() const;
AXObjectImpl* LeafNodeAncestor() const;
bool IsDescendantOfDisabledNode() const;
const AXObjectImpl* DisabledAncestor() const;
bool LastKnownIsIgnoredValue();
void SetLastKnownIsIgnoredValue(bool);
bool HasInheritedPresentationalRole() const;
bool IsPresentationalChild() const;
bool AncestorExposesActiveDescendant() const;
bool ComputeAncestorExposesActiveDescendant() const;
//
// Accessible name calculation
//
// Retrieves the accessible name of the object, an enum indicating where the
// name was derived from, and a list of objects that were used to derive the
// name, if any.
virtual String GetName(AXNameFrom&, AXObjectVector* name_objects) const;
typedef HeapVector<NameSource> NameSources;
// Retrieves the accessible name of the object and a list of all potential
// sources for the name, indicating which were used.
virtual String GetName(NameSources*) const;
typedef HeapVector<DescriptionSource> DescriptionSources;
// Takes the result of nameFrom from calling |name|, above, and retrieves the
// accessible description of the object, which is secondary to |name|, an enum
// indicating where the description was derived from, and a list of objects
// that were used to derive the description, if any.
virtual String Description(AXNameFrom,
AXDescriptionFrom&,
AXObjectVector* description_objects) const {
return String();
}
// Same as above, but returns a list of all potential sources for the
// description, indicating which were used.
virtual String Description(AXNameFrom,
AXDescriptionFrom&,
DescriptionSources*,
AXRelatedObjectVector*) const {
return String();
}
// Takes the result of nameFrom and descriptionFrom from calling |name| and
// |description|, above, and retrieves the placeholder of the object, if
// present and if it wasn't already exposed by one of the two functions above.
virtual String Placeholder(AXNameFrom) const { return String(); }
// Internal functions used by name and description, above.
typedef HeapHashSet<Member<const AXObjectImpl>> AXObjectSet;
virtual String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
AXNameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
return String();
}
virtual String TextFromDescendants(AXObjectSet& visited,
bool recursive) const {
return String();
}
// Returns result of Accessible Name Calculation algorithm.
// This is a simpler high-level interface to |name| used by Inspector.
String ComputedName() const;
// Internal function used to determine whether the result of calling |name| on
// this object would return text that came from the an HTML label element or
// not. This is intended to be faster than calling |name| or
// |textAlternative|, and without side effects (it won't call
// axObjectCache->getOrCreate).
virtual bool NameFromLabelElement() const { return false; }
//
// Properties of static elements.
//
virtual const AtomicString& AccessKey() const { return g_null_atom; }
RGBA32 BackgroundColor() const;
virtual RGBA32 ComputeBackgroundColor() const { return Color::kTransparent; }
virtual RGBA32 GetColor() const { return Color::kBlack; }
// Used by objects of role ColorWellRole.
virtual RGBA32 ColorValue() const { return Color::kTransparent; }
virtual bool CanvasHasFallbackContent() const { return false; }
virtual String FontFamily() const { return g_null_atom; }
// Font size is in pixels.
virtual float FontSize() const { return 0.0f; }
// Value should be 1-based. 0 means not supported.
virtual int HeadingLevel() const { return 0; }
// Value should be 1-based. 0 means not supported.
virtual unsigned HierarchicalLevel() const { return 0; }
// Return the content of an image or canvas as an image data url in
// PNG format. If |maxSize| is not empty and if the image is larger than
// those dimensions, the image will be resized proportionally first to fit.
virtual String ImageDataUrl(const IntSize& max_size) const {
return g_null_atom;
}
virtual AXObjectImpl* InPageLinkTarget() const { return nullptr; }
virtual AccessibilityOrientation Orientation() const;
virtual String GetText() const { return String(); }
virtual AccessibilityTextDirection GetTextDirection() const {
return kAccessibilityTextDirectionLTR;
}
virtual int TextLength() const { return 0; }
virtual TextStyle GetTextStyle() const { return kTextStyleNone; }
virtual AXObjectVector RadioButtonsInGroup() const {
return AXObjectVector();
}
virtual KURL Url() const { return KURL(); }
// Load inline text boxes for just this node, even if
// settings->inlineTextBoxAccessibilityEnabled() is false.
virtual void LoadInlineTextBoxes() {}
// Walk the AXObjects on the same line. This is supported on any
// object type but primarily intended to be used for inline text boxes.
virtual AXObjectImpl* NextOnLine() const { return nullptr; }
virtual AXObjectImpl* PreviousOnLine() const { return nullptr; }
// For all node objects. The start and end character offset of each
// marker, such as spelling or grammar error.
virtual void Markers(Vector<DocumentMarker::MarkerType>&,
Vector<AXRange>&) const {}
// For an inline text box.
// The integer horizontal pixel offset of each character in the string;
// negative values for RTL.
virtual void TextCharacterOffsets(Vector<int>&) const {}
// The start and end character offset of each word in the object's text.
virtual void GetWordBoundaries(Vector<AXRange>&) const {}
// Properties of interactive elements.
AXDefaultActionVerb Action() const;
AccessibilityButtonState CheckedState() const;
virtual AriaCurrentState GetAriaCurrentState() const {
return kAriaCurrentStateUndefined;
}
virtual InvalidState GetInvalidState() const {
return kInvalidStateUndefined;
}
// Only used when invalidState() returns InvalidStateOther.
virtual String AriaInvalidValue() const { return String(); }
virtual String ValueDescription() const { return String(); }
virtual float ValueForRange() const { return 0.0f; }
virtual float MaxValueForRange() const { return 0.0f; }
virtual float MinValueForRange() const { return 0.0f; }
virtual String StringValue() const { return String(); }
// ARIA attributes.
virtual AXObjectImpl* ActiveDescendant() { return nullptr; }
virtual String AriaAutoComplete() const { return String(); }
virtual void AriaOwnsElements(AXObjectVector& owns) const {}
virtual void AriaDescribedbyElements(AXObjectVector&) const {}
virtual void AriaLabelledbyElements(AXObjectVector&) const {}
virtual bool AriaHasPopup() const { return false; }
virtual bool IsEditable() const { return false; }
bool IsMultiline() const;
virtual bool IsRichlyEditable() const { return false; }
bool AriaPressedIsPresent() const;
virtual AccessibilityRole AriaRoleAttribute() const { return kUnknownRole; }
virtual bool AriaRoleHasPresentationalChildren() const { return false; }
virtual AXObjectImpl* AncestorForWhichThisIsAPresentationalChild() const {
return 0;
}
bool SupportsActiveDescendant() const;
bool SupportsARIAAttributes() const;
virtual bool SupportsARIADragging() const { return false; }
virtual bool SupportsARIADropping() const { return false; }
virtual bool SupportsARIAFlowTo() const { return false; }
virtual bool SupportsARIAOwns() const { return false; }
bool SupportsRangeValue() const;
virtual SortDirection GetSortDirection() const {
return kSortDirectionUndefined;
}
// Returns 0-based index.
int IndexInParent() const;
// Value should be 1-based. 0 means not supported.
virtual int PosInSet() const { return 0; }
virtual int SetSize() const { return 0; }
bool SupportsSetSizeAndPosInSet() const;
// ARIA live-region features.
bool IsLiveRegion() const;
AXObjectImpl* LiveRegionRoot() const;
virtual const AtomicString& LiveRegionStatus() const { return g_null_atom; }
virtual const AtomicString& LiveRegionRelevant() const { return g_null_atom; }
virtual bool LiveRegionAtomic() const { return false; }
virtual bool LiveRegionBusy() const { return false; }
const AtomicString& ContainerLiveRegionStatus() const;
const AtomicString& ContainerLiveRegionRelevant() const;
bool ContainerLiveRegionAtomic() const;
bool ContainerLiveRegionBusy() const;
// Every object's bounding box is returned relative to a
// container object (which is guaranteed to be an ancestor) and
// optionally a transformation matrix that needs to be applied too.
// To compute the absolute bounding box of an element, start with its
// boundsInContainer and apply the transform. Then as long as its container is
// not null, walk up to its container and offset by the container's offset
// from origin, the container's scroll position if any, and apply the
// container's transform. Do this until you reach the root of the tree.
virtual void GetRelativeBounds(AXObjectImpl** out_container,
FloatRect& out_bounds_in_container,
SkMatrix44& out_container_transform) const;
// Get the bounds in frame-relative coordinates as a LayoutRect.
LayoutRect GetBoundsInFrameCoordinates() const;
// Explicitly set an object's bounding rect and offset container.
void SetElementRect(LayoutRect r, AXObjectImpl* container) {
explicit_element_rect_ = r;
explicit_container_id_ = container->AxObjectID();
}
// Hit testing.
// Called on the root AX object to return the deepest available element.
virtual AXObjectImpl* AccessibilityHitTest(const IntPoint&) const {
return 0;
}
// Called on the AX object after the layout tree determines which is the right
// AXLayoutObject.
virtual AXObjectImpl* ElementAccessibilityHitTest(const IntPoint&) const;
// High-level accessibility tree access. Other modules should only use these
// functions.
const AXObjectVector& Children();
AXObjectImpl* ParentObject() const;
AXObjectImpl* ParentObjectIfExists() const;
virtual AXObjectImpl* ComputeParent() const = 0;
virtual AXObjectImpl* ComputeParentIfExists() const { return 0; }
AXObjectImpl* CachedParentObject() const { return parent_; }
AXObjectImpl* ParentObjectUnignored() const;
// Low-level accessibility tree exploration, only for use within the
// accessibility module.
virtual AXObjectImpl* RawFirstChild() const { return 0; }
virtual AXObjectImpl* RawNextSibling() const { return 0; }
virtual void AddChildren() {}
virtual bool CanHaveChildren() const { return true; }
bool HasChildren() const { return have_children_; }
virtual void UpdateChildrenIfNecessary();
virtual bool NeedsToUpdateChildren() const { return false; }
virtual void SetNeedsToUpdateChildren() {}
virtual void ClearChildren();
virtual void DetachFromParent() { parent_ = 0; }
virtual AXObjectImpl* ScrollBar(AccessibilityOrientation) { return 0; }
// Properties of the object's owning document or page.
virtual double EstimatedLoadingProgress() const { return 0; }
// DOM and layout tree access.
virtual Node* GetNode() const { return nullptr; }
virtual Element* GetElement() const; // Same as GetNode, if it's an Element.
virtual LayoutObject* GetLayoutObject() const { return nullptr; }
virtual Document* GetDocument() const;
virtual FrameView* DocumentFrameView() const;
virtual Element* AnchorElement() const { return nullptr; }
virtual Element* ActionElement() const { return nullptr; }
String Language() const;
bool HasAttribute(const QualifiedName&) const;
const AtomicString& GetAttribute(const QualifiedName&) const;
// Methods that retrieve or manipulate the current selection.
// Get the current selection from anywhere in the accessibility tree.
virtual AXRange Selection() const { return AXRange(); }
// Gets only the start and end offsets of the selection computed using the
// current object as the starting point. Returns a null selection if there is
// no selection in the subtree rooted at this object.
virtual AXRange SelectionUnderObject() const { return AXRange(); }
virtual void SetSelection(const AXRange&) {}
// Scrollable containers.
bool IsScrollableContainer() const;
IntPoint GetScrollOffset() const;
IntPoint MinimumScrollOffset() const;
IntPoint MaximumScrollOffset() const;
void SetScrollOffset(const IntPoint&) const;
// If this object itself scrolls, return its ScrollableArea.
virtual ScrollableArea* GetScrollableAreaIfScrollable() const { return 0; }
// Modify or take an action on an object.
virtual void Increment() {}
virtual void Decrement() {}
bool PerformDefaultAction() { return Press(); }
virtual bool Press();
// Make this object visible by scrolling as many nested scrollable views as
// needed.
void ScrollToMakeVisible() const;
// Same, but if the whole object can't be made visible, try for this subrect,
// in local coordinates.
void ScrollToMakeVisibleWithSubFocus(const IntRect&) const;
// Scroll this object to a given point in global coordinates of the top-level
// window.
void ScrollToGlobalPoint(const IntPoint&) const;
virtual void SetFocused(bool) {}
virtual void SetSelected(bool) {}
virtual void SetSequentialFocusNavigationStartingPoint();
virtual void SetValue(const String&) {}
virtual void SetValue(float) {}
// Notifications that this object may have changed.
virtual void ChildrenChanged() {}
virtual void HandleActiveDescendantChanged() {}
virtual void HandleAriaExpandedChanged() {}
void NotifyIfIgnoredValueChanged();
virtual void SelectionChanged();
virtual void TextChanged() {}
virtual void UpdateAccessibilityRole() {}
// Text metrics. Most of these should be deprecated, needs major cleanup.
virtual VisiblePosition VisiblePositionForIndex(int) const {
return VisiblePosition();
}
int LineForPosition(const VisiblePosition&) const;
virtual int Index(const VisiblePosition&) const { return -1; }
virtual void LineBreaks(Vector<int>&) const {}
// Static helper functions.
static bool IsARIAControl(AccessibilityRole);
static bool IsARIAInput(AccessibilityRole);
static AccessibilityRole AriaRoleToWebCoreRole(const String&);
static const AtomicString& RoleName(AccessibilityRole);
static const AtomicString& InternalRoleName(AccessibilityRole);
static bool IsInsideFocusableElementOrARIAWidget(const Node&);
protected:
AXID id_;
AXObjectVector children_;
mutable bool have_children_;
AccessibilityRole role_;
AXObjectInclusion last_known_is_ignored_value_;
LayoutRect explicit_element_rect_;
AXID explicit_container_id_;
// Used only inside textAlternative():
static String CollapseWhitespace(const String&);
static String RecursiveTextAlternative(const AXObjectImpl&,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited);
bool IsHiddenForTextAlternativeCalculation() const;
String AriaTextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
AXNameFrom&,
AXRelatedObjectVector*,
NameSources*,
bool* found_text_alternative) const;
String TextFromElements(bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
HeapVector<Member<Element>>& elements,
AXRelatedObjectVector* related_objects) const;
void TokenVectorFromAttribute(Vector<String>&, const QualifiedName&) const;
void ElementsFromAttribute(HeapVector<Member<Element>>& elements,
const QualifiedName&) const;
void AriaLabelledbyElementVector(HeapVector<Member<Element>>& elements) const;
String TextFromAriaLabelledby(AXObjectSet& visited,
AXRelatedObjectVector* related_objects) const;
String TextFromAriaDescribedby(AXRelatedObjectVector* related_objects) const;
virtual const AXObjectImpl* InheritsPresentationalRoleFrom() const {
return 0;
}
bool CanReceiveAccessibilityFocus() const;
bool NameFromContents(bool recursive) const;
AccessibilityRole ButtonRoleType() const;
virtual LayoutObject* LayoutObjectForRelativeBounds() const {
return nullptr;
}
const AXObjectImpl* InertRoot() const;
mutable Member<AXObjectImpl> parent_;
// The following cached attribute values (the ones starting with m_cached*)
// are only valid if m_lastModificationCount matches
// AXObjectCacheImpl::modificationCount().
mutable int last_modification_count_;
mutable RGBA32 cached_background_color_;
mutable bool cached_is_ignored_ : 1;
mutable bool cached_is_inert_or_aria_hidden_ : 1;
mutable bool cached_is_descendant_of_leaf_node_ : 1;
mutable bool cached_is_descendant_of_disabled_node_ : 1;
mutable bool cached_has_inherited_presentational_role_ : 1;
mutable bool cached_is_presentational_child_ : 1;
mutable bool cached_ancestor_exposes_active_descendant_ : 1;
mutable Member<AXObjectImpl> cached_live_region_root_;
Member<AXObjectCacheImpl> ax_object_cache_;
// Updates the cached attribute values. This may be recursive, so to prevent
// deadlocks,
// functions called here may only search up the tree (ancestors), not down.
void UpdateCachedAttributeValuesIfNeeded() const;
private:
static bool IsNativeInputInMixedState(const Node*);
static bool IncludesARIAWidgetRole(const String&);
static bool HasInteractiveARIAAttribute(const Element&);
static unsigned number_of_live_ax_objects_;
};
DEFINE_TYPE_CASTS(AXObjectImpl, AXObject, obj, true, true);
#define DEFINE_AX_OBJECT_TYPE_CASTS(thisType, predicate) \
DEFINE_TYPE_CASTS(thisType, AXObjectImpl, object, object->predicate, \
object.predicate)
} // namespace blink
#endif // AXObjectImpl_h