| 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 |