2017-05-12 20:28:25 +02:00
|
|
|
// Copyright 2017 The Chromium Embedded Framework Authors. Portions copyright
|
|
|
|
// 2013 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.
|
|
|
|
|
|
|
|
// Base class implementation for CEF Acccessibility node. This is subclassed and
|
|
|
|
// used by both IAccessible/NSAccessibility protocol implementation.
|
|
|
|
|
|
|
|
#include "tests/cefclient/browser/osr_accessibility_node.h"
|
|
|
|
|
|
|
|
#include "tests/cefclient/browser/osr_accessibility_helper.h"
|
|
|
|
|
|
|
|
namespace client {
|
|
|
|
|
2020-04-02 23:19:25 +02:00
|
|
|
OsrAXNode::OsrAXNode(const CefString& treeId,
|
2019-03-21 17:56:06 +01:00
|
|
|
int nodeId,
|
|
|
|
CefRefPtr<CefDictionaryValue> value,
|
2017-05-12 20:28:25 +02:00
|
|
|
OsrAccessibilityHelper* helper)
|
2019-03-21 17:56:06 +01:00
|
|
|
: tree_id_(treeId),
|
|
|
|
node_id_(nodeId),
|
2020-01-15 15:28:12 +01:00
|
|
|
platform_accessibility_(nullptr),
|
|
|
|
parent_(nullptr),
|
2019-03-21 17:56:06 +01:00
|
|
|
offset_container_id_(-1),
|
2017-05-17 11:29:28 +02:00
|
|
|
accessibility_helper_(helper) {
|
2017-05-12 20:28:25 +02:00
|
|
|
UpdateValue(value);
|
|
|
|
}
|
|
|
|
|
2019-03-21 17:56:06 +01:00
|
|
|
void OsrAXNode::UpdateLocation(CefRefPtr<CefDictionaryValue> value) {
|
|
|
|
// Update Bounds
|
|
|
|
if (value->HasKey("bounds")) {
|
|
|
|
CefRefPtr<CefDictionaryValue> loc = value->GetDictionary("bounds");
|
|
|
|
if (loc) {
|
|
|
|
location_ = CefRect(loc->GetDouble("x"), loc->GetDouble("y"),
|
|
|
|
loc->GetDouble("width"), loc->GetDouble("height"));
|
2017-05-12 20:28:25 +02:00
|
|
|
}
|
2019-03-21 17:56:06 +01:00
|
|
|
}
|
|
|
|
// Update offsets
|
|
|
|
if (value->HasKey("offset_container_id")) {
|
|
|
|
offset_container_id_ = OsrAccessibilityHelper::CastToInt(
|
|
|
|
value->GetValue("offset_container_id"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OsrAXNode::UpdateValue(CefRefPtr<CefDictionaryValue> value) {
|
2023-01-02 23:59:03 +01:00
|
|
|
if (value->HasKey("role")) {
|
2019-03-21 17:56:06 +01:00
|
|
|
role_ = value->GetString("role");
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
2019-03-21 17:56:06 +01:00
|
|
|
|
|
|
|
if (value->HasKey("child_ids")) {
|
|
|
|
CefRefPtr<CefListValue> childs = value->GetList("child_ids");
|
|
|
|
// Reset child Ids
|
|
|
|
child_ids_.clear();
|
2023-01-02 23:59:03 +01:00
|
|
|
for (size_t idx = 0; idx < childs->GetSize(); idx++) {
|
2019-03-21 17:56:06 +01:00
|
|
|
child_ids_.push_back(
|
|
|
|
OsrAccessibilityHelper::CastToInt(childs->GetValue(idx)));
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
2019-03-21 17:56:06 +01:00
|
|
|
}
|
|
|
|
// Update Location
|
|
|
|
if (value->HasKey("location")) {
|
|
|
|
CefRefPtr<CefDictionaryValue> loc = value->GetDictionary("location");
|
|
|
|
if (loc) {
|
|
|
|
location_ = CefRect(loc->GetDouble("x"), loc->GetDouble("y"),
|
|
|
|
loc->GetDouble("width"), loc->GetDouble("height"));
|
2017-05-12 20:28:25 +02:00
|
|
|
}
|
2019-03-21 17:56:06 +01:00
|
|
|
}
|
|
|
|
// Update offsets
|
|
|
|
if (value->HasKey("offset_container_id")) {
|
|
|
|
offset_container_id_ = OsrAccessibilityHelper::CastToInt(
|
|
|
|
value->GetValue("offset_container_id"));
|
|
|
|
}
|
|
|
|
// Update attributes
|
|
|
|
if (value->HasKey("attributes")) {
|
2020-04-02 23:19:25 +02:00
|
|
|
child_tree_id_ = "";
|
2019-03-21 17:56:06 +01:00
|
|
|
|
|
|
|
attributes_ = value->GetDictionary("attributes");
|
|
|
|
|
|
|
|
if (attributes_) {
|
|
|
|
scroll_.x = attributes_->HasKey("scrollX")
|
|
|
|
? OsrAccessibilityHelper::CastToInt(
|
|
|
|
attributes_->GetValue("scrollX"))
|
|
|
|
: 0;
|
|
|
|
scroll_.y = attributes_->HasKey("scrollY")
|
|
|
|
? OsrAccessibilityHelper::CastToInt(
|
|
|
|
attributes_->GetValue("scrollY"))
|
|
|
|
: 0;
|
2017-05-12 20:28:25 +02:00
|
|
|
}
|
2019-03-21 17:56:06 +01:00
|
|
|
|
|
|
|
if (attributes_ && attributes_->HasKey("childTreeId")) {
|
2020-04-02 23:19:25 +02:00
|
|
|
child_tree_id_ = attributes_->GetString("childTreeId");
|
2017-05-12 20:28:25 +02:00
|
|
|
}
|
2023-01-02 23:59:03 +01:00
|
|
|
if (attributes_ && attributes_->HasKey("name")) {
|
2019-03-21 17:56:06 +01:00
|
|
|
name_ = attributes_->GetString("name");
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
|
|
|
if (attributes_ && attributes_->HasKey("value")) {
|
2019-03-21 17:56:06 +01:00
|
|
|
value_ = attributes_->GetString("value");
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
|
|
|
if (attributes_ && attributes_->HasKey("description")) {
|
2019-03-21 17:56:06 +01:00
|
|
|
description_ = attributes_->GetString("description");
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
2017-05-12 20:28:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CefWindowHandle OsrAXNode::GetWindowHandle() const {
|
2023-01-02 23:59:03 +01:00
|
|
|
if (accessibility_helper_) {
|
2017-05-12 20:28:25 +02:00
|
|
|
return accessibility_helper_->GetWindowHandle();
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
2021-06-17 22:08:01 +02:00
|
|
|
return nullptr;
|
2017-05-12 20:28:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
CefRefPtr<CefBrowser> OsrAXNode::GetBrowser() const {
|
2023-01-02 23:59:03 +01:00
|
|
|
if (accessibility_helper_) {
|
2017-05-12 20:28:25 +02:00
|
|
|
return accessibility_helper_->GetBrowser();
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
2020-01-15 15:28:12 +01:00
|
|
|
return nullptr;
|
2017-05-12 20:28:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void OsrAXNode::SetParent(OsrAXNode* parent) {
|
|
|
|
parent_ = parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
CefRect OsrAXNode::AxLocation() const {
|
|
|
|
CefRect loc = location_;
|
2019-03-21 17:56:06 +01:00
|
|
|
loc.x -= scroll_.x;
|
|
|
|
loc.y -= scroll_.y;
|
|
|
|
OsrAXNode* offsetNode =
|
|
|
|
accessibility_helper_->GetNode(OsrAXTreeId(), offset_container_id_);
|
|
|
|
if (!offsetNode) {
|
|
|
|
OsrAXNode* p = parent_;
|
|
|
|
while (p) {
|
|
|
|
if (p->OsrAXTreeId() != OsrAXTreeId()) {
|
|
|
|
offsetNode = p;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p = p->parent_;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Add offset from parent Location
|
2017-05-12 20:28:25 +02:00
|
|
|
if (offsetNode) {
|
|
|
|
CefRect offset = offsetNode->AxLocation();
|
|
|
|
loc.x += offset.x;
|
|
|
|
loc.y += offset.y;
|
|
|
|
}
|
|
|
|
return loc;
|
|
|
|
}
|
|
|
|
|
2019-03-21 17:56:06 +01:00
|
|
|
int OsrAXNode::GetChildCount() const {
|
|
|
|
int count = static_cast<int>(child_ids_.size());
|
2020-04-02 23:19:25 +02:00
|
|
|
if (!child_tree_id_.empty()) {
|
2019-03-21 17:56:06 +01:00
|
|
|
OsrAXNode* childTreeRootNode =
|
|
|
|
accessibility_helper_->GetTreeRootNode(child_tree_id_);
|
|
|
|
if (childTreeRootNode) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2017-05-12 20:28:25 +02:00
|
|
|
OsrAXNode* OsrAXNode::ChildAtIndex(int index) const {
|
2019-03-21 17:56:06 +01:00
|
|
|
int count = static_cast<int>(child_ids_.size());
|
2023-01-02 23:59:03 +01:00
|
|
|
if (index < count) {
|
2019-03-21 17:56:06 +01:00
|
|
|
return accessibility_helper_->GetNode(OsrAXTreeId(), child_ids_[index]);
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
2020-04-02 23:19:25 +02:00
|
|
|
if ((index == count) && (!child_tree_id_.empty())) {
|
2019-03-21 17:56:06 +01:00
|
|
|
OsrAXNode* childTreeRootNode =
|
|
|
|
accessibility_helper_->GetTreeRootNode(child_tree_id_);
|
|
|
|
if (childTreeRootNode) {
|
|
|
|
return childTreeRootNode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-15 15:28:12 +01:00
|
|
|
return nullptr;
|
2017-05-12 20:28:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create and return the platform specific OsrAXNode Object
|
2020-04-02 23:19:25 +02:00
|
|
|
OsrAXNode* OsrAXNode::CreateNode(const CefString& treeId,
|
2019-03-21 17:56:06 +01:00
|
|
|
int nodeId,
|
|
|
|
CefRefPtr<CefDictionaryValue> value,
|
2017-05-12 20:28:25 +02:00
|
|
|
OsrAccessibilityHelper* helper) {
|
2019-03-21 17:56:06 +01:00
|
|
|
return new OsrAXNode(treeId, nodeId, value, helper);
|
2017-05-12 20:28:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace client
|