Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(630)

Side by Side Diff: chrome/renderer/extensions/automation_internal_custom_bindings.cc

Issue 2762373002: Fix computation of Automation API location offsets in WebViews. (Closed)
Patch Set: Only run new test on chromeos because of required perms Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/extensions/automation_internal_custom_bindings.h" 5 #include "chrome/renderer/extensions/automation_internal_custom_bindings.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 TreeCache* cache, ui::AXNode* node) { 531 TreeCache* cache, ui::AXNode* node) {
532 std::string role_name = ui::ToString(node->data().role); 532 std::string role_name = ui::ToString(node->data().role);
533 result.Set(v8::String::NewFromUtf8(isolate, role_name.c_str())); 533 result.Set(v8::String::NewFromUtf8(isolate, role_name.c_str()));
534 }); 534 });
535 RouteNodeIDFunction( 535 RouteNodeIDFunction(
536 "GetLocation", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, 536 "GetLocation", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
537 TreeCache* cache, ui::AXNode* node) { 537 TreeCache* cache, ui::AXNode* node) {
538 gfx::RectF local_bounds = ComputeLocalNodeBounds(cache, node); 538 gfx::RectF local_bounds = ComputeLocalNodeBounds(cache, node);
539 gfx::Rect global_bounds = 539 gfx::Rect global_bounds =
540 ComputeGlobalNodeBounds(cache, node, local_bounds); 540 ComputeGlobalNodeBounds(cache, node, local_bounds);
541 global_bounds.Offset(cache->location_offset);
542 result.Set(RectToV8Object(isolate, global_bounds)); 541 result.Set(RectToV8Object(isolate, global_bounds));
543 }); 542 });
544 RouteNodeIDFunction( 543 RouteNodeIDFunction(
545 "GetLineStartOffsets", 544 "GetLineStartOffsets",
546 [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, 545 [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
547 TreeCache* cache, ui::AXNode* node) { 546 TreeCache* cache, ui::AXNode* node) {
548 const std::vector<int> line_starts = 547 const std::vector<int> line_starts =
549 node->GetOrComputeLineStartOffsets(); 548 node->GetOrComputeLineStartOffsets();
550 v8::Local<v8::Array> array_result( 549 v8::Local<v8::Array> array_result(
551 v8::Array::New(isolate, line_starts.size())); 550 v8::Array::New(isolate, line_starts.size()));
(...skipping 19 matching lines...) Expand all
571 // and return a property of the node. 570 // and return a property of the node.
572 571
573 RouteNodeIDPlusRangeFunction( 572 RouteNodeIDPlusRangeFunction(
574 "GetBoundsForRange", 573 "GetBoundsForRange",
575 [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, 574 [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
576 TreeCache* cache, ui::AXNode* node, int start, int end) { 575 TreeCache* cache, ui::AXNode* node, int start, int end) {
577 gfx::RectF local_bounds = ComputeLocalNodeBounds(cache, node); 576 gfx::RectF local_bounds = ComputeLocalNodeBounds(cache, node);
578 if (node->data().role != ui::AX_ROLE_INLINE_TEXT_BOX) { 577 if (node->data().role != ui::AX_ROLE_INLINE_TEXT_BOX) {
579 gfx::Rect global_bounds = 578 gfx::Rect global_bounds =
580 ComputeGlobalNodeBounds(cache, node, local_bounds); 579 ComputeGlobalNodeBounds(cache, node, local_bounds);
581 global_bounds.Offset(cache->location_offset);
582 result.Set(RectToV8Object(isolate, global_bounds)); 580 result.Set(RectToV8Object(isolate, global_bounds));
583 } 581 }
584 582
585 // Use character offsets to compute the local bounds of this subrange. 583 // Use character offsets to compute the local bounds of this subrange.
586 std::string name = node->data().GetStringAttribute(ui::AX_ATTR_NAME); 584 std::string name = node->data().GetStringAttribute(ui::AX_ATTR_NAME);
587 std::vector<int> character_offsets = 585 std::vector<int> character_offsets =
588 node->data().GetIntListAttribute(ui::AX_ATTR_CHARACTER_OFFSETS); 586 node->data().GetIntListAttribute(ui::AX_ATTR_CHARACTER_OFFSETS);
589 int len = 587 int len =
590 static_cast<int>(std::min(name.size(), character_offsets.size())); 588 static_cast<int>(std::min(name.size(), character_offsets.size()));
591 if (start >= 0 && start <= end && end <= len) { 589 if (start >= 0 && start <= end && end <= len) {
(...skipping 21 matching lines...) Expand all
613 local_bounds.set_height(end_offset - start_offset); 611 local_bounds.set_height(end_offset - start_offset);
614 break; 612 break;
615 } 613 }
616 } 614 }
617 615
618 // Convert from local to global coordinates second, after subsetting, 616 // Convert from local to global coordinates second, after subsetting,
619 // because the local to global conversion might involve matrix 617 // because the local to global conversion might involve matrix
620 // transformations. 618 // transformations.
621 gfx::Rect global_bounds = 619 gfx::Rect global_bounds =
622 ComputeGlobalNodeBounds(cache, node, local_bounds); 620 ComputeGlobalNodeBounds(cache, node, local_bounds);
623 global_bounds.Offset(cache->location_offset);
624 result.Set(RectToV8Object(isolate, global_bounds)); 621 result.Set(RectToV8Object(isolate, global_bounds));
625 }); 622 });
626 623
627 // Bindings that take a Tree ID and Node ID and string attribute name 624 // Bindings that take a Tree ID and Node ID and string attribute name
628 // and return a property of the node. 625 // and return a property of the node.
629 626
630 RouteNodeIDPlusAttributeFunction( 627 RouteNodeIDPlusAttributeFunction(
631 "GetStringAttribute", 628 "GetStringAttribute",
632 [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, 629 [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
633 ui::AXNode* node, const std::string& attribute_name) { 630 ui::AXNode* node, const std::string& attribute_name) {
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 tree_change_observer_overall_filter_ |= 1 << observer.filter; 1004 tree_change_observer_overall_filter_ |= 1 << observer.filter;
1008 } 1005 }
1009 1006
1010 ui::AXNode* AutomationInternalCustomBindings::GetParent( 1007 ui::AXNode* AutomationInternalCustomBindings::GetParent(
1011 ui::AXNode* node, 1008 ui::AXNode* node,
1012 TreeCache** in_out_cache) { 1009 TreeCache** in_out_cache) {
1013 if (node->parent()) 1010 if (node->parent())
1014 return node->parent(); 1011 return node->parent();
1015 1012
1016 int parent_tree_id = (*in_out_cache)->tree.data().parent_tree_id; 1013 int parent_tree_id = (*in_out_cache)->tree.data().parent_tree_id;
1014
1015 // Try the desktop tree if the parent is unknown. If this tree really is
1016 // a child of the desktop tree, we'll find its parent, and if not, the
1017 // search, below, will fail until the real parent tree loads.
1017 if (parent_tree_id < 0) 1018 if (parent_tree_id < 0)
1018 return nullptr; 1019 parent_tree_id = api::automation::kDesktopTreeID;
1019 1020
1020 TreeCache* parent_cache = GetTreeCacheFromTreeID(parent_tree_id); 1021 TreeCache* parent_cache = GetTreeCacheFromTreeID(parent_tree_id);
1021 if (!parent_cache) 1022 if (!parent_cache)
1022 return nullptr; 1023 return nullptr;
1023 1024
1024 // Try to use the cached parent node from the most recent time this 1025 // Try to use the cached parent node from the most recent time this
1025 // was called. 1026 // was called.
1026 if (parent_cache->parent_node_id_from_parent_tree > 0) { 1027 if ((*in_out_cache)->parent_node_id_from_parent_tree > 0) {
1027 ui::AXNode* parent = parent_cache->tree.GetFromId( 1028 ui::AXNode* parent = parent_cache->tree.GetFromId(
1028 parent_cache->parent_node_id_from_parent_tree); 1029 (*in_out_cache)->parent_node_id_from_parent_tree);
1029 if (parent) { 1030 if (parent) {
1030 int parent_child_tree_id = 1031 int parent_child_tree_id =
1031 parent->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID); 1032 parent->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID);
1032 if (parent_child_tree_id == (*in_out_cache)->tree_id) { 1033 if (parent_child_tree_id == (*in_out_cache)->tree_id) {
1033 *in_out_cache = parent_cache; 1034 *in_out_cache = parent_cache;
1034 return parent; 1035 return parent;
1035 } 1036 }
1036 } 1037 }
1037 } 1038 }
1038 1039
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 cache->parent_node_id_from_parent_tree = -1; 1127 cache->parent_node_id_from_parent_tree = -1;
1127 cache->tree.SetDelegate(this); 1128 cache->tree.SetDelegate(this);
1128 cache->owner = this; 1129 cache->owner = this;
1129 tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache)); 1130 tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache));
1130 axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache)); 1131 axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache));
1131 } else { 1132 } else {
1132 cache = iter->second; 1133 cache = iter->second;
1133 } 1134 }
1134 1135
1135 // Update the internal state whether it's the active profile or not. 1136 // Update the internal state whether it's the active profile or not.
1136 cache->location_offset = params.location_offset;
1137 deleted_node_ids_.clear(); 1137 deleted_node_ids_.clear();
1138 v8::Isolate* isolate = GetIsolate(); 1138 v8::Isolate* isolate = GetIsolate();
1139 v8::HandleScope handle_scope(isolate); 1139 v8::HandleScope handle_scope(isolate);
1140 v8::Context::Scope context_scope(context()->v8_context()); 1140 v8::Context::Scope context_scope(context()->v8_context());
1141 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 1U)); 1141 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 1U));
1142 if (!cache->tree.Unserialize(params.update)) { 1142 if (!cache->tree.Unserialize(params.update)) {
1143 LOG(ERROR) << cache->tree.error(); 1143 LOG(ERROR) << cache->tree.error();
1144 args->Set(0U, v8::Number::New(isolate, tree_id)); 1144 args->Set(0U, v8::Number::New(isolate, tree_id));
1145 context()->DispatchEvent( 1145 context()->DispatchEvent(
1146 "automationInternal.onAccessibilityTreeSerializationError", args); 1146 "automationInternal.onAccessibilityTreeSerializationError", args);
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); 1393 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U));
1394 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); 1394 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id));
1395 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); 1395 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size()));
1396 args->Set(1U, nodes); 1396 args->Set(1U, nodes);
1397 for (size_t i = 0; i < ids.size(); ++i) 1397 for (size_t i = 0; i < ids.size(); ++i)
1398 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); 1398 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i]));
1399 context()->DispatchEvent("automationInternal.onNodesRemoved", args); 1399 context()->DispatchEvent("automationInternal.onNodesRemoved", args);
1400 } 1400 }
1401 1401
1402 } // namespace extensions 1402 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698