| 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 "ash/common/devtools/ash_devtools_dom_agent.h" | 5 #include "ash/common/devtools/ash_devtools_dom_agent.h" |
| 6 | 6 |
| 7 #include "ash/common/wm_window.h" | 7 #include "ash/common/wm_window.h" |
| 8 #include "components/ui_devtools/devtools_server.h" | 8 #include "components/ui_devtools/devtools_server.h" |
| 9 #include "ui/views/view.h" | 9 #include "ui/views/view.h" |
| 10 #include "ui/views/widget/widget.h" | 10 #include "ui/views/widget/widget.h" |
| 11 | 11 |
| 12 namespace ash { | 12 namespace ash { |
| 13 namespace devtools { | 13 namespace devtools { |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 using namespace ui::devtools::protocol; | 16 using namespace ui::devtools::protocol; |
| 17 DOM::NodeId node_ids = 1; |
| 17 | 18 |
| 18 std::unique_ptr<DOM::Node> BuildNode( | 19 std::unique_ptr<DOM::Node> BuildNode( |
| 19 const std::string& name, | 20 const std::string& name, |
| 20 std::unique_ptr<Array<std::string>> attributes, | 21 std::unique_ptr<Array<std::string>> attributes, |
| 21 std::unique_ptr<Array<DOM::Node>> children) { | 22 std::unique_ptr<Array<DOM::Node>> children) { |
| 22 static DOM::NodeId node_ids = 0; | |
| 23 constexpr int kDomElementNodeType = 1; | 23 constexpr int kDomElementNodeType = 1; |
| 24 std::unique_ptr<DOM::Node> node = DOM::Node::create() | 24 std::unique_ptr<DOM::Node> node = DOM::Node::create() |
| 25 .setNodeId(node_ids++) | 25 .setNodeId(node_ids++) |
| 26 .setNodeName(name) | 26 .setNodeName(name) |
| 27 .setNodeType(kDomElementNodeType) | 27 .setNodeType(kDomElementNodeType) |
| 28 .setAttributes(std::move(attributes)) | 28 .setAttributes(std::move(attributes)) |
| 29 .build(); | 29 .build(); |
| 30 node->setChildNodeCount(children->length()); | 30 node->setChildNodeCount(children->length()); |
| 31 node->setChildren(std::move(children)); | 31 node->setChildren(std::move(children)); |
| 32 return node; | 32 return node; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 } | 64 } |
| 65 return BuildNode("View", GetAttributes(view), std::move(children)); | 65 return BuildNode("View", GetAttributes(view), std::move(children)); |
| 66 } | 66 } |
| 67 | 67 |
| 68 std::unique_ptr<DOM::Node> BuildTreeForRootWidget(views::Widget* widget) { | 68 std::unique_ptr<DOM::Node> BuildTreeForRootWidget(views::Widget* widget) { |
| 69 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); | 69 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); |
| 70 children->addItem(BuildTreeForView(widget->GetRootView())); | 70 children->addItem(BuildTreeForView(widget->GetRootView())); |
| 71 return BuildNode("Widget", GetAttributes(widget), std::move(children)); | 71 return BuildNode("Widget", GetAttributes(widget), std::move(children)); |
| 72 } | 72 } |
| 73 | 73 |
| 74 std::unique_ptr<DOM::Node> BuildTreeForWindow(ash::WmWindow* window) { | 74 WmWindow* FindPreviousSibling(WmWindow* window) { |
| 75 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); | 75 std::vector<WmWindow*> siblings = window->GetParent()->GetChildren(); |
| 76 for (ash::WmWindow* child : window->GetChildren()) { | 76 std::vector<WmWindow*>::iterator it = |
| 77 children->addItem(BuildTreeForWindow(child)); | 77 std::find(siblings.begin(), siblings.end(), window); |
| 78 views::Widget* widget = child->GetInternalWidget(); | 78 DCHECK(it != siblings.end()); |
| 79 if (widget) | 79 // If this is the first child of its parent, the previous sibling is null |
| 80 children->addItem(BuildTreeForRootWidget(widget)); | 80 return it == siblings.begin() ? nullptr : *std::prev(it); |
| 81 } | |
| 82 return BuildNode("Window", GetAttributes(window), std::move(children)); | |
| 83 } | 81 } |
| 84 | 82 |
| 85 } // namespace | 83 } // namespace |
| 86 | 84 |
| 87 AshDevToolsDOMAgent::AshDevToolsDOMAgent(ash::WmShell* shell) : shell_(shell) { | 85 AshDevToolsDOMAgent::AshDevToolsDOMAgent(ash::WmShell* shell) : shell_(shell) { |
| 88 DCHECK(shell_); | 86 DCHECK(shell_); |
| 89 } | 87 } |
| 90 | 88 |
| 91 AshDevToolsDOMAgent::~AshDevToolsDOMAgent() {} | 89 AshDevToolsDOMAgent::~AshDevToolsDOMAgent() { |
| 90 RemoveObserverFromAllWindows(); |
| 91 } |
| 92 |
| 93 ui::devtools::protocol::Response AshDevToolsDOMAgent::disable() { |
| 94 Reset(); |
| 95 return ui::devtools::protocol::Response::OK(); |
| 96 } |
| 97 |
| 98 ui::devtools::protocol::Response AshDevToolsDOMAgent::getDocument( |
| 99 std::unique_ptr<ui::devtools::protocol::DOM::Node>* out_root) { |
| 100 *out_root = BuildInitialTree(); |
| 101 return ui::devtools::protocol::Response::OK(); |
| 102 } |
| 103 |
| 104 // Need to remove node in OnWindowDestroying because the window parent reference |
| 105 // is gone in OnWindowDestroyed |
| 106 void AshDevToolsDOMAgent::OnWindowDestroying(WmWindow* window) { |
| 107 RemoveWindowNode(window, window->GetParent()); |
| 108 } |
| 109 |
| 110 void AshDevToolsDOMAgent::OnWindowTreeChanged(WmWindow* window, |
| 111 const TreeChangeParams& params) { |
| 112 // Only trigger this when window == root window. |
| 113 // Removals are handled on OnWindowDestroying. |
| 114 if (window != window->GetRootWindow() || !params.new_parent) |
| 115 return; |
| 116 // If there is an old_parent + new_parent, then this window is being moved |
| 117 // which requires a remove followed by an add. If only new_parent |
| 118 // exists, then a new window is being created so only add is called. |
| 119 if (params.old_parent) |
| 120 RemoveWindowNode(params.target, params.old_parent); |
| 121 AddWindowNode(params.target); |
| 122 } |
| 123 |
| 124 void AshDevToolsDOMAgent::OnWindowStackingChanged(WmWindow* window) { |
| 125 RemoveWindowNode(window, window->GetParent()); |
| 126 AddWindowNode(window); |
| 127 } |
| 128 |
| 129 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForWindow( |
| 130 ash::WmWindow* window) { |
| 131 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); |
| 132 for (ash::WmWindow* child : window->GetChildren()) { |
| 133 children->addItem(BuildTreeForWindow(child)); |
| 134 views::Widget* widget = child->GetInternalWidget(); |
| 135 if (widget) |
| 136 children->addItem(BuildTreeForRootWidget(widget)); |
| 137 } |
| 138 std::unique_ptr<ui::devtools::protocol::DOM::Node> node = |
| 139 BuildNode("Window", GetAttributes(window), std::move(children)); |
| 140 // Only add as observer if window is not in map |
| 141 if (!window_to_node_id_map_.count(window)) |
| 142 window->AddObserver(this); |
| 143 window_to_node_id_map_[window] = node->getNodeId(); |
| 144 return node; |
| 145 } |
| 92 | 146 |
| 93 std::unique_ptr<ui::devtools::protocol::DOM::Node> | 147 std::unique_ptr<ui::devtools::protocol::DOM::Node> |
| 94 AshDevToolsDOMAgent::BuildInitialTree() { | 148 AshDevToolsDOMAgent::BuildInitialTree() { |
| 95 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); | 149 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); |
| 96 for (ash::WmWindow* window : shell_->GetAllRootWindows()) { | 150 for (ash::WmWindow* window : shell_->GetAllRootWindows()) { |
| 97 children->addItem(BuildTreeForWindow(window)); | 151 children->addItem(BuildTreeForWindow(window)); |
| 98 } | 152 } |
| 99 return BuildNode("root", nullptr, std::move(children)); | 153 return BuildNode("root", nullptr, std::move(children)); |
| 100 } | 154 } |
| 101 | 155 |
| 102 ui::devtools::protocol::Response AshDevToolsDOMAgent::enable() { | 156 void AshDevToolsDOMAgent::AddWindowNode(WmWindow* window) { |
| 103 return ui::devtools::protocol::Response::OK(); | 157 WmWindow* prev_sibling = FindPreviousSibling(window); |
| 158 frontend()->childNodeInserted( |
| 159 window_to_node_id_map_[window->GetParent()], |
| 160 prev_sibling ? window_to_node_id_map_[prev_sibling] : 0, |
| 161 BuildTreeForWindow(window)); |
| 104 } | 162 } |
| 105 | 163 |
| 106 ui::devtools::protocol::Response AshDevToolsDOMAgent::disable() { | 164 void AshDevToolsDOMAgent::RemoveWindowNode(WmWindow* window, |
| 107 return ui::devtools::protocol::Response::OK(); | 165 WmWindow* old_parent) { |
| 166 window->RemoveObserver(this); |
| 167 WindowToNodeIdMap::iterator it = window_to_node_id_map_.find(window); |
| 168 DCHECK(it != window_to_node_id_map_.end()); |
| 169 |
| 170 int node_id = it->second; |
| 171 int parent_id = old_parent ? window_to_node_id_map_[old_parent] : 0; |
| 172 |
| 173 window_to_node_id_map_.erase(it); |
| 174 frontend()->childNodeRemoved(parent_id, node_id); |
| 108 } | 175 } |
| 109 | 176 |
| 110 ui::devtools::protocol::Response AshDevToolsDOMAgent::getDocument( | 177 void AshDevToolsDOMAgent::RemoveObserverFromAllWindows() { |
| 111 std::unique_ptr<ui::devtools::protocol::DOM::Node>* out_root) { | 178 for (auto& pair : window_to_node_id_map_) |
| 112 *out_root = BuildInitialTree(); | 179 pair.first->RemoveObserver(this); |
| 113 return ui::devtools::protocol::Response::OK(); | 180 } |
| 181 |
| 182 void AshDevToolsDOMAgent::Reset() { |
| 183 RemoveObserverFromAllWindows(); |
| 184 window_to_node_id_map_.clear(); |
| 185 node_ids = 1; |
| 114 } | 186 } |
| 115 | 187 |
| 116 } // namespace devtools | 188 } // namespace devtools |
| 117 } // namespace ash | 189 } // namespace ash |
| OLD | NEW |