OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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; | |
David Tseng
2016/02/17 23:55:56
nit: focused_tree_cache
dmazzoni
2016/02/18 23:56:36
Done.
| |
812 ui::AXNode* focused_node = nullptr; | |
813 if (!GetFocusInternal(cache, &focused_node_treecache, &focused_node)) | |
814 return; | |
815 | |
816 v8::Isolate* isolate = GetIsolate(); | |
817 v8::Local<v8::Object> result(v8::Object::New(isolate)); | |
818 result->Set(CreateV8String(isolate, "treeId"), | |
819 v8::Integer::New(isolate, focused_node_treecache->tree_id)); | |
820 result->Set(CreateV8String(isolate, "nodeId"), | |
821 v8::Integer::New(isolate, focused_node->id())); | |
822 args.GetReturnValue().Set(result); | |
823 } | |
824 | |
825 void AutomationInternalCustomBindings::GetState( | |
826 const v8::FunctionCallbackInfo<v8::Value>& args) { | |
827 v8::Isolate* isolate = GetIsolate(); | |
828 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) | |
829 ThrowInvalidArgumentsException(this); | |
830 | |
831 int tree_id = args[0]->Int32Value(); | |
832 int node_id = args[1]->Int32Value(); | |
833 | |
834 TreeCache* cache = GetTreeCacheFromTreeID(tree_id); | |
835 if (!cache) | |
836 return; | |
837 | |
838 ui::AXNode* node = cache->tree.GetFromId(node_id); | |
839 if (!node) | |
840 return; | |
841 | |
842 v8::Local<v8::Object> state(v8::Object::New(isolate)); | |
843 uint32_t state_pos = 0, state_shifter = node->data().state; | |
844 while (state_shifter) { | |
845 if (state_shifter & 1) { | |
846 std::string key = ToString(static_cast<ui::AXState>(state_pos)); | |
847 state->Set(CreateV8String(isolate, key), v8::Boolean::New(isolate, true)); | |
848 } | |
849 state_shifter = state_shifter >> 1; | |
850 state_pos++; | |
851 } | |
852 | |
853 TreeCache* top_cache = GetTreeCacheFromTreeID(0); | |
854 if (!top_cache) | |
855 top_cache = cache; | |
856 TreeCache* focused_cache = nullptr; | |
857 ui::AXNode* focused_node = nullptr; | |
858 if (GetFocusInternal(top_cache, &focused_cache, &focused_node)) { | |
859 if (focused_cache == cache && focused_node == node) { | |
860 state->Set(CreateV8String(isolate, "focused"), | |
861 v8::Boolean::New(isolate, true)); | |
862 } | |
863 } | |
864 if (cache->tree.data().focus_id == node->id()) { | |
865 state->Set(CreateV8String(isolate, "focused"), | |
866 v8::Boolean::New(isolate, true)); | |
867 } | |
868 | |
869 args.GetReturnValue().Set(state); | |
870 } | |
871 | |
780 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { | 872 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { |
781 tree_change_observer_overall_filter_ = | 873 tree_change_observer_overall_filter_ = |
782 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES; | 874 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES; |
783 for (const auto& observer : tree_change_observers_) { | 875 for (const auto& observer : tree_change_observers_) { |
784 tree_change_observer_overall_filter_ = | 876 tree_change_observer_overall_filter_ = |
785 std::max(observer.filter, tree_change_observer_overall_filter_); | 877 std::max(observer.filter, tree_change_observer_overall_filter_); |
786 } | 878 } |
787 } | 879 } |
788 | 880 |
789 void AutomationInternalCustomBindings::RouteTreeIDFunction( | 881 void AutomationInternalCustomBindings::RouteTreeIDFunction( |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1054 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); | 1146 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); |
1055 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); | 1147 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); |
1056 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); | 1148 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); |
1057 args->Set(1U, nodes); | 1149 args->Set(1U, nodes); |
1058 for (size_t i = 0; i < ids.size(); ++i) | 1150 for (size_t i = 0; i < ids.size(); ++i) |
1059 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); | 1151 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); |
1060 context()->DispatchEvent("automationInternal.onNodesRemoved", args); | 1152 context()->DispatchEvent("automationInternal.onNodesRemoved", args); |
1061 } | 1153 } |
1062 | 1154 |
1063 } // namespace extensions | 1155 } // namespace extensions |
OLD | NEW |