blob: 32b9d2e9177519eb5eb575840f50eeedfb167ce1 [file] [log] [blame]
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* 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 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.
*/
#pragma once
#include "AccessibilityObject.h"
#include "LayoutRect.h"
#include <wtf/Forward.h>
namespace WebCore {
class AXObjectCache;
class Element;
class HTMLLabelElement;
class Node;
class AccessibilityNodeObject : public AccessibilityObject {
public:
static Ref<AccessibilityNodeObject> create(AXID, Node&, AXObjectCache&);
virtual ~AccessibilityNodeObject();
void init() override;
bool hasElementDescendant() const final;
bool isBusy() const final;
bool isDetached() const override { return !m_node; }
bool isFieldset() const final;
bool isMultiSelectable() const override;
bool isNativeImage() const;
bool isNativeTextControl() const final;
bool isSecureField() const final;
bool isSearchField() const final;
bool isChecked() const final;
bool isEnabled() const override;
bool isIndeterminate() const override;
bool isPressed() const final;
bool isRequired() const final;
bool supportsARIAOwns() const final;
bool supportsDropping() const final;
bool supportsDragging() const final;
bool isGrabbed() final;
Vector<String> determineDropEffects() const final;
bool canSetSelectedAttribute() const override;
Node* node() const final { return m_node.get(); }
Document* document() const override;
LocalFrameView* documentFrameView() const override;
void setFocused(bool) override;
bool isFocused() const final;
bool canSetFocusAttribute() const override;
bool canSetValueAttribute() const override;
String valueDescription() const override;
float valueForRange() const override;
float maxValueForRange() const override;
float minValueForRange() const override;
float stepValueForRange() const override;
std::optional<AccessibilityOrientation> orientationFromARIA() const;
std::optional<AccessibilityOrientation> explicitOrientation() const override { return orientationFromARIA(); }
AccessibilityButtonState checkboxOrRadioValue() const final;
URL url() const override;
String textUnderElement(TextUnderElementMode = TextUnderElementMode()) const override;
String accessibilityDescriptionForChildren() const;
String description() const override;
String helpText() const override;
String title() const override;
String text() const final;
void alternativeText(Vector<AccessibilityText>&) const;
void helpText(Vector<AccessibilityText>&) const;
String stringValue() const override;
WallTime dateTimeValue() const final;
SRGBA<uint8_t> colorValue() const final;
String ariaLabeledByAttribute() const final;
bool hasAccNameAttribute() const;
bool hasAttributesRequiredForInclusion() const final;
bool hasClickHandler() const final;
void setIsExpanded(bool) final;
Element* actionElement() const override;
Element* anchorElement() const override;
RefPtr<Element> popoverTargetElement() const final;
RefPtr<Element> commandForElement() const final;
CommandType commandType() const final;
AccessibilityObject* internalLinkElement() const final;
AccessibilityChildrenVector radioButtonGroup() const final;
virtual void changeValueByPercent(float percentChange);
AccessibilityObject* firstChild() const override;
AccessibilityObject* lastChild() const override;
AccessibilityObject* previousSibling() const override;
AccessibilityObject* nextSibling() const override;
AccessibilityObject* parentObject() const override;
bool matchesTextAreaRole() const;
void increment() override;
void decrement() override;
bool toggleDetailsAncestor() final;
LayoutRect elementRect() const override;
#if ENABLE(AX_THREAD_TEXT_APIS)
TextEmissionBehavior textEmissionBehavior() const final;
#endif
protected:
explicit AccessibilityNodeObject(AXID, Node*, AXObjectCache&);
void detachRemoteParts(AccessibilityDetachmentType) override;
AccessibilityRole m_ariaRole { AccessibilityRole::Unknown };
// FIXME: These `is_` member variables should be replaced with an enum or be computed on demand.
// Only used by AccessibilityTableCell, but placed here to use space that would otherwise be taken by padding.
bool m_isARIAGridCell { false };
// Only used by AccessibilitySVGObject, but placed here to use space that would otherwise be taken by padding.
bool m_isSVGRoot { false };
#ifndef NDEBUG
bool m_initialized { false };
#endif
AccessibilityRole determineAccessibilityRole() override;
enum class TreatStyleFormatGroupAsInline : bool { No, Yes };
AccessibilityRole determineAccessibilityRoleFromNode(TreatStyleFormatGroupAsInline = TreatStyleFormatGroupAsInline::No) const;
AccessibilityRole roleFromInputElement(const HTMLInputElement&) const;
AccessibilityRole ariaRoleAttribute() const final { return m_ariaRole; }
virtual AccessibilityRole determineAriaRoleAttribute() const;
AccessibilityRole remapAriaRoleDueToParent(AccessibilityRole) const;
bool computeIsIgnored() const override;
void addChildren() override;
void clearChildren() override;
void updateChildrenIfNecessary() override;
bool canHaveChildren() const override;
AccessibilityChildrenVector visibleChildren() override;
bool isDescendantOfBarrenParent() const final;
void updateOwnedChildren();
AccessibilityObject* ownerParentObject() const;
enum class StepAction : bool { Decrement, Increment };
void alterRangeValue(StepAction);
void changeValueByStep(StepAction);
// This returns true if it's focusable but it's not content editable and it's not a control or ARIA control.
bool isGenericFocusableElement() const;
VisiblePositionRange visiblePositionRange() const final;
VisiblePositionRange selectedVisiblePositionRange() const final;
VisiblePositionRange visiblePositionRangeForLine(unsigned) const final;
VisiblePosition visiblePositionForIndex(int) const override;
int indexForVisiblePosition(const VisiblePosition&) const override;
bool elementAttributeValue(const QualifiedName&) const;
const String explicitLiveRegionStatus() const final { return getAttribute(HTMLNames::aria_liveAttr); }
const String explicitLiveRegionRelevant() const final { return getAttribute(HTMLNames::aria_relevantAttr); }
bool liveRegionAtomic() const final;
String accessKey() const final;
bool isLabelable() const;
AccessibilityObject* controlForLabelElement() const final;
String textAsLabelFor(const AccessibilityObject&) const;
String textForLabelElements(Vector<Ref<HTMLElement>>&&) const;
HTMLLabelElement* labelElementContainer() const;
String ariaAccessibilityDescription() const;
Vector<Ref<Element>> ariaLabeledByElements() const;
String descriptionForElements(const Vector<Ref<Element>>&) const;
LayoutRect boundingBoxRect() const override;
LayoutRect nonEmptyAncestorBoundingBox() const;
String ariaDescribedByAttribute() const final;
AccessibilityObject* captionForFigure() const;
virtual void labelText(Vector<AccessibilityText>&) const;
private:
bool isAccessibilityNodeObject() const final { return true; }
void accessibilityText(Vector<AccessibilityText>&) const override;
void visibleText(Vector<AccessibilityText>&) const;
String alternativeTextForWebArea() const;
void ariaLabeledByText(Vector<AccessibilityText>&) const;
bool usesAltForTextComputation() const;
bool roleIgnoresTitle() const;
bool postKeyboardKeysForValueChange(StepAction);
void setNodeValue(StepAction, float);
bool performDismissAction() final;
bool hasTextAlternative() const;
LayoutRect checkboxOrRadioRect() const;
void setNeedsToUpdateChildren() override { m_childrenDirty = true; }
bool needsToUpdateChildren() const final { return m_childrenDirty; }
void setNeedsToUpdateSubtree() final { m_subtreeDirty = true; }
bool isDescendantOfElementType(const HashSet<QualifiedName>&) const;
protected:
WeakPtr<Node, WeakPtrImplWithEventTargetData> m_node;
};
namespace Accessibility {
RefPtr<HTMLElement> controlForLabelElement(const HTMLLabelElement&);
Vector<Ref<HTMLElement>> labelsForElement(Element*);
} // namespace Accessibility
} // namespace WebCore
SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::AccessibilityNodeObject) \
static bool isType(const WebCore::AccessibilityObject& object) { return object.isAccessibilityNodeObject(); } \
SPECIALIZE_TYPE_TRAITS_END()