dom_agent_views.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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
  3. // found in the LICENSE file.
  4. #include "components/ui_devtools/views/dom_agent_views.h"
  5. #include <memory>
  6. #include <utility>
  7. #include <vector>
  8. #include "components/ui_devtools/devtools_server.h"
  9. #include "components/ui_devtools/root_element.h"
  10. #include "components/ui_devtools/ui_element.h"
  11. #include "components/ui_devtools/views/view_element.h"
  12. #include "components/ui_devtools/views/widget_element.h"
  13. #include "ui/views/view.h"
  14. #include "ui/views/widget/widget.h"
  15. namespace ui_devtools {
  16. namespace {
  17. using ui_devtools::protocol::Array;
  18. using ui_devtools::protocol::DOM::Node;
  19. } // namespace
  20. DOMAgentViews::DOMAgentViews() {}
  21. DOMAgentViews::~DOMAgentViews() {}
  22. std::unique_ptr<Node> DOMAgentViews::BuildTreeForUIElement(
  23. UIElement* ui_element) {
  24. if (ui_element->type() == UIElementType::WINDOW) {
  25. return BuildTreeForWindow(ui_element);
  26. } else if (ui_element->type() == UIElementType::WIDGET) {
  27. return BuildTreeForRootWidget(ui_element);
  28. } else if (ui_element->type() == UIElementType::VIEW) {
  29. return BuildTreeForView(ui_element);
  30. }
  31. return nullptr;
  32. }
  33. std::unique_ptr<Node> DOMAgentViews::BuildTreeForRootWidget(
  34. UIElement* widget_element) {
  35. DCHECK(widget_element->type() == UIElementType::WIDGET);
  36. views::Widget* widget =
  37. UIElement::GetBackingElement<views::Widget, WidgetElement>(
  38. widget_element);
  39. auto children = std::make_unique<protocol::Array<Node>>();
  40. ViewElement* view_element =
  41. new ViewElement(widget->GetRootView(), this, widget_element);
  42. children->emplace_back(BuildTreeForView(view_element));
  43. widget_element->AddChild(view_element);
  44. std::unique_ptr<Node> node =
  45. BuildNode("Widget",
  46. std::make_unique<std::vector<std::string>>(
  47. widget_element->GetAttributes()),
  48. std::move(children), widget_element->node_id());
  49. return node;
  50. }
  51. std::unique_ptr<Node> DOMAgentViews::BuildTreeForView(UIElement* view_element) {
  52. DCHECK(view_element->type() == UIElementType::VIEW);
  53. views::View* view =
  54. UIElement::GetBackingElement<views::View, ViewElement>(view_element);
  55. auto children = std::make_unique<protocol::Array<Node>>();
  56. for (auto* child : view->GetChildrenInZOrder()) {
  57. // When building the subtree, a particular view could be visited multiple
  58. // times because for each view of the subtree, we would call
  59. // BuildTreeForView(..) on that view which causes the subtree with that view
  60. // as root being visited again. Here we check if we already constructed the
  61. // ViewElement and skip true.
  62. UIElement* view_element_child = nullptr;
  63. auto id =
  64. view_element->FindUIElementIdForBackendElement<views::View>(child);
  65. if (id > 0) {
  66. view_element_child = GetElementFromNodeId(id);
  67. } else {
  68. view_element_child = new ViewElement(child, this, view_element);
  69. view_element->AddChild(view_element_child);
  70. }
  71. children->emplace_back(BuildTreeForView(view_element_child));
  72. }
  73. return BuildNode(
  74. "View",
  75. std::make_unique<std::vector<std::string>>(view_element->GetAttributes()),
  76. std::move(children), view_element->node_id());
  77. }
  78. } // namespace ui_devtools