diff --git a/tests/cefclient/browser/browser_window_osr_gtk.cc b/tests/cefclient/browser/browser_window_osr_gtk.cc index 096a5e46b..1be76c1d0 100644 --- a/tests/cefclient/browser/browser_window_osr_gtk.cc +++ b/tests/cefclient/browser/browser_window_osr_gtk.cc @@ -1362,6 +1362,11 @@ void BrowserWindowOsrGtk::UpdateAccessibilityTree(CefRefPtr value) { CEF_REQUIRE_UI_THREAD(); } +void BrowserWindowOsrGtk::UpdateAccessibilityLocation( + CefRefPtr value) { + CEF_REQUIRE_UI_THREAD(); +} + void BrowserWindowOsrGtk::Create(ClientWindowHandle parent_handle) { REQUIRE_MAIN_THREAD(); DCHECK(!glarea_); diff --git a/tests/cefclient/browser/browser_window_osr_gtk.h b/tests/cefclient/browser/browser_window_osr_gtk.h index 59d2c1692..8c63d4201 100644 --- a/tests/cefclient/browser/browser_window_osr_gtk.h +++ b/tests/cefclient/browser/browser_window_osr_gtk.h @@ -89,6 +89,7 @@ class BrowserWindowOsrGtk : public BrowserWindow, const CefRange& selection_range, const CefRenderHandler::RectList& character_bounds) OVERRIDE; void UpdateAccessibilityTree(CefRefPtr value) OVERRIDE; + void UpdateAccessibilityLocation(CefRefPtr value) OVERRIDE; private: ~BrowserWindowOsrGtk(); diff --git a/tests/cefclient/browser/browser_window_osr_mac.h b/tests/cefclient/browser/browser_window_osr_mac.h index a949ef5ed..b718a203f 100644 --- a/tests/cefclient/browser/browser_window_osr_mac.h +++ b/tests/cefclient/browser/browser_window_osr_mac.h @@ -85,6 +85,7 @@ class BrowserWindowOsrMac : public BrowserWindow, const CefRenderHandler::RectList& character_bounds) OVERRIDE; void UpdateAccessibilityTree(CefRefPtr value) OVERRIDE; + void UpdateAccessibilityLocation(CefRefPtr value) OVERRIDE; private: // Create the NSView. diff --git a/tests/cefclient/browser/browser_window_osr_mac.mm b/tests/cefclient/browser/browser_window_osr_mac.mm index fa96865b1..a8ea7f44b 100644 --- a/tests/cefclient/browser/browser_window_osr_mac.mm +++ b/tests/cefclient/browser/browser_window_osr_mac.mm @@ -109,6 +109,7 @@ CefTextInputClientOSRMac* GetInputClientFromContext( character_bounds: (const CefRenderHandler::RectList&)character_bounds; - (void)UpdateAccessibilityTree:(CefRefPtr)value; +- (void)UpdateAccessibilityLocation:(CefRefPtr)value; @end namespace { @@ -1306,6 +1307,18 @@ NSPoint ConvertPointFromWindowToScreen(NSWindow* window, NSPoint point) { } return; } + +- (void)UpdateAccessibilityLocation:(CefRefPtr)value { + if (accessibility_helper_) { + accessibility_helper_->UpdateAccessibilityLocation(value); + } + + if (accessibility_helper_) { + NSAccessibilityPostNotification(self, + NSAccessibilityValueChangedNotification); + } + return; +} @end namespace client { diff --git a/tests/cefclient/browser/client_handler_osr.cc b/tests/cefclient/browser/client_handler_osr.cc index 5a49a63fe..547223586 100644 --- a/tests/cefclient/browser/client_handler_osr.cc +++ b/tests/cefclient/browser/client_handler_osr.cc @@ -167,4 +167,12 @@ void ClientHandlerOsr::OnAccessibilityTreeChange(CefRefPtr value) { osr_delegate_->UpdateAccessibilityTree(value); } +void ClientHandlerOsr::OnAccessibilityLocationChange( + CefRefPtr value) { + CEF_REQUIRE_UI_THREAD(); + if (!osr_delegate_) + return; + osr_delegate_->UpdateAccessibilityLocation(value); +} + } // namespace client diff --git a/tests/cefclient/browser/client_handler_osr.h b/tests/cefclient/browser/client_handler_osr.h index 509b164b3..1a2c200ef 100644 --- a/tests/cefclient/browser/client_handler_osr.h +++ b/tests/cefclient/browser/client_handler_osr.h @@ -68,6 +68,8 @@ class ClientHandlerOsr : public ClientHandler, virtual void UpdateAccessibilityTree(CefRefPtr value) = 0; + virtual void UpdateAccessibilityLocation(CefRefPtr value) = 0; + protected: virtual ~OsrDelegate() {} }; @@ -130,7 +132,7 @@ class ClientHandlerOsr : public ClientHandler, // CefAccessibilityHandler methods. void OnAccessibilityTreeChange(CefRefPtr value) OVERRIDE; - void OnAccessibilityLocationChange(CefRefPtr value) OVERRIDE {} + void OnAccessibilityLocationChange(CefRefPtr value) OVERRIDE; private: // Only accessed on the UI thread. diff --git a/tests/cefclient/browser/osr_accessibility_helper.cc b/tests/cefclient/browser/osr_accessibility_helper.cc index 673e0f974..9ccd47f1a 100644 --- a/tests/cefclient/browser/osr_accessibility_helper.cc +++ b/tests/cefclient/browser/osr_accessibility_helper.cc @@ -7,134 +7,260 @@ namespace client { +OsrAXTree::OsrAXTree() : parent_tree_id_(-1), root_node_id_(-1) {} + +OsrAXNode* OsrAXTree::GetNode(int nodeId) const { + auto result = node_map_.find(nodeId); + if (result != node_map_.end()) { + return result->second; + } + return NULL; +} + +void OsrAXTree::EraseNode(int nodeId) { + node_map_.erase(nodeId); +} + +void OsrAXTree::AddNode(OsrAXNode* node) { + node_map_[node->OsrAXNodeId()] = node; +} + +void OsrAXTree::UpdateTreeData(CefRefPtr value) { + if (value->HasKey("parent_tree_id")) { + parent_tree_id_ = + OsrAccessibilityHelper::CastToInt(value->GetValue("parent_tree_id")); + } else { + parent_tree_id_ = -1; + } + + // may also update following: + // doctype, title, url, mimetype +} + OsrAccessibilityHelper::OsrAccessibilityHelper(CefRefPtr value, CefRefPtr browser) - : root_node_id_(-1), focused_node_id_(-1), browser_(browser) { + : root_tree_id_(-1), + focused_tree_id_(-1), + focused_node_id_(-1), + browser_(browser) { UpdateAccessibilityTree(value); } +int OsrAccessibilityHelper::CastToInt(CefRefPtr value) { + if (value->GetType() == VTYPE_STRING) { + const std::string& str = value->GetString(); + return atoi(str.c_str()); + } else { + return value->GetInt(); + } +} + +void OsrAccessibilityHelper::UpdateAccessibilityLocation( + CefRefPtr value) { + if (!value || value->GetType() != VTYPE_LIST) { + return; + } + + CefRefPtr locationChangeList = value->GetList(); + size_t locationChangeCount = locationChangeList->GetSize(); + if (locationChangeCount == 0) { + return; + } + + for (size_t i = 0; i < locationChangeCount; i++) { + CefRefPtr locationChangeDict = + locationChangeList->GetDictionary(i); + if (!locationChangeDict->HasKey("ax_tree_id") || + !locationChangeDict->HasKey("new_location") || + !locationChangeDict->HasKey("id")) { + continue; + } + int treeId = CastToInt(locationChangeDict->GetValue("ax_tree_id")); + int nodeId = CastToInt(locationChangeDict->GetValue("id")); + + CefRefPtr newLocationDict = + locationChangeDict->GetDictionary("new_location"); + if (!newLocationDict) { + continue; + } + + OsrAXNode* node = GetNode(treeId, nodeId); + if (!node) { + continue; + } + node->UpdateLocation(newLocationDict); + } +} + void OsrAccessibilityHelper::UpdateAccessibilityTree( CefRefPtr value) { - if (value && value->GetType() == VTYPE_LIST) { - CefRefPtr list = value->GetList(); - size_t numEvents = list->GetSize(); - if (numEvents > 0) { - for (size_t i = 0; i < numEvents; i++) { - CefRefPtr event = list->GetDictionary(i); - if (event && event->HasKey("event_type") && event->HasKey("update")) { - std::string event_type = event->GetString("event_type"); - - CefRefPtr update = event->GetDictionary("update"); - if (event_type == "layoutComplete") - UpdateLayout(update); - if (event_type == "focus" && event->HasKey("id")) { - // Update focused node id - focused_node_id_ = event->GetInt("id"); - UpdateFocusedNode(update); - } - } - } - } + if (!value || value->GetType() != VTYPE_DICTIONARY) { + return; } + + CefRefPtr mainDict = value->GetDictionary(); + if (!mainDict->HasKey("ax_tree_id") || !mainDict->HasKey("updates")) { + return; + } + + int treeId = CastToInt(mainDict->GetValue("ax_tree_id")); + CefRefPtr updatesList = mainDict->GetList("updates"); + + size_t updatesCount = updatesList->GetSize(); + if (updatesCount == 0) { + return; + } + + for (size_t i = 0; i < updatesCount; i++) { + CefRefPtr updateDict = updatesList->GetDictionary(i); + UpdateLayout(treeId, updateDict); + } +} + +OsrAXNode* OsrAccessibilityHelper::GetRootNode() const { + return GetTreeRootNode(root_tree_id_); +} + +OsrAXNode* OsrAccessibilityHelper::GetFocusedNode() const { + auto tree = accessibility_node_map_.find(focused_tree_id_); + if (tree != accessibility_node_map_.end()) { + return tree->second.GetNode(focused_node_id_); + } + + return NULL; +} + +OsrAXNode* OsrAccessibilityHelper::GetTreeRootNode(int treeId) const { + auto tree = accessibility_node_map_.find(treeId); + if (tree != accessibility_node_map_.end()) { + return tree->second.GetNode(tree->second.GetRootNodeId()); + } + + return NULL; } void OsrAccessibilityHelper::UpdateLayout( + int treeId, CefRefPtr update) { - if (update) { - CefRefPtr tree_data; - // get tree data - if (update->HasKey("has_tree_data") && update->GetBool("has_tree_data")) - tree_data = update->GetDictionary("tree_data"); + if (!update) { + return; + } - // If a node is to be cleared - if (update->HasKey("node_id_to_clear")) { - int node_id_to_clear = update->GetInt("node_id_to_clear"); + // If a node is to be cleared + if (update->HasKey("node_id_to_clear")) { + int nodeId = CastToInt(update->GetValue("node_id_to_clear")); - // reset root node if that is to be cleared - if (node_id_to_clear == root_node_id_) - root_node_id_ = -1; - OsrAXNode* node = GetNode(node_id_to_clear); - DestroyNode(node); - } - - if (update->HasKey("root_id")) - root_node_id_ = update->GetInt("root_id"); - - if (tree_data && tree_data->HasKey("focus_id")) - focused_node_id_ = tree_data->GetInt("focus_id"); - // Now initialize/update the node data. - if (update->HasKey("nodes")) { - CefRefPtr nodes = update->GetList("nodes"); - - for (size_t index = 0; index < nodes->GetSize(); index++) { - CefRefPtr node = nodes->GetDictionary(index); - if (node) { - int node_id = node->GetInt("id"); - OsrAXNode* axNode = GetNode(node_id); - // Create if it is a new one - if (axNode) { - axNode->UpdateValue(node); - } else { - axNode = OsrAXNode::CreateNode(node, this); - accessibility_node_map_[node_id] = axNode; - } - } + // reset root node if that is to be cleared + auto tree = accessibility_node_map_.find(treeId); + if (tree != accessibility_node_map_.end()) { + if (tree->second.GetRootNodeId() == nodeId) { + root_tree_id_ = -1; + tree->second.SetRootNodeId(-1); } } + if ((focused_tree_id_ == treeId) && (focused_node_id_ == nodeId)) { + UpdateFocusedNode(-1, -1); + } + OsrAXNode* node = GetNode(treeId, nodeId); + DestroyNode(node); } -} -void OsrAccessibilityHelper::UpdateFocusedNode( - CefRefPtr update) { - if (update && update->HasKey("nodes")) { + // get tree data + if (update->HasKey("tree_data") && update->HasKey("has_tree_data") && + update->GetBool("has_tree_data")) { + CefRefPtr tree_data = + update->GetDictionary("tree_data"); + auto& tree = accessibility_node_map_[treeId]; + tree.UpdateTreeData(tree_data); + if (tree.GetParentTreeId() == -1) { + root_tree_id_ = treeId; + } + if (tree_data->HasKey("focus_id") && tree_data->HasKey("focused_tree_id")) { + UpdateFocusedNode(CastToInt(tree_data->GetValue("focused_tree_id")), + CastToInt(tree_data->GetValue("focus_id"))); + } + } + + // Now initialize/update the node data. + if (update->HasKey("nodes")) { CefRefPtr nodes = update->GetList("nodes"); for (size_t index = 0; index < nodes->GetSize(); index++) { CefRefPtr node = nodes->GetDictionary(index); if (node) { - int node_id = node->GetInt("id"); - OsrAXNode* axNode = GetNode(node_id); + auto& tree = accessibility_node_map_[treeId]; + int nodeId = CastToInt(node->GetValue("id")); + OsrAXNode* axNode = tree.GetNode(nodeId); // Create if it is a new one if (axNode) { axNode->UpdateValue(node); } else { - axNode = OsrAXNode::CreateNode(node, this); - accessibility_node_map_[node_id] = axNode; + axNode = OsrAXNode::CreateNode(treeId, nodeId, node, this); + tree.AddNode(axNode); } } } } + + if (update->HasKey("root_id")) { + int nodeId = CastToInt(update->GetValue("root_id")); + OsrAXNode* node = GetNode(treeId, nodeId); + if (node != NULL) { + auto& tree = accessibility_node_map_[treeId]; + tree.SetRootNodeId(nodeId); + } + } +} + +void OsrAccessibilityHelper::UpdateFocusedNode(int treeId, int nodeId) { + if ((focused_tree_id_ == treeId) && (focused_node_id_ == nodeId)) { + return; + } + focused_tree_id_ = treeId; + focused_node_id_ = nodeId; + // Now Notify Screen Reader OsrAXNode* axNode = GetFocusedNode(); - // Fallback to Root - if (!axNode) - axNode = GetRootNode(); - - axNode->NotifyAccessibilityEvent("focus"); + if (axNode) { + axNode->NotifyAccessibilityEvent("focus"); + } } void OsrAccessibilityHelper::Reset() { accessibility_node_map_.clear(); - root_node_id_ = focused_node_id_ = -1; + root_tree_id_ = -1; + focused_tree_id_ = focused_node_id_ = -1; } void OsrAccessibilityHelper::DestroyNode(OsrAXNode* node) { if (node) { + int treeId = node->OsrAXTreeId(); int numChilds = node->GetChildCount(); if (numChilds > 0) { for (int i = 0; i < numChilds; i++) { - DestroyNode(node->ChildAtIndex(i)); + OsrAXNode* childNode = node->ChildAtIndex(i); + if (!childNode) { + continue; + } + childNode->SetParent(NULL); + if (childNode->OsrAXTreeId() == treeId) { + DestroyNode(childNode); + } } } - accessibility_node_map_.erase(node->OsrAXNodeId()); + auto tree = accessibility_node_map_.find(treeId); + if (tree != accessibility_node_map_.end()) { + tree->second.EraseNode(node->OsrAXNodeId()); + } + node->Destroy(); } } -OsrAXNode* OsrAccessibilityHelper::GetNode(int nodeId) const { - if (nodeId != -1 && - accessibility_node_map_.find(nodeId) != accessibility_node_map_.end()) { - return accessibility_node_map_.at(nodeId); +OsrAXNode* OsrAccessibilityHelper::GetNode(int treeId, int nodeId) const { + auto tree = accessibility_node_map_.find(treeId); + if (tree != accessibility_node_map_.end()) { + return tree->second.GetNode(nodeId); } return NULL; diff --git a/tests/cefclient/browser/osr_accessibility_helper.h b/tests/cefclient/browser/osr_accessibility_helper.h index 1555a08ea..61db6d8c6 100644 --- a/tests/cefclient/browser/osr_accessibility_helper.h +++ b/tests/cefclient/browser/osr_accessibility_helper.h @@ -12,6 +12,24 @@ namespace client { class OsrAXNode; +class OsrAccessibilityHelper; + +class OsrAXTree { + public: + OsrAXTree(); + OsrAXNode* GetNode(int nodeId) const; + void EraseNode(int nodeId); + void UpdateTreeData(CefRefPtr value); + void AddNode(OsrAXNode* node); + int GetParentTreeId() const { return parent_tree_id_; } + int GetRootNodeId() const { return root_node_id_; } + void SetRootNodeId(int nodeId) { root_node_id_ = nodeId; } + + private: + int parent_tree_id_; + int root_node_id_; + std::map node_map_; +}; // Helper class that abstracts Renderer Accessibility tree and provides a // uniform interface to be consumed by IAccessible interface on Windows and @@ -23,9 +41,11 @@ class OsrAccessibilityHelper { void UpdateAccessibilityTree(CefRefPtr value); - OsrAXNode* GetRootNode() const { return GetNode(root_node_id_); } + void UpdateAccessibilityLocation(CefRefPtr value); - OsrAXNode* GetFocusedNode() const { return GetNode(focused_node_id_); } + OsrAXNode* GetRootNode() const; + + OsrAXNode* GetFocusedNode() const; CefWindowHandle GetWindowHandle() const { return browser_->GetHost()->GetWindowHandle(); @@ -33,23 +53,26 @@ class OsrAccessibilityHelper { CefRefPtr GetBrowser() const { return browser_; } - OsrAXNode* GetNode(int nodeId) const; + OsrAXNode* GetNode(int treeId, int nodeId) const; + + OsrAXNode* GetTreeRootNode(int treeId) const; + + static int CastToInt(CefRefPtr value); private: - OsrAXNode* CreateNode(OsrAXNode* parent, CefRefPtr value); - void Reset(); - void UpdateLayout(CefRefPtr update); + void UpdateLayout(int treeId, CefRefPtr update); - void UpdateFocusedNode(CefRefPtr update); + void UpdateFocusedNode(int treeId, int nodeId); // Destroy the node and remove from Map void DestroyNode(OsrAXNode* node); - int root_node_id_; + int root_tree_id_; + int focused_tree_id_; int focused_node_id_; CefRefPtr browser_; - std::map accessibility_node_map_; + std::map accessibility_node_map_; }; } // namespace client diff --git a/tests/cefclient/browser/osr_accessibility_node.cc b/tests/cefclient/browser/osr_accessibility_node.cc index fdbb41d1f..a86125188 100644 --- a/tests/cefclient/browser/osr_accessibility_node.cc +++ b/tests/cefclient/browser/osr_accessibility_node.cc @@ -11,52 +11,88 @@ namespace client { -OsrAXNode::OsrAXNode(CefRefPtr value, +OsrAXNode::OsrAXNode(int treeId, + int nodeId, + CefRefPtr value, OsrAccessibilityHelper* helper) - : node_id_(-1), + : tree_id_(treeId), + node_id_(nodeId), + child_tree_id_(-1), platform_accessibility_(NULL), parent_(NULL), + offset_container_id_(-1), accessibility_helper_(helper) { UpdateValue(value); } +void OsrAXNode::UpdateLocation(CefRefPtr value) { + // Update Bounds + if (value->HasKey("bounds")) { + CefRefPtr 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 value) { - if (value && value->HasKey("id")) { - node_id_ = value->GetInt("id"); + if (value->HasKey("role")) + role_ = value->GetString("role"); - if (value->HasKey("role")) - role_ = value->GetString("role"); + if (value->HasKey("child_ids")) { + CefRefPtr 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 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_ = -1; - if (value->HasKey("child_ids")) { - CefRefPtr childs = value->GetList("child_ids"); - // Reset child Ids - child_ids_.clear(); - for (size_t idx = 0; idx < childs->GetSize(); idx++) - child_ids_.push_back(childs->GetInt(idx)); - } - // Update Location - if (value->HasKey("location")) { - CefRefPtr 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_ = value->GetInt("offset_container_id"); - } - // Update attributes - if (value->HasKey("attributes")) { - attributes_ = value->GetDictionary("attributes"); + attributes_ = value->GetDictionary("attributes"); - 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"); + 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_ = OsrAccessibilityHelper::CastToInt( + attributes_->GetValue("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"); } } @@ -78,8 +114,21 @@ void OsrAXNode::SetParent(OsrAXNode* parent) { CefRect OsrAXNode::AxLocation() const { CefRect loc = location_; - OsrAXNode* offsetNode = accessibility_helper_->GetNode(offset_container_id_); - // Add offset from parent Lcoation + 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; @@ -88,17 +137,39 @@ CefRect OsrAXNode::AxLocation() const { return loc; } +int OsrAXNode::GetChildCount() const { + int count = static_cast(child_ids_.size()); + if (child_tree_id_ >= 0) { + OsrAXNode* childTreeRootNode = + accessibility_helper_->GetTreeRootNode(child_tree_id_); + if (childTreeRootNode) { + count++; + } + } + return count; +} + OsrAXNode* OsrAXNode::ChildAtIndex(int index) const { - if (index < GetChildCount()) - return accessibility_helper_->GetNode(child_ids_[index]); - else - return NULL; + int count = static_cast(child_ids_.size()); + if (index < count) + return accessibility_helper_->GetNode(OsrAXTreeId(), child_ids_[index]); + if ((index == count) && (child_tree_id_ >= 0)) { + OsrAXNode* childTreeRootNode = + accessibility_helper_->GetTreeRootNode(child_tree_id_); + if (childTreeRootNode) { + return childTreeRootNode; + } + } + + return NULL; } // Create and return the platform specific OsrAXNode Object -OsrAXNode* OsrAXNode::CreateNode(CefRefPtr value, +OsrAXNode* OsrAXNode::CreateNode(int treeId, + int nodeId, + CefRefPtr value, OsrAccessibilityHelper* helper) { - return new OsrAXNode(value, helper); + return new OsrAXNode(treeId, nodeId, value, helper); } } // namespace client diff --git a/tests/cefclient/browser/osr_accessibility_node.h b/tests/cefclient/browser/osr_accessibility_node.h index dedec57cb..329cce408 100644 --- a/tests/cefclient/browser/osr_accessibility_node.h +++ b/tests/cefclient/browser/osr_accessibility_node.h @@ -33,12 +33,17 @@ class OsrAccessibilityHelper; class OsrAXNode { public: // Create and return the platform specific OsrAXNode Object. - static OsrAXNode* CreateNode(CefRefPtr value, + static OsrAXNode* CreateNode(int treeId, + int nodeId, + CefRefPtr value, OsrAccessibilityHelper* helper); // Update Value. void UpdateValue(CefRefPtr value); + // UpdateLocation + void UpdateLocation(CefRefPtr value); + // Fire a platform-specific notification that an event has occurred on // this object. void NotifyAccessibilityEvent(std::string event_type) const; @@ -58,13 +63,15 @@ class OsrAXNode { return accessibility_helper_; } - int GetChildCount() const { return static_cast(child_ids_.size()); } + int GetChildCount() const; // Return the Child at the specified index OsrAXNode* ChildAtIndex(int index) const; const CefString& AxRole() const { return role_; } + int OsrAXTreeId() const { return tree_id_; } + int OsrAXNodeId() const { return node_id_; } const CefString& AxValue() const { return value_; } @@ -82,15 +89,20 @@ class OsrAXNode { void SetParent(OsrAXNode* parent); protected: - OsrAXNode(CefRefPtr value, + OsrAXNode(int treeId, + int nodeId, + CefRefPtr value, OsrAccessibilityHelper* helper); + int tree_id_; int node_id_; + int child_tree_id_; CefString role_; CefString value_; CefString name_; CefString description_; CefRect location_; + CefPoint scroll_; std::vector child_ids_; CefNativeAccessible* platform_accessibility_; OsrAXNode* parent_; diff --git a/tests/cefclient/browser/osr_accessibility_node_win.cc b/tests/cefclient/browser/osr_accessibility_node_win.cc index 73e6f9478..17e80290b 100644 --- a/tests/cefclient/browser/osr_accessibility_node_win.cc +++ b/tests/cefclient/browser/osr_accessibility_node_win.cc @@ -347,7 +347,7 @@ STDMETHODIMP CefIAccessible::get_accName(VARIANT varChild, BSTR* pszName) { HRESULT retCode = DATACHECK(node_); if (SUCCEEDED(retCode)) { if (pszName && VALID_CHILDID(varChild)) { - std::string name = node_->AxName(); + std::wstring name = node_->AxName(); CComBSTR bstrResult(name.c_str()); *pszName = bstrResult.Detach(); } @@ -362,7 +362,7 @@ STDMETHODIMP CefIAccessible::get_accValue(VARIANT varChild, BSTR* pszValue) { HRESULT retCode = DATACHECK(node_); if (SUCCEEDED(retCode)) { if (pszValue && VALID_CHILDID(varChild)) { - std::string name = node_->AxValue(); + std::wstring name = node_->AxValue(); CComBSTR bstrResult(name.c_str()); *pszValue = bstrResult.Detach(); } @@ -378,7 +378,7 @@ STDMETHODIMP CefIAccessible::get_accDescription(VARIANT varChild, HRESULT retCode = DATACHECK(node_); if (SUCCEEDED(retCode)) { if (pszDescription && VALID_CHILDID(varChild)) { - std::string name = node_->AxDescription(); + std::wstring name = node_->AxDescription(); CComBSTR bstrResult(name.c_str()); *pszDescription = bstrResult.Detach(); } diff --git a/tests/cefclient/browser/osr_window_win.cc b/tests/cefclient/browser/osr_window_win.cc index fd8d66131..9f366708e 100644 --- a/tests/cefclient/browser/osr_window_win.cc +++ b/tests/cefclient/browser/osr_window_win.cc @@ -1058,6 +1058,16 @@ void OsrWindowWin::UpdateAccessibilityTree(CefRefPtr value) { #endif // defined(CEF_USE_ATL) } +void OsrWindowWin::UpdateAccessibilityLocation(CefRefPtr value) { + CEF_REQUIRE_UI_THREAD(); + +#if defined(CEF_USE_ATL) + if (accessibility_handler_) { + accessibility_handler_->UpdateAccessibilityLocation(value); + } +#endif // defined(CEF_USE_ATL) +} + #if defined(CEF_USE_ATL) CefBrowserHost::DragOperationsMask OsrWindowWin::OnDragEnter( diff --git a/tests/cefclient/browser/osr_window_win.h b/tests/cefclient/browser/osr_window_win.h index 5a908fcc6..642dc69d8 100644 --- a/tests/cefclient/browser/osr_window_win.h +++ b/tests/cefclient/browser/osr_window_win.h @@ -146,7 +146,9 @@ class OsrWindowWin const CefRange& selection_range, const CefRenderHandler::RectList& character_bounds) OVERRIDE; - void UpdateAccessibilityTree(CefRefPtr value); + void UpdateAccessibilityTree(CefRefPtr value) OVERRIDE; + + void UpdateAccessibilityLocation(CefRefPtr value) OVERRIDE; #if defined(CEF_USE_ATL) // OsrDragEvents methods.