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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ash/common/devtools/ash_devtools_dom_agent.cc
diff --git a/ash/common/devtools/ash_devtools_dom_agent.cc b/ash/common/devtools/ash_devtools_dom_agent.cc
index 366ab9b7e6855422cb13cb76165ba3b2d619839a..8640892d34058c41bf04db7ee5f345c1f347a7d3 100644
--- a/ash/common/devtools/ash_devtools_dom_agent.cc
+++ b/ash/common/devtools/ash_devtools_dom_agent.cc
@@ -14,12 +14,12 @@ namespace devtools {
namespace {
using namespace ui::devtools::protocol;
+DOM::NodeId node_ids = 1;
std::unique_ptr<DOM::Node> BuildNode(
const std::string& name,
std::unique_ptr<Array<std::string>> attributes,
std::unique_ptr<Array<DOM::Node>> children) {
- static DOM::NodeId node_ids = 0;
constexpr int kDomElementNodeType = 1;
std::unique_ptr<DOM::Node> node = DOM::Node::create()
.setNodeId(node_ids++)
@@ -71,15 +71,13 @@ std::unique_ptr<DOM::Node> BuildTreeForRootWidget(views::Widget* widget) {
return BuildNode("Widget", GetAttributes(widget), std::move(children));
}
-std::unique_ptr<DOM::Node> BuildTreeForWindow(ash::WmWindow* window) {
- std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
- for (ash::WmWindow* child : window->GetChildren()) {
- children->addItem(BuildTreeForWindow(child));
- views::Widget* widget = child->GetInternalWidget();
- if (widget)
- children->addItem(BuildTreeForRootWidget(widget));
- }
- return BuildNode("Window", GetAttributes(window), std::move(children));
+WmWindow* FindPreviousSibling(WmWindow* window) {
+ std::vector<WmWindow*> siblings = window->GetParent()->GetChildren();
+ std::vector<WmWindow*>::iterator it =
+ std::find(siblings.begin(), siblings.end(), window);
+ DCHECK(it != siblings.end());
+ // If this is the first child of its parent, the previous sibling is null
+ return it == siblings.begin() ? nullptr : *std::prev(it);
}
} // namespace
@@ -88,7 +86,63 @@ AshDevToolsDOMAgent::AshDevToolsDOMAgent(ash::WmShell* shell) : shell_(shell) {
DCHECK(shell_);
}
-AshDevToolsDOMAgent::~AshDevToolsDOMAgent() {}
+AshDevToolsDOMAgent::~AshDevToolsDOMAgent() {
+ RemoveObserverFromAllWindows();
+}
+
+ui::devtools::protocol::Response AshDevToolsDOMAgent::disable() {
+ Reset();
+ return ui::devtools::protocol::Response::OK();
+}
+
+ui::devtools::protocol::Response AshDevToolsDOMAgent::getDocument(
+ std::unique_ptr<ui::devtools::protocol::DOM::Node>* out_root) {
+ *out_root = BuildInitialTree();
+ return ui::devtools::protocol::Response::OK();
+}
+
+// Need to remove node in OnWindowDestroying because the window parent reference
+// is gone in OnWindowDestroyed
+void AshDevToolsDOMAgent::OnWindowDestroying(WmWindow* window) {
+ RemoveWindowNode(window, window->GetParent());
+}
+
+void AshDevToolsDOMAgent::OnWindowTreeChanged(WmWindow* window,
+ const TreeChangeParams& params) {
+ // Only trigger this when window == root window.
+ // Removals are handled on OnWindowDestroying.
+ if (window != window->GetRootWindow() || !params.new_parent)
+ return;
+ // If there is an old_parent + new_parent, then this window is being moved
+ // which requires a remove followed by an add. If only new_parent
+ // exists, then a new window is being created so only add is called.
+ if (params.old_parent)
+ RemoveWindowNode(params.target, params.old_parent);
+ AddWindowNode(params.target);
+}
+
+void AshDevToolsDOMAgent::OnWindowStackingChanged(WmWindow* window) {
+ RemoveWindowNode(window, window->GetParent());
+ AddWindowNode(window);
+}
+
+std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForWindow(
+ ash::WmWindow* window) {
+ std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
+ for (ash::WmWindow* child : window->GetChildren()) {
+ children->addItem(BuildTreeForWindow(child));
+ views::Widget* widget = child->GetInternalWidget();
+ if (widget)
+ children->addItem(BuildTreeForRootWidget(widget));
+ }
+ std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
+ BuildNode("Window", GetAttributes(window), std::move(children));
+ // Only add as observer if window is not in map
+ if (!window_to_node_id_map_.count(window))
+ window->AddObserver(this);
+ window_to_node_id_map_[window] = node->getNodeId();
+ return node;
+}
std::unique_ptr<ui::devtools::protocol::DOM::Node>
AshDevToolsDOMAgent::BuildInitialTree() {
@@ -99,18 +153,36 @@ AshDevToolsDOMAgent::BuildInitialTree() {
return BuildNode("root", nullptr, std::move(children));
}
-ui::devtools::protocol::Response AshDevToolsDOMAgent::enable() {
- return ui::devtools::protocol::Response::OK();
+void AshDevToolsDOMAgent::AddWindowNode(WmWindow* window) {
+ WmWindow* prev_sibling = FindPreviousSibling(window);
+ frontend()->childNodeInserted(
+ window_to_node_id_map_[window->GetParent()],
+ prev_sibling ? window_to_node_id_map_[prev_sibling] : 0,
+ BuildTreeForWindow(window));
}
-ui::devtools::protocol::Response AshDevToolsDOMAgent::disable() {
- return ui::devtools::protocol::Response::OK();
+void AshDevToolsDOMAgent::RemoveWindowNode(WmWindow* window,
+ WmWindow* old_parent) {
+ window->RemoveObserver(this);
+ WindowToNodeIdMap::iterator it = window_to_node_id_map_.find(window);
+ DCHECK(it != window_to_node_id_map_.end());
+
+ int node_id = it->second;
+ int parent_id = old_parent ? window_to_node_id_map_[old_parent] : 0;
+
+ window_to_node_id_map_.erase(it);
+ frontend()->childNodeRemoved(parent_id, node_id);
}
-ui::devtools::protocol::Response AshDevToolsDOMAgent::getDocument(
- std::unique_ptr<ui::devtools::protocol::DOM::Node>* out_root) {
- *out_root = BuildInitialTree();
- return ui::devtools::protocol::Response::OK();
+void AshDevToolsDOMAgent::RemoveObserverFromAllWindows() {
+ for (auto& pair : window_to_node_id_map_)
+ pair.first->RemoveObserver(this);
+}
+
+void AshDevToolsDOMAgent::Reset() {
+ RemoveObserverFromAllWindows();
+ window_to_node_id_map_.clear();
+ node_ids = 1;
}
} // namespace devtools
« 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