| // 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 { |
| |
| OsrAXNode::OsrAXNode(const CefString& treeId, |
| int nodeId, |
| CefRefPtr<CefDictionaryValue> value, |
| OsrAccessibilityHelper* helper) |
| : tree_id_(treeId), |
| node_id_(nodeId), |
| platform_accessibility_(nullptr), |
| parent_(nullptr), |
| offset_container_id_(-1), |
| accessibility_helper_(helper) { |
| UpdateValue(value); |
| } |
| |
| 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")); |
| } |
| } |
| // Update offsets |
| if (value->HasKey("offset_container_id")) { |
| offset_container_id_ = OsrAccessibilityHelper::CastToInt( |
| value->GetValue("offset_container_id")); |
| } |
| } |
| |
| void OsrAXNode::UpdateValue(CefRefPtr<CefDictionaryValue> value) { |
| if (value->HasKey("role")) |
| role_ = value->GetString("role"); |
| |
| if (value->HasKey("child_ids")) { |
| CefRefPtr<CefListValue> childs = value->GetList("child_ids"); |
| // Reset child Ids |
| child_ids_.clear(); |
| for (size_t idx = 0; idx < childs->GetSize(); idx++) |
| child_ids_.push_back( |
| OsrAccessibilityHelper::CastToInt(childs->GetValue(idx))); |
| } |
| // 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")); |
| } |
| } |
| // Update offsets |
| if (value->HasKey("offset_container_id")) { |
| offset_container_id_ = OsrAccessibilityHelper::CastToInt( |
| value->GetValue("offset_container_id")); |
| } |
| // Update attributes |
| if (value->HasKey("attributes")) { |
| child_tree_id_ = ""; |
| |
| 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; |
| } |
| |
| if (attributes_ && attributes_->HasKey("childTreeId")) { |
| child_tree_id_ = attributes_->GetString("childTreeId"); |
| } |
| if (attributes_ && attributes_->HasKey("name")) |
| name_ = attributes_->GetString("name"); |
| if (attributes_ && attributes_->HasKey("value")) |
| value_ = attributes_->GetString("value"); |
| if (attributes_ && attributes_->HasKey("description")) |
| description_ = attributes_->GetString("description"); |
| } |
| } |
| |
| CefWindowHandle OsrAXNode::GetWindowHandle() const { |
| if (accessibility_helper_) |
| return accessibility_helper_->GetWindowHandle(); |
| return NULL; |
| } |
| |
| CefRefPtr<CefBrowser> OsrAXNode::GetBrowser() const { |
| if (accessibility_helper_) |
| return accessibility_helper_->GetBrowser(); |
| return nullptr; |
| } |
| |
| void OsrAXNode::SetParent(OsrAXNode* parent) { |
| parent_ = parent; |
| } |
| |
| CefRect OsrAXNode::AxLocation() const { |
| CefRect loc = location_; |
| 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 |
| if (offsetNode) { |
| CefRect offset = offsetNode->AxLocation(); |
| loc.x += offset.x; |
| loc.y += offset.y; |
| } |
| return loc; |
| } |
| |
| int OsrAXNode::GetChildCount() const { |
| int count = static_cast<int>(child_ids_.size()); |
| if (!child_tree_id_.empty()) { |
| OsrAXNode* childTreeRootNode = |
| accessibility_helper_->GetTreeRootNode(child_tree_id_); |
| if (childTreeRootNode) { |
| count++; |
| } |
| } |
| return count; |
| } |
| |
| OsrAXNode* OsrAXNode::ChildAtIndex(int index) const { |
| int count = static_cast<int>(child_ids_.size()); |
| if (index < count) |
| return accessibility_helper_->GetNode(OsrAXTreeId(), child_ids_[index]); |
| if ((index == count) && (!child_tree_id_.empty())) { |
| OsrAXNode* childTreeRootNode = |
| accessibility_helper_->GetTreeRootNode(child_tree_id_); |
| if (childTreeRootNode) { |
| return childTreeRootNode; |
| } |
| } |
| |
| return nullptr; |
| } |
| |
| // Create and return the platform specific OsrAXNode Object |
| OsrAXNode* OsrAXNode::CreateNode(const CefString& treeId, |
| int nodeId, |
| CefRefPtr<CefDictionaryValue> value, |
| OsrAccessibilityHelper* helper) { |
| return new OsrAXNode(treeId, nodeId, value, helper); |
| } |
| |
| } // namespace client |