OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/ui_devtools/views/ui_devtools_dom_agent.h" | 5 #include "components/ui_devtools/views/ui_devtools_dom_agent.h" |
6 | 6 |
7 #include "components/ui_devtools/devtools_server.h" | 7 #include "components/ui_devtools/devtools_server.h" |
| 8 #include "components/ui_devtools/views/ui_devtools_overlay_agent.h" |
8 #include "components/ui_devtools/views/ui_element.h" | 9 #include "components/ui_devtools/views/ui_element.h" |
9 #include "components/ui_devtools/views/view_element.h" | 10 #include "components/ui_devtools/views/view_element.h" |
10 #include "components/ui_devtools/views/widget_element.h" | 11 #include "components/ui_devtools/views/widget_element.h" |
11 #include "components/ui_devtools/views/window_element.h" | 12 #include "components/ui_devtools/views/window_element.h" |
12 #include "third_party/skia/include/core/SkColor.h" | 13 #include "third_party/skia/include/core/SkColor.h" |
13 #include "ui/aura/client/screen_position_client.h" | 14 #include "ui/aura/client/screen_position_client.h" |
14 #include "ui/aura/env.h" | 15 #include "ui/aura/env.h" |
15 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
16 #include "ui/aura/window_tree_host.h" | 17 #include "ui/aura/window_tree_host.h" |
17 #include "ui/display/display.h" | 18 #include "ui/display/display.h" |
18 #include "ui/display/screen.h" | 19 #include "ui/display/screen.h" |
19 #include "ui/views/background.h" | 20 #include "ui/views/background.h" |
20 #include "ui/views/border.h" | 21 #include "ui/views/border.h" |
| 22 #include "ui/views/pointer_watcher.h" |
21 #include "ui/views/view.h" | 23 #include "ui/views/view.h" |
22 #include "ui/views/widget/widget.h" | 24 #include "ui/views/widget/widget.h" |
23 #include "ui/wm/core/window_util.h" | 25 #include "ui/wm/core/window_util.h" |
24 | 26 |
25 namespace ui_devtools { | 27 namespace ui_devtools { |
26 namespace { | 28 namespace { |
27 | 29 |
28 using namespace ui_devtools::protocol; | 30 using namespace ui_devtools::protocol; |
29 // TODO(mhashmi): Make ids reusable | 31 // TODO(mhashmi): Make ids reusable |
30 | 32 |
31 std::unique_ptr<DOM::Node> BuildNode( | 33 std::unique_ptr<DOM::Node> BuildNode( |
32 const std::string& name, | 34 const std::string& name, |
33 std::unique_ptr<Array<std::string>> attributes, | 35 std::unique_ptr<Array<std::string>> attributes, |
34 std::unique_ptr<Array<DOM::Node>> children, | 36 std::unique_ptr<Array<DOM::Node>> children, |
35 int node_ids) { | 37 int node_ids) { |
36 constexpr int kDomElementNodeType = 1; | 38 constexpr int kDomElementNodeType = 1; |
37 std::unique_ptr<DOM::Node> node = DOM::Node::create() | 39 std::unique_ptr<DOM::Node> node = DOM::Node::create() |
38 .setNodeId(node_ids) | 40 .setNodeId(node_ids) |
| 41 .setBackendNodeId(node_ids) |
39 .setNodeName(name) | 42 .setNodeName(name) |
40 .setNodeType(kDomElementNodeType) | 43 .setNodeType(kDomElementNodeType) |
41 .setAttributes(std::move(attributes)) | 44 .setAttributes(std::move(attributes)) |
42 .build(); | 45 .build(); |
43 node->setChildNodeCount(static_cast<int>(children->length())); | 46 node->setChildNodeCount(static_cast<int>(children->length())); |
44 node->setChildren(std::move(children)); | 47 node->setChildren(std::move(children)); |
45 return node; | 48 return node; |
46 } | 49 } |
47 | 50 |
48 // TODO(thanhph): Move this function to UIElement::GetAttributes(). | 51 // TODO(thanhph): Move this function to UIElement::GetAttributes(). |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 } | 101 } |
99 | 102 |
100 std::unique_ptr<DOM::Node> BuildDomNodeFromUIElement(UIElement* root) { | 103 std::unique_ptr<DOM::Node> BuildDomNodeFromUIElement(UIElement* root) { |
101 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); | 104 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); |
102 for (auto* it : root->children()) | 105 for (auto* it : root->children()) |
103 children->addItem(BuildDomNodeFromUIElement(it)); | 106 children->addItem(BuildDomNodeFromUIElement(it)); |
104 | 107 |
105 constexpr int kDomElementNodeType = 1; | 108 constexpr int kDomElementNodeType = 1; |
106 std::unique_ptr<DOM::Node> node = DOM::Node::create() | 109 std::unique_ptr<DOM::Node> node = DOM::Node::create() |
107 .setNodeId(root->node_id()) | 110 .setNodeId(root->node_id()) |
| 111 .setBackendNodeId(root->node_id()) |
108 .setNodeName(root->GetTypeName()) | 112 .setNodeName(root->GetTypeName()) |
109 .setNodeType(kDomElementNodeType) | 113 .setNodeType(kDomElementNodeType) |
110 .setAttributes(GetAttributes(root)) | 114 .setAttributes(GetAttributes(root)) |
111 .build(); | 115 .build(); |
112 node->setChildNodeCount(static_cast<int>(children->length())); | 116 node->setChildNodeCount(static_cast<int>(children->length())); |
113 node->setChildren(std::move(children)); | 117 node->setChildren(std::move(children)); |
114 return node; | 118 return node; |
115 } | 119 } |
116 | 120 |
| 121 int FindUIElementIdForView(UIElement* root, views::View* element) { |
| 122 if (root->type() == UIElementType::VIEW && |
| 123 UIElement::GetBackingElement<views::View, ViewElement>(root) == element) |
| 124 return root->node_id(); |
| 125 |
| 126 for (auto* child : root->children()) { |
| 127 int ui_element_id = FindUIElementIdForView(child, element); |
| 128 if (ui_element_id) |
| 129 return ui_element_id; |
| 130 } |
| 131 return 0; |
| 132 } |
| 133 |
| 134 int FindUIElementIdForWidget(UIElement* root, views::Widget* element) { |
| 135 if (root->type() == UIElementType::WIDGET && |
| 136 UIElement::GetBackingElement<views::Widget, WidgetElement>(root) == |
| 137 element) |
| 138 return root->node_id(); |
| 139 |
| 140 for (auto* child : root->children()) { |
| 141 int ui_element_id = FindUIElementIdForWidget(child, element); |
| 142 if (ui_element_id) |
| 143 return ui_element_id; |
| 144 } |
| 145 return 0; |
| 146 } |
| 147 |
| 148 int FindUIElementIdForWindow(UIElement* root, aura::Window* element) { |
| 149 if (root->type() == UIElementType::WINDOW && |
| 150 UIElement::GetBackingElement<aura::Window, WindowElement>(root) == |
| 151 element) |
| 152 return root->node_id(); |
| 153 |
| 154 for (auto* child : root->children()) { |
| 155 int ui_element_id = FindUIElementIdForWindow(child, element); |
| 156 if (ui_element_id) |
| 157 return ui_element_id; |
| 158 } |
| 159 return 0; |
| 160 } |
| 161 |
117 } // namespace | 162 } // namespace |
118 | 163 |
119 UIDevToolsDOMAgent::UIDevToolsDOMAgent() : is_building_tree_(false) { | 164 UIDevToolsDOMAgent::UIDevToolsDOMAgent() : is_building_tree_(false) { |
120 aura::Env::GetInstance()->AddObserver(this); | 165 aura::Env::GetInstance()->AddObserver(this); |
121 } | 166 } |
122 | 167 |
123 UIDevToolsDOMAgent::~UIDevToolsDOMAgent() { | 168 UIDevToolsDOMAgent::~UIDevToolsDOMAgent() { |
124 aura::Env::GetInstance()->RemoveObserver(this); | 169 aura::Env::GetInstance()->RemoveObserver(this); |
125 Reset(); | 170 Reset(); |
126 } | 171 } |
127 | 172 |
128 ui_devtools::protocol::Response UIDevToolsDOMAgent::disable() { | 173 ui_devtools::protocol::Response UIDevToolsDOMAgent::disable() { |
129 Reset(); | 174 Reset(); |
130 return ui_devtools::protocol::Response::OK(); | 175 return ui_devtools::protocol::Response::OK(); |
131 } | 176 } |
132 | 177 |
133 ui_devtools::protocol::Response UIDevToolsDOMAgent::getDocument( | 178 ui_devtools::protocol::Response UIDevToolsDOMAgent::getDocument( |
134 std::unique_ptr<ui_devtools::protocol::DOM::Node>* out_root) { | 179 std::unique_ptr<ui_devtools::protocol::DOM::Node>* out_root) { |
135 *out_root = BuildInitialTree(); | 180 *out_root = BuildInitialTree(); |
136 return ui_devtools::protocol::Response::OK(); | 181 return ui_devtools::protocol::Response::OK(); |
137 } | 182 } |
138 | 183 |
139 ui_devtools::protocol::Response UIDevToolsDOMAgent::highlightNode( | |
140 std::unique_ptr<ui_devtools::protocol::DOM::HighlightConfig> | |
141 highlight_config, | |
142 ui_devtools::protocol::Maybe<int> node_id) { | |
143 return HighlightNode(std::move(highlight_config), node_id.fromJust()); | |
144 } | |
145 | |
146 ui_devtools::protocol::Response UIDevToolsDOMAgent::hideHighlight() { | 184 ui_devtools::protocol::Response UIDevToolsDOMAgent::hideHighlight() { |
147 if (layer_for_highlighting_ && layer_for_highlighting_->visible()) | 185 if (layer_for_highlighting_ && layer_for_highlighting_->visible()) |
148 layer_for_highlighting_->SetVisible(false); | 186 layer_for_highlighting_->SetVisible(false); |
149 return ui_devtools::protocol::Response::OK(); | 187 return ui_devtools::protocol::Response::OK(); |
150 } | 188 } |
151 | 189 |
| 190 ui_devtools::protocol::Response |
| 191 UIDevToolsDOMAgent::pushNodesByBackendIdsToFrontend( |
| 192 std::unique_ptr<protocol::Array<int>> backend_node_ids, |
| 193 std::unique_ptr<protocol::Array<int>>* result) { |
| 194 *result = protocol::Array<int>::create(); |
| 195 for (size_t index = 0; index < backend_node_ids->length(); ++index) |
| 196 (*result)->addItem(backend_node_ids->get(index)); |
| 197 return ui_devtools::protocol::Response::OK(); |
| 198 } |
| 199 |
| 200 ui_devtools::protocol::Response UIDevToolsDOMAgent::setInspectedNode( |
| 201 int node_id) { |
| 202 return ui_devtools::protocol::Response::OK(); |
| 203 } |
| 204 |
152 void UIDevToolsDOMAgent::OnUIElementAdded(UIElement* parent, UIElement* child) { | 205 void UIDevToolsDOMAgent::OnUIElementAdded(UIElement* parent, UIElement* child) { |
153 // When parent is null, only need to update |node_id_to_ui_element_|. | 206 // When parent is null, only need to update |node_id_to_ui_element_|. |
154 if (!parent) { | 207 if (!parent) { |
155 node_id_to_ui_element_[child->node_id()] = child; | 208 node_id_to_ui_element_[child->node_id()] = child; |
156 return; | 209 return; |
157 } | 210 } |
158 // If tree is being built, don't add child to dom tree again. | 211 // If tree is being built, don't add child to dom tree again. |
159 if (is_building_tree_) | 212 if (is_building_tree_) |
160 return; | 213 return; |
161 DCHECK(node_id_to_ui_element_.count(parent->node_id())); | 214 DCHECK(node_id_to_ui_element_.count(parent->node_id())); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 } | 251 } |
199 | 252 |
200 void UIDevToolsDOMAgent::RemoveObserver(UIDevToolsDOMAgentObserver* observer) { | 253 void UIDevToolsDOMAgent::RemoveObserver(UIDevToolsDOMAgentObserver* observer) { |
201 observers_.RemoveObserver(observer); | 254 observers_.RemoveObserver(observer); |
202 } | 255 } |
203 | 256 |
204 UIElement* UIDevToolsDOMAgent::GetElementFromNodeId(int node_id) { | 257 UIElement* UIDevToolsDOMAgent::GetElementFromNodeId(int node_id) { |
205 return node_id_to_ui_element_[node_id]; | 258 return node_id_to_ui_element_[node_id]; |
206 } | 259 } |
207 | 260 |
| 261 ui_devtools::protocol::Response UIDevToolsDOMAgent::HighlightNode( |
| 262 std::unique_ptr<ui_devtools::protocol::Overlay::HighlightConfig> |
| 263 highlight_config, |
| 264 int node_id) { |
| 265 if (!layer_for_highlighting_) { |
| 266 layer_for_highlighting_.reset( |
| 267 new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR)); |
| 268 layer_for_highlighting_->set_name("HighlightingLayer"); |
| 269 } |
| 270 |
| 271 std::pair<aura::Window*, gfx::Rect> window_and_bounds = |
| 272 node_id_to_ui_element_.count(node_id) |
| 273 ? node_id_to_ui_element_[node_id]->GetNodeWindowAndBounds() |
| 274 : std::make_pair<aura::Window*, gfx::Rect>(nullptr, gfx::Rect()); |
| 275 |
| 276 if (!window_and_bounds.first) { |
| 277 return ui_devtools::protocol::Response::Error("No node found with that id"); |
| 278 } |
| 279 SkColor content_color = |
| 280 RGBAToSkColor(highlight_config->getContentColor(nullptr)); |
| 281 UpdateHighlight(window_and_bounds, content_color); |
| 282 |
| 283 if (!layer_for_highlighting_->visible()) |
| 284 layer_for_highlighting_->SetVisible(true); |
| 285 |
| 286 return ui_devtools::protocol::Response::OK(); |
| 287 } |
| 288 |
| 289 void UIDevToolsDOMAgent::FindElementByEventHandler(const gfx::Point& p, |
| 290 int* element_id) { |
| 291 for (auto* element_window : window_element_root_->children()) { |
| 292 aura::Window* window = |
| 293 UIElement::GetBackingElement<aura::Window, WindowElement>( |
| 294 element_window); |
| 295 if (!window->bounds().Contains(p)) |
| 296 return; |
| 297 aura::Window* point_window = window->GetEventHandlerForPoint(p); |
| 298 |
| 299 if (point_window) { |
| 300 views::Widget* widget = |
| 301 views::Widget::GetWidgetForNativeWindow(point_window); |
| 302 |
| 303 if (widget) { |
| 304 views::View* view = widget->GetRootView(); |
| 305 |
| 306 if (view) { |
| 307 gfx::Point p_inside(p); |
| 308 aura::Window::ConvertPointToTarget(window, point_window, &p_inside); |
| 309 views::View* point_view = view->GetEventHandlerForPoint(p_inside); |
| 310 |
| 311 DCHECK(point_view); |
| 312 *element_id = FindUIElementIdForView(element_window, point_view); |
| 313 } else { |
| 314 *element_id = FindUIElementIdForWidget(element_window, widget); |
| 315 } |
| 316 } else { |
| 317 *element_id = FindUIElementIdForWindow(element_window, point_window); |
| 318 } |
| 319 } |
| 320 } |
| 321 } |
| 322 |
208 void UIDevToolsDOMAgent::OnHostInitialized(aura::WindowTreeHost* host) { | 323 void UIDevToolsDOMAgent::OnHostInitialized(aura::WindowTreeHost* host) { |
209 root_windows_.push_back(host->window()); | 324 root_windows_.push_back(host->window()); |
210 } | 325 } |
211 | 326 |
212 void UIDevToolsDOMAgent::OnNodeBoundsChanged(int node_id) { | 327 void UIDevToolsDOMAgent::OnNodeBoundsChanged(int node_id) { |
213 for (auto& observer : observers_) | 328 for (auto& observer : observers_) |
214 observer.OnNodeBoundsChanged(node_id); | 329 observer.OnNodeBoundsChanged(node_id); |
215 } | 330 } |
216 | 331 |
217 std::unique_ptr<ui_devtools::protocol::DOM::Node> | 332 std::unique_ptr<ui_devtools::protocol::DOM::Node> |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 aura::client::ScreenPositionClient* screen_position_client = | 461 aura::client::ScreenPositionClient* screen_position_client = |
347 aura::client::GetScreenPositionClient(root); | 462 aura::client::GetScreenPositionClient(root); |
348 | 463 |
349 gfx::Rect bounds(window_and_bounds.second); | 464 gfx::Rect bounds(window_and_bounds.second); |
350 gfx::Point origin = bounds.origin(); | 465 gfx::Point origin = bounds.origin(); |
351 screen_position_client->ConvertPointFromScreen(root, &origin); | 466 screen_position_client->ConvertPointFromScreen(root, &origin); |
352 bounds.set_origin(origin); | 467 bounds.set_origin(origin); |
353 layer_for_highlighting_->SetBounds(bounds); | 468 layer_for_highlighting_->SetBounds(bounds); |
354 } | 469 } |
355 | 470 |
356 ui_devtools::protocol::Response UIDevToolsDOMAgent::HighlightNode( | |
357 std::unique_ptr<ui_devtools::protocol::DOM::HighlightConfig> | |
358 highlight_config, | |
359 int node_id) { | |
360 if (!layer_for_highlighting_) { | |
361 layer_for_highlighting_.reset( | |
362 new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR)); | |
363 layer_for_highlighting_->set_name("HighlightingLayer"); | |
364 } | |
365 | |
366 std::pair<aura::Window*, gfx::Rect> window_and_bounds = | |
367 node_id_to_ui_element_.count(node_id) | |
368 ? node_id_to_ui_element_[node_id]->GetNodeWindowAndBounds() | |
369 : std::make_pair<aura::Window*, gfx::Rect>(nullptr, gfx::Rect()); | |
370 | |
371 if (!window_and_bounds.first) { | |
372 return ui_devtools::protocol::Response::Error("No node found with that id"); | |
373 } | |
374 SkColor content_color = | |
375 RGBAToSkColor(highlight_config->getContentColor(nullptr)); | |
376 UpdateHighlight(window_and_bounds, content_color); | |
377 | |
378 if (!layer_for_highlighting_->visible()) | |
379 layer_for_highlighting_->SetVisible(true); | |
380 | |
381 return ui_devtools::protocol::Response::OK(); | |
382 } | |
383 | |
384 } // namespace ui_devtools | 471 } // namespace ui_devtools |
OLD | NEW |