summaryrefslogtreecommitdiff
path: root/chromium/ui/views/accessibility/ax_virtual_view.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-13 15:05:36 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-14 10:33:47 +0000
commite684a3455bcc29a6e3e66a004e352dea4e1141e7 (patch)
treed55b4003bde34d7d05f558f02cfd82b2a66a7aac /chromium/ui/views/accessibility/ax_virtual_view.cc
parent2b94bfe47ccb6c08047959d1c26e392919550e86 (diff)
downloadqtwebengine-chromium-e684a3455bcc29a6e3e66a004e352dea4e1141e7.tar.gz
BASELINE: Update Chromium to 72.0.3626.110 and Ninja to 1.9.0
Change-Id: Ic57220b00ecc929a893c91f5cc552f5d3e99e922 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/ui/views/accessibility/ax_virtual_view.cc')
-rw-r--r--chromium/ui/views/accessibility/ax_virtual_view.cc281
1 files changed, 281 insertions, 0 deletions
diff --git a/chromium/ui/views/accessibility/ax_virtual_view.cc b/chromium/ui/views/accessibility/ax_virtual_view.cc
new file mode 100644
index 00000000000..f6519a599e2
--- /dev/null
+++ b/chromium/ui/views/accessibility/ax_virtual_view.cc
@@ -0,0 +1,281 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/accessibility/ax_virtual_view.h"
+
+#include <stdint.h>
+
+#include <algorithm>
+#include <utility>
+
+#include "ui/accessibility/ax_action_data.h"
+#include "ui/accessibility/ax_tree_data.h"
+#include "ui/accessibility/platform/ax_platform_node.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/views/accessibility/view_accessibility.h"
+#include "ui/views/view.h"
+#include "ui/views/widget/widget.h"
+
+namespace views {
+
+// static
+const char AXVirtualView::kViewClassName[] = "AXVirtualView";
+
+AXVirtualView::AXVirtualView()
+ : parent_view_(nullptr), virtual_parent_view_(nullptr) {
+ ax_platform_node_ = ui::AXPlatformNode::Create(this);
+ DCHECK(ax_platform_node_);
+ custom_data_.AddStringAttribute(ax::mojom::StringAttribute::kClassName,
+ GetViewClassName());
+}
+
+AXVirtualView::~AXVirtualView() {
+ DCHECK(!parent_view_ || !virtual_parent_view_)
+ << "Either |parent_view_| or |virtual_parent_view_| could be set but "
+ "not both.";
+
+ if (ax_platform_node_) {
+ ax_platform_node_->Destroy();
+ ax_platform_node_ = nullptr;
+ }
+}
+
+void AXVirtualView::AddChildView(std::unique_ptr<AXVirtualView> view) {
+ DCHECK(view);
+ if (view->virtual_parent_view_ == this)
+ return;
+ AddChildViewAt(std::move(view), GetChildCount());
+}
+
+void AXVirtualView::AddChildViewAt(std::unique_ptr<AXVirtualView> view,
+ int index) {
+ DCHECK(view);
+ CHECK_NE(view.get(), this)
+ << "You cannot add an AXVirtualView as its own child.";
+ DCHECK(!view->parent_view_) << "This |view| already has a View "
+ "parent. Call RemoveVirtualChildView first.";
+ DCHECK(!view->virtual_parent_view_) << "This |view| already has an "
+ "AXVirtualView parent. Call "
+ "RemoveChildView first.";
+ DCHECK_GE(index, 0);
+ DCHECK_LE(index, GetChildCount());
+
+ view->virtual_parent_view_ = this;
+ children_.insert(children_.begin() + index, std::move(view));
+}
+
+void AXVirtualView::ReorderChildView(AXVirtualView* view, int index) {
+ DCHECK(view);
+ if (index >= GetChildCount())
+ return;
+ if (index < 0)
+ index = GetChildCount() - 1;
+
+ DCHECK_EQ(view->virtual_parent_view_, this);
+ if (children_[index].get() == view)
+ return;
+
+ int cur_index = GetIndexOf(view);
+ if (cur_index < 0)
+ return;
+
+ std::unique_ptr<AXVirtualView> child = std::move(children_[cur_index]);
+ children_.erase(children_.begin() + cur_index);
+ children_.insert(children_.begin() + index, std::move(child));
+}
+
+std::unique_ptr<AXVirtualView> AXVirtualView::RemoveChildView(
+ AXVirtualView* view) {
+ DCHECK(view);
+ int cur_index = GetIndexOf(view);
+ if (cur_index < 0)
+ return {};
+
+ if (GetOwnerView()) {
+ ViewAccessibility& view_accessibility =
+ GetOwnerView()->GetViewAccessibility();
+ if (view_accessibility.FocusedVirtualChild() &&
+ Contains(view_accessibility.FocusedVirtualChild())) {
+ view_accessibility.OverrideFocus(nullptr);
+ }
+ }
+
+ std::unique_ptr<AXVirtualView> child = std::move(children_[cur_index]);
+ children_.erase(children_.begin() + cur_index);
+ child->virtual_parent_view_ = nullptr;
+ return child;
+}
+
+void AXVirtualView::RemoveAllChildViews() {
+ while (!children_.empty())
+ RemoveChildView(children_.back().get());
+}
+
+const AXVirtualView* AXVirtualView::child_at(int index) const {
+ DCHECK_GE(index, 0);
+ DCHECK_LT(index, static_cast<int>(children_.size()));
+ return children_[index].get();
+}
+
+AXVirtualView* AXVirtualView::child_at(int index) {
+ return const_cast<AXVirtualView*>(
+ const_cast<const AXVirtualView*>(this)->child_at(index));
+}
+
+bool AXVirtualView::Contains(const AXVirtualView* view) const {
+ DCHECK(view);
+ for (const AXVirtualView* v = view; v; v = v->virtual_parent_view_) {
+ if (v == this)
+ return true;
+ }
+ return false;
+}
+
+int AXVirtualView::GetIndexOf(const AXVirtualView* view) const {
+ DCHECK(view);
+ const auto iter =
+ std::find_if(children_.begin(), children_.end(),
+ [view](const auto& child) { return child.get() == view; });
+ return iter != children_.end() ? static_cast<int>(iter - children_.begin())
+ : -1;
+}
+
+const char* AXVirtualView::GetViewClassName() const {
+ return kViewClassName;
+}
+
+gfx::NativeViewAccessible AXVirtualView::GetNativeObject() const {
+ DCHECK(ax_platform_node_);
+ return ax_platform_node_->GetNativeViewAccessible();
+}
+
+void AXVirtualView::NotifyAccessibilityEvent(ax::mojom::Event event_type) {
+ DCHECK(ax_platform_node_);
+ ax_platform_node_->NotifyAccessibilityEvent(event_type);
+}
+
+ui::AXNodeData& AXVirtualView::GetCustomData() {
+ return custom_data_;
+}
+
+// ui::AXPlatformNodeDelegate
+
+const ui::AXNodeData& AXVirtualView::GetData() const {
+ // Make a copy of our |custom_data_| so that any modifications will not be
+ // made to the data that users of this class will be manipulating.
+ static ui::AXNodeData node_data;
+ node_data = custom_data_;
+ if (!GetOwnerView() || !GetOwnerView()->enabled())
+ node_data.SetRestriction(ax::mojom::Restriction::kDisabled);
+
+ if (!GetOwnerView() || !GetOwnerView()->IsDrawn())
+ node_data.AddState(ax::mojom::State::kInvisible);
+
+ if (GetOwnerView() && GetOwnerView()->context_menu_controller())
+ node_data.AddAction(ax::mojom::Action::kShowContextMenu);
+
+ return node_data;
+}
+
+int AXVirtualView::GetChildCount() {
+ return static_cast<int>(children_.size());
+}
+
+gfx::NativeViewAccessible AXVirtualView::ChildAtIndex(int index) {
+ DCHECK_GE(index, 0) << "Child indices should be greater or equal to 0.";
+ DCHECK_LT(index, GetChildCount())
+ << "Child indices should be less than the child count.";
+ if (index >= 0 && index < GetChildCount())
+ return children_[index]->GetNativeObject();
+ return nullptr;
+}
+
+gfx::NativeViewAccessible AXVirtualView::GetNSWindow() {
+ NOTREACHED();
+ return nullptr;
+}
+
+gfx::NativeViewAccessible AXVirtualView::GetParent() {
+ if (parent_view_)
+ return parent_view_->GetNativeObject();
+
+ if (virtual_parent_view_)
+ return virtual_parent_view_->GetNativeObject();
+
+ // This virtual view hasn't been added to a parent view yet.
+ return nullptr;
+}
+
+gfx::Rect AXVirtualView::GetClippedScreenBoundsRect() const {
+ // We could optionally add clipping here if ever needed.
+ // TODO(nektar): Implement bounds that are relative to the parent.
+ return gfx::ToEnclosingRect(custom_data_.relative_bounds.bounds);
+}
+
+gfx::Rect AXVirtualView::GetUnclippedScreenBoundsRect() const {
+ // TODO(nektar): Implement bounds that are relative to the parent.
+ return gfx::ToEnclosingRect(custom_data_.relative_bounds.bounds);
+}
+
+gfx::NativeViewAccessible AXVirtualView::HitTestSync(int x, int y) {
+ // TODO(nektar): Implement.
+ return GetNativeObject();
+}
+
+gfx::NativeViewAccessible AXVirtualView::GetFocus() {
+ if (parent_view_)
+ return parent_view_->GetFocusedDescendant();
+
+ if (virtual_parent_view_)
+ return virtual_parent_view_->GetFocus();
+
+ // This virtual view hasn't been added to a parent view yet.
+ return nullptr;
+}
+
+ui::AXPlatformNode* AXVirtualView::GetFromNodeID(int32_t id) {
+ // TODO(nektar): Implement.
+ return nullptr;
+}
+
+bool AXVirtualView::AccessibilityPerformAction(const ui::AXActionData& data) {
+ bool result = false;
+ if (custom_data_.HasAction(data.action))
+ result = HandleAccessibleAction(data);
+ if (!result && GetOwnerView())
+ return GetOwnerView()->HandleAccessibleAction(data);
+ return result;
+}
+
+bool AXVirtualView::ShouldIgnoreHoveredStateForTesting() {
+ // TODO(nektar): Implement.
+ return false;
+}
+
+bool AXVirtualView::IsOffscreen() const {
+ // TODO(nektar): Implement.
+ return false;
+}
+
+const ui::AXUniqueId& AXVirtualView::GetUniqueId() const {
+ return unique_id_;
+}
+
+bool AXVirtualView::HandleAccessibleAction(
+ const ui::AXActionData& action_data) {
+ return false;
+}
+
+View* AXVirtualView::GetOwnerView() const {
+ if (parent_view_)
+ return parent_view_->view();
+
+ if (virtual_parent_view_)
+ return virtual_parent_view_->GetOwnerView();
+
+ // This virtual view hasn't been added to a parent view yet.
+ return nullptr;
+}
+
+} // namespace views