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

Side by Side Diff: ash/common/devtools/ash_devtools_dom_agent.cc

Issue 2466073003: Push updates to inspector when windows are added, destroyed or reorganized (Closed)
Patch Set: Document previous sibling id Created 4 years, 1 month 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 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
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
OLDNEW
« no previous file with comments | « ash/common/devtools/ash_devtools_dom_agent.h ('k') | ash/common/devtools/ash_devtools_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698