• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Embedded Framework Authors. Portions copyright
2 // 2013 The Chromium Authors. All rights reserved. Use of this source code is
3 // governed by a BSD-style license that can be found in the LICENSE file.
4 
5 // Base class implementation for CEF Acccessibility node. This is subclassed and
6 // used by both IAccessible/NSAccessibility protocol implementation.
7 
8 #include "tests/cefclient/browser/osr_accessibility_node.h"
9 
10 #include "tests/cefclient/browser/osr_accessibility_helper.h"
11 
12 namespace client {
13 
OsrAXNode(const CefString & treeId,int nodeId,CefRefPtr<CefDictionaryValue> value,OsrAccessibilityHelper * helper)14 OsrAXNode::OsrAXNode(const CefString& treeId,
15                      int nodeId,
16                      CefRefPtr<CefDictionaryValue> value,
17                      OsrAccessibilityHelper* helper)
18     : tree_id_(treeId),
19       node_id_(nodeId),
20       platform_accessibility_(nullptr),
21       parent_(nullptr),
22       offset_container_id_(-1),
23       accessibility_helper_(helper) {
24   UpdateValue(value);
25 }
26 
UpdateLocation(CefRefPtr<CefDictionaryValue> value)27 void OsrAXNode::UpdateLocation(CefRefPtr<CefDictionaryValue> value) {
28   // Update Bounds
29   if (value->HasKey("bounds")) {
30     CefRefPtr<CefDictionaryValue> loc = value->GetDictionary("bounds");
31     if (loc) {
32       location_ = CefRect(loc->GetDouble("x"), loc->GetDouble("y"),
33                           loc->GetDouble("width"), loc->GetDouble("height"));
34     }
35   }
36   // Update offsets
37   if (value->HasKey("offset_container_id")) {
38     offset_container_id_ = OsrAccessibilityHelper::CastToInt(
39         value->GetValue("offset_container_id"));
40   }
41 }
42 
UpdateValue(CefRefPtr<CefDictionaryValue> value)43 void OsrAXNode::UpdateValue(CefRefPtr<CefDictionaryValue> value) {
44   if (value->HasKey("role"))
45     role_ = value->GetString("role");
46 
47   if (value->HasKey("child_ids")) {
48     CefRefPtr<CefListValue> childs = value->GetList("child_ids");
49     // Reset child Ids
50     child_ids_.clear();
51     for (size_t idx = 0; idx < childs->GetSize(); idx++)
52       child_ids_.push_back(
53           OsrAccessibilityHelper::CastToInt(childs->GetValue(idx)));
54   }
55   // Update Location
56   if (value->HasKey("location")) {
57     CefRefPtr<CefDictionaryValue> loc = value->GetDictionary("location");
58     if (loc) {
59       location_ = CefRect(loc->GetDouble("x"), loc->GetDouble("y"),
60                           loc->GetDouble("width"), loc->GetDouble("height"));
61     }
62   }
63   // Update offsets
64   if (value->HasKey("offset_container_id")) {
65     offset_container_id_ = OsrAccessibilityHelper::CastToInt(
66         value->GetValue("offset_container_id"));
67   }
68   // Update attributes
69   if (value->HasKey("attributes")) {
70     child_tree_id_ = "";
71 
72     attributes_ = value->GetDictionary("attributes");
73 
74     if (attributes_) {
75       scroll_.x = attributes_->HasKey("scrollX")
76                       ? OsrAccessibilityHelper::CastToInt(
77                             attributes_->GetValue("scrollX"))
78                       : 0;
79       scroll_.y = attributes_->HasKey("scrollY")
80                       ? OsrAccessibilityHelper::CastToInt(
81                             attributes_->GetValue("scrollY"))
82                       : 0;
83     }
84 
85     if (attributes_ && attributes_->HasKey("childTreeId")) {
86       child_tree_id_ = attributes_->GetString("childTreeId");
87     }
88     if (attributes_ && attributes_->HasKey("name"))
89       name_ = attributes_->GetString("name");
90     if (attributes_ && attributes_->HasKey("value"))
91       value_ = attributes_->GetString("value");
92     if (attributes_ && attributes_->HasKey("description"))
93       description_ = attributes_->GetString("description");
94   }
95 }
96 
GetWindowHandle() const97 CefWindowHandle OsrAXNode::GetWindowHandle() const {
98   if (accessibility_helper_)
99     return accessibility_helper_->GetWindowHandle();
100   return nullptr;
101 }
102 
GetBrowser() const103 CefRefPtr<CefBrowser> OsrAXNode::GetBrowser() const {
104   if (accessibility_helper_)
105     return accessibility_helper_->GetBrowser();
106   return nullptr;
107 }
108 
SetParent(OsrAXNode * parent)109 void OsrAXNode::SetParent(OsrAXNode* parent) {
110   parent_ = parent;
111 }
112 
AxLocation() const113 CefRect OsrAXNode::AxLocation() const {
114   CefRect loc = location_;
115   loc.x -= scroll_.x;
116   loc.y -= scroll_.y;
117   OsrAXNode* offsetNode =
118       accessibility_helper_->GetNode(OsrAXTreeId(), offset_container_id_);
119   if (!offsetNode) {
120     OsrAXNode* p = parent_;
121     while (p) {
122       if (p->OsrAXTreeId() != OsrAXTreeId()) {
123         offsetNode = p;
124         break;
125       }
126       p = p->parent_;
127     }
128   }
129   // Add offset from parent Location
130   if (offsetNode) {
131     CefRect offset = offsetNode->AxLocation();
132     loc.x += offset.x;
133     loc.y += offset.y;
134   }
135   return loc;
136 }
137 
GetChildCount() const138 int OsrAXNode::GetChildCount() const {
139   int count = static_cast<int>(child_ids_.size());
140   if (!child_tree_id_.empty()) {
141     OsrAXNode* childTreeRootNode =
142         accessibility_helper_->GetTreeRootNode(child_tree_id_);
143     if (childTreeRootNode) {
144       count++;
145     }
146   }
147   return count;
148 }
149 
ChildAtIndex(int index) const150 OsrAXNode* OsrAXNode::ChildAtIndex(int index) const {
151   int count = static_cast<int>(child_ids_.size());
152   if (index < count)
153     return accessibility_helper_->GetNode(OsrAXTreeId(), child_ids_[index]);
154   if ((index == count) && (!child_tree_id_.empty())) {
155     OsrAXNode* childTreeRootNode =
156         accessibility_helper_->GetTreeRootNode(child_tree_id_);
157     if (childTreeRootNode) {
158       return childTreeRootNode;
159     }
160   }
161 
162   return nullptr;
163 }
164 
165 // Create and return the platform specific OsrAXNode Object
CreateNode(const CefString & treeId,int nodeId,CefRefPtr<CefDictionaryValue> value,OsrAccessibilityHelper * helper)166 OsrAXNode* OsrAXNode::CreateNode(const CefString& treeId,
167                                  int nodeId,
168                                  CefRefPtr<CefDictionaryValue> value,
169                                  OsrAccessibilityHelper* helper) {
170   return new OsrAXNode(treeId, nodeId, value, helper);
171 }
172 
173 }  // namespace client
174