
/*
 * 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
