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

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

Issue 1705853002: NOT FOR REVIEW. ax tree focus with debugging (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed crash Created 4 years, 10 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 "base/bind.h" 10 #include "base/bind.h"
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 base::Bind(&AutomationInternalCustomBindings::FN, \ 409 base::Bind(&AutomationInternalCustomBindings::FN, \
410 base::Unretained(this))) 410 base::Unretained(this)))
411 ROUTE_FUNCTION(IsInteractPermitted); 411 ROUTE_FUNCTION(IsInteractPermitted);
412 ROUTE_FUNCTION(GetSchemaAdditions); 412 ROUTE_FUNCTION(GetSchemaAdditions);
413 ROUTE_FUNCTION(GetRoutingID); 413 ROUTE_FUNCTION(GetRoutingID);
414 ROUTE_FUNCTION(StartCachingAccessibilityTrees); 414 ROUTE_FUNCTION(StartCachingAccessibilityTrees);
415 ROUTE_FUNCTION(DestroyAccessibilityTree); 415 ROUTE_FUNCTION(DestroyAccessibilityTree);
416 ROUTE_FUNCTION(AddTreeChangeObserver); 416 ROUTE_FUNCTION(AddTreeChangeObserver);
417 ROUTE_FUNCTION(RemoveTreeChangeObserver); 417 ROUTE_FUNCTION(RemoveTreeChangeObserver);
418 ROUTE_FUNCTION(GetChildIDAtIndex); 418 ROUTE_FUNCTION(GetChildIDAtIndex);
419 ROUTE_FUNCTION(GetFocus);
420 ROUTE_FUNCTION(GetState);
419 #undef ROUTE_FUNCTION 421 #undef ROUTE_FUNCTION
420 422
421 // Bindings that take a Tree ID and return a property of the tree. 423 // Bindings that take a Tree ID and return a property of the tree.
422 424
423 RouteTreeIDFunction( 425 RouteTreeIDFunction(
424 "GetRootID", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, 426 "GetRootID", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
425 TreeCache* cache) { 427 TreeCache* cache) {
426 result.Set(v8::Integer::New(isolate, cache->tree.root()->id())); 428 result.Set(v8::Integer::New(isolate, cache->tree.root()->id()));
427 }); 429 });
428 RouteTreeIDFunction( 430 RouteTreeIDFunction(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 TreeCache* cache, ui::AXNode* node) { 486 TreeCache* cache, ui::AXNode* node) {
485 result.Set(v8::Integer::New(isolate, node->child_count())); 487 result.Set(v8::Integer::New(isolate, node->child_count()));
486 }); 488 });
487 RouteNodeIDFunction( 489 RouteNodeIDFunction(
488 "GetIndexInParent", 490 "GetIndexInParent",
489 [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, 491 [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
490 TreeCache* cache, ui::AXNode* node) { 492 TreeCache* cache, ui::AXNode* node) {
491 result.Set(v8::Integer::New(isolate, node->index_in_parent())); 493 result.Set(v8::Integer::New(isolate, node->index_in_parent()));
492 }); 494 });
493 RouteNodeIDFunction( 495 RouteNodeIDFunction(
494 "GetState", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
495 TreeCache* cache, ui::AXNode* node) {
496 v8::Local<v8::Object> state(v8::Object::New(isolate));
497 uint32_t state_pos = 0, state_shifter = node->data().state;
498 while (state_shifter) {
499 if (state_shifter & 1) {
500 std::string key = ToString(static_cast<ui::AXState>(state_pos));
501 state->Set(CreateV8String(isolate, key),
502 v8::Boolean::New(isolate, true));
503 }
504 state_shifter = state_shifter >> 1;
505 state_pos++;
506 }
507 result.Set(state);
508 });
509 RouteNodeIDFunction(
510 "GetRole", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, 496 "GetRole", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
511 TreeCache* cache, ui::AXNode* node) { 497 TreeCache* cache, ui::AXNode* node) {
512 std::string role_name = ui::ToString(node->data().role); 498 std::string role_name = ui::ToString(node->data().role);
513 result.Set(v8::String::NewFromUtf8(isolate, role_name.c_str())); 499 result.Set(v8::String::NewFromUtf8(isolate, role_name.c_str()));
514 }); 500 });
515 RouteNodeIDFunction( 501 RouteNodeIDFunction(
516 "GetLocation", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, 502 "GetLocation", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
517 TreeCache* cache, ui::AXNode* node) { 503 TreeCache* cache, ui::AXNode* node) {
518 gfx::Rect location = ComputeGlobalNodeBounds(cache, node); 504 gfx::Rect location = ComputeGlobalNodeBounds(cache, node);
519 location.Offset(cache->location_offset); 505 location.Offset(cache->location_offset);
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 iter != tree_change_observers_.end(); ++iter) { 756 iter != tree_change_observers_.end(); ++iter) {
771 if (iter->id == observer_id) { 757 if (iter->id == observer_id) {
772 tree_change_observers_.erase(iter); 758 tree_change_observers_.erase(iter);
773 break; 759 break;
774 } 760 }
775 } 761 }
776 762
777 UpdateOverallTreeChangeObserverFilter(); 763 UpdateOverallTreeChangeObserverFilter();
778 } 764 }
779 765
766 bool AutomationInternalCustomBindings::GetFocusInternal(TreeCache* cache,
767 TreeCache** out_cache,
768 ui::AXNode** out_node) {
769 int focus_id = cache->tree.data().focus_id;
770 ui::AXNode* focus = cache->tree.GetFromId(focus_id);
771 if (!focus)
772 return false;
773
774 while (focus->data().HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
775 // Try to keep following focus recursively, by letting |tree_id| be the
776 // new subtree to search in, while keeping |focus_tree_id| set to the tree
777 // where we know we found a focused node.
778 int child_tree_id =
779 focus->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID);
780
781 TreeCache* child_cache = GetTreeCacheFromTreeID(child_tree_id);
782 if (!child_cache)
783 break;
784
785 int child_focus_id = child_cache->tree.data().focus_id;
786 ui::AXNode* child_focus = child_cache->tree.GetFromId(child_focus_id);
787 if (!child_focus)
788 break;
789
790 focus = child_focus;
791 cache = child_cache;
792 }
793
794 *out_cache = cache;
795 *out_node = focus;
796 return true;
797 }
798
799 void AutomationInternalCustomBindings::GetFocus(
800 const v8::FunctionCallbackInfo<v8::Value>& args) {
801 if (args.Length() != 1 || !args[0]->IsNumber()) {
802 ThrowInvalidArgumentsException(this);
803 return;
804 }
805
806 int tree_id = args[0]->Int32Value();
807 TreeCache* cache = GetTreeCacheFromTreeID(tree_id);
808 if (!cache)
809 return;
810
811 TreeCache* focused_node_treecache = nullptr;
812 ui::AXNode* focused_node = nullptr;
813 if (!GetFocusInternal(cache, &focused_node_treecache, &focused_node)) {
814 LOG(ERROR) << "GetFocusInternal returning undefined";
815 return;
816 }
817 LOG(ERROR) << "GetFocusInternal returning a value";
818
819 v8::Isolate* isolate = GetIsolate();
820 v8::Local<v8::Object> result(v8::Object::New(isolate));
821 result->Set(CreateV8String(isolate, "treeId"),
822 v8::Integer::New(isolate, focused_node_treecache->tree_id));
823 result->Set(CreateV8String(isolate, "nodeId"),
824 v8::Integer::New(isolate, focused_node->id()));
825 args.GetReturnValue().Set(result);
826 }
827
828 void AutomationInternalCustomBindings::GetState(
829 const v8::FunctionCallbackInfo<v8::Value>& args) {
830 v8::Isolate* isolate = GetIsolate();
831 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber())
832 ThrowInvalidArgumentsException(this);
833
834 int tree_id = args[0]->Int32Value();
835 int node_id = args[1]->Int32Value();
836
837 TreeCache* cache = GetTreeCacheFromTreeID(tree_id);
838 if (!cache)
839 return;
840
841 ui::AXNode* node = cache->tree.GetFromId(node_id);
842 if (!node)
843 return;
844
845 v8::Local<v8::Object> state(v8::Object::New(isolate));
846 uint32_t state_pos = 0, state_shifter = node->data().state;
847 while (state_shifter) {
848 if (state_shifter & 1) {
849 std::string key = ToString(static_cast<ui::AXState>(state_pos));
850 state->Set(CreateV8String(isolate, key), v8::Boolean::New(isolate, true));
851 }
852 state_shifter = state_shifter >> 1;
853 state_pos++;
854 }
855
856 TreeCache* top_cache = GetTreeCacheFromTreeID(0);
857 if (!top_cache)
858 top_cache = cache;
859 TreeCache* focused_cache = nullptr;
860 ui::AXNode* focused_node = nullptr;
861 if (GetFocusInternal(top_cache, &focused_cache, &focused_node)) {
862 if (focused_cache == cache && focused_node == node) {
863 state->Set(CreateV8String(isolate, "focused"),
864 v8::Boolean::New(isolate, true));
865 }
866 }
867 if (cache->tree.data().focus_id == node->id()) {
868 state->Set(CreateV8String(isolate, "focused"),
869 v8::Boolean::New(isolate, true));
870 }
871
872 args.GetReturnValue().Set(state);
873 }
874
780 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { 875 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() {
781 tree_change_observer_overall_filter_ = 876 tree_change_observer_overall_filter_ =
782 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES; 877 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES;
783 for (const auto& observer : tree_change_observers_) { 878 for (const auto& observer : tree_change_observers_) {
784 tree_change_observer_overall_filter_ = 879 tree_change_observer_overall_filter_ =
785 std::max(observer.filter, tree_change_observer_overall_filter_); 880 std::max(observer.filter, tree_change_observer_overall_filter_);
786 } 881 }
787 } 882 }
788 883
789 void AutomationInternalCustomBindings::RouteTreeIDFunction( 884 void AutomationInternalCustomBindings::RouteTreeIDFunction(
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); 1149 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U));
1055 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); 1150 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id));
1056 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); 1151 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size()));
1057 args->Set(1U, nodes); 1152 args->Set(1U, nodes);
1058 for (size_t i = 0; i < ids.size(); ++i) 1153 for (size_t i = 0; i < ids.size(); ++i)
1059 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); 1154 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i]));
1060 context()->DispatchEvent("automationInternal.onNodesRemoved", args); 1155 context()->DispatchEvent("automationInternal.onNodesRemoved", args);
1061 } 1156 }
1062 1157
1063 } // namespace extensions 1158 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698