blob: 00a1da561252e3d494c9f9bb8adf65dc9ffac465 [file]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_ACCESSIBILITY_VIEW_AX_PLATFORM_NODE_DELEGATE_H_
#define UI_VIEWS_ACCESSIBILITY_VIEW_AX_PLATFORM_NODE_DELEGATE_H_
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "build/build_config.h"
#include "ui/accessibility/ax_enums.mojom-forward.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_node_position.h"
#include "ui/accessibility/platform/ax_platform_node.h"
#include "ui/accessibility/platform/ax_platform_node_delegate.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_ui_types.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/views_export.h"
namespace ui {
struct AXActionData;
} // namespace ui
namespace views {
class AtomicViewAXTreeManager;
class TableView;
class View;
// Shared base class for platforms that require an implementation of
// |ViewAXPlatformNodeDelegate| to interface with the native accessibility
// toolkit. This class owns the |AXPlatformNode|, which implements those native
// APIs.
class VIEWS_EXPORT ViewAXPlatformNodeDelegate
: public ViewAccessibility,
public ui::AXPlatformNodeDelegate {
public:
static std::unique_ptr<ViewAccessibility> CreatePlatformSpecific(View* view);
ViewAXPlatformNodeDelegate(const ViewAXPlatformNodeDelegate&) = delete;
ViewAXPlatformNodeDelegate& operator=(const ViewAXPlatformNodeDelegate&) =
delete;
~ViewAXPlatformNodeDelegate() override;
// ViewAccessibility:
void EnsureAtomicViewAXTreeManager() override;
bool IsAccessibilityFocusable() const override;
bool IsFocusedForTesting() const override;
void SetPopupFocusOverride() override;
void EndPopupFocusOverride() override;
void FireFocusAfterMenuClose() override;
gfx::NativeViewAccessible GetNativeObject() const override;
void FireNativeEvent(ax::mojom::Event event_type) override;
#if BUILDFLAG(IS_MAC)
void AnnounceTextAs(const std::u16string& text,
ui::AXPlatformNode::AnnouncementType announcement_type);
#endif
// ui::AXPlatformNodeDelegate.
const ui::AXNodeData& GetData() const override;
size_t GetChildCount() const override;
gfx::NativeViewAccessible ChildAtIndex(size_t index) const override;
bool HasModalDialog() const override;
std::wstring ComputeListItemNameFromContent() const override;
// Also in |ViewAccessibility|.
bool IsChildOfLeaf() const override;
const ui::AXSelection GetUnignoredSelection() const override;
ui::AXNodePosition::AXPositionInstance CreatePositionAt(
int offset,
ax::mojom::TextAffinity affinity) const override;
ui::AXNodePosition::AXPositionInstance CreateTextPositionAt(
int offset,
ax::mojom::TextAffinity affinity) const override;
gfx::NativeViewAccessible GetNSWindow() override;
// TODO(nektar): Make "GetNativeViewAccessible" a const method throughout the
// codebase.
gfx::NativeViewAccessible GetNativeViewAccessible() const;
gfx::NativeViewAccessible GetNativeViewAccessible() override;
gfx::NativeViewAccessible GetParent() const override;
bool IsLeaf() const override;
bool IsInvisibleOrIgnored() const override;
bool IsFocused() const override;
gfx::Rect GetBoundsRect(
const ui::AXCoordinateSystem coordinate_system,
const ui::AXClippingBehavior clipping_behavior,
ui::AXOffscreenResult* offscreen_result) const override;
gfx::Rect GetInnerTextRangeBoundsRect(
const int start_offset,
const int end_offset,
const ui::AXCoordinateSystem coordinate_system,
const ui::AXClippingBehavior clipping_behavior,
ui::AXOffscreenResult* offscreen_result) const override;
gfx::NativeViewAccessible HitTestSync(
int screen_physical_pixel_x,
int screen_physical_pixel_y) const override;
gfx::NativeViewAccessible GetFocus() const override;
ui::AXPlatformNode* GetFromNodeID(int32_t id) override;
ui::AXPlatformNode* GetFromTreeIDAndNodeID(const ui::AXTreeID& ax_tree_id,
int32_t id) override;
bool AccessibilityPerformAction(const ui::AXActionData& data) override;
bool ShouldIgnoreHoveredStateForTesting() override;
bool IsOffscreen() const override;
std::u16string GetAuthorUniqueId() const override;
bool IsMinimized() const override;
bool IsReadOnlySupported() const override;
bool IsReadOnlyOrDisabled() const override;
// Also in |ViewAccessibility|.
ui::AXPlatformNodeId GetUniqueId() const override;
std::vector<int32_t> GetColHeaderNodeIds() const override;
std::vector<int32_t> GetColHeaderNodeIds(int col_index) const override;
std::optional<int32_t> GetCellId(int row_index, int col_index) const override;
bool IsOrderedSetItem() const override;
bool IsOrderedSet() const override;
std::optional<int> GetPosInSet() const override;
std::optional<int> GetSetSize() const override;
bool TableHasColumnOrRowHeaderNodeForTesting() const;
// Return the bounds of inline text in this node's coordinate system.
gfx::RectF GetInlineTextRect(const int start_offset,
const int end_offset) const;
// Return the bounds relative to the container bounds. This functions applies
// the horizontal scroll offset and clips the bounds to the container bounds.
// TODO(accessibility): Add support for vertical scroll offsets if needed.
// There's no known use case for this yet.
gfx::RectF RelativeToContainerBounds(
const gfx::RectF& bounds,
ui::AXOffscreenResult* offscreen_result) const;
AtomicViewAXTreeManager* GetAtomicViewAXTreeManagerForTesting()
const override;
virtual gfx::Point ScreenToDIPPoint(const gfx::Point& screen_point) const;
protected:
explicit ViewAXPlatformNodeDelegate(View* view);
friend class ViewAccessibility;
// Called by ViewAccessibility::Create immediately after
// construction. Used to avoid issues with calling virtual functions
// during the constructor.
virtual void Init();
const ui::AXNodeData& data() const { return data_; }
ui::AXPlatformNode* ax_platform_node() { return ax_platform_node_.get(); }
// Manager for the accessibility tree for this view. The tree will only have
// one node, which contains the AXNodeData for this view. It's a temporary
// solution to enable the ITextRangeProvider in Views: crbug.com/1468416.
std::unique_ptr<AtomicViewAXTreeManager> atomic_view_ax_tree_manager_;
private:
friend class AtomicViewAXTreeManagerTest;
struct ChildWidgetsResult final {
ChildWidgetsResult();
ChildWidgetsResult(
std::vector<raw_ptr<Widget, VectorExperimental>> child_widgets,
bool is_tab_modal_showing);
ChildWidgetsResult(const ChildWidgetsResult& other);
~ChildWidgetsResult();
ChildWidgetsResult& operator=(const ChildWidgetsResult& other);
std::vector<raw_ptr<Widget, VectorExperimental>> child_widgets;
// When the focus is within a child widget, |child_widgets| contains only
// that widget. Otherwise, |child_widgets| contains all child widgets.
//
// The former arises when a modal dialog is showing. In order to support the
// "read title (NVDAKey+T)" and "read window (NVDAKey+B)" commands in the
// NVDA screen reader, we need to hide the rest of the UI from the
// accessibility tree for these commands to work properly.
bool is_tab_modal_showing = false;
};
// Uses Views::GetViewsInGroup to find nearby Views in the same group.
// Searches from the View's parent to include siblings within that group.
void GetViewsInGroupForSet(
std::vector<raw_ptr<View, VectorExperimental>>* views_in_group) const;
// If this delegate is attached to the root view, returns all the child
// widgets of this view's owning widget.
ChildWidgetsResult GetChildWidgets() const;
// Gets the real (non-virtual) TableView, otherwise nullptr.
TableView* GetAncestorTableView() const;
ui::AXPlatformNode::Pointer ax_platform_node_;
mutable ui::AXNodeData data_;
};
} // namespace views
#endif // UI_VIEWS_ACCESSIBILITY_VIEW_AX_PLATFORM_NODE_DELEGATE_H_