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

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

Issue 2548103002: Make bounds editable through the CSS sidepanel (Closed)
Patch Set: Make bounds editable through the CSS sidepanel Created 4 years 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_css_agent.h" 5 #include "ash/common/devtools/ash_devtools_css_agent.h"
6 6
7 #include "ash/common/wm_lookup.h"
7 #include "ash/common/wm_window.h" 8 #include "ash/common/wm_window.h"
9 #include "base/strings/string_split.h"
10 #include "base/strings/string_util.h"
11 #include "ui/display/display.h"
8 12
9 namespace ash { 13 namespace ash {
10 namespace devtools { 14 namespace devtools {
11 15
12 namespace { 16 namespace {
13 using namespace ui::devtools::protocol; 17 using namespace ui::devtools::protocol;
14 18
19 const char kHeight[] = "height";
20 const char kWidth[] = "width";
21 const char kX[] = "x";
22 const char kY[] = "y";
23
24 std::unique_ptr<CSS::SourceRange> BuildDefaultSourceRange() {
25 return CSS::SourceRange::create()
26 .setStartLine(0)
27 .setEndLine(0)
28 .setStartColumn(0)
29 .setEndColumn(0)
sadrul 2016/12/06 20:56:30 What do these mean?
Sarmad Hashmi 2016/12/07 01:23:27 Added comment.
30 .build();
31 }
32
15 std::unique_ptr<CSS::CSSProperty> BuildCSSProperty(const std::string& name, 33 std::unique_ptr<CSS::CSSProperty> BuildCSSProperty(const std::string& name,
16 int value) { 34 int value) {
17 return CSS::CSSProperty::create() 35 return CSS::CSSProperty::create()
36 .setRange(BuildDefaultSourceRange())
18 .setName(name) 37 .setName(name)
19 .setValue(base::IntToString(value)) 38 .setValue(base::IntToString(value))
20 .build(); 39 .build();
21 } 40 }
22 41
23 std::unique_ptr<Array<CSS::CSSProperty>> BuildBoundsCSSPropertyArray( 42 std::unique_ptr<Array<CSS::CSSProperty>> BuildBoundsCSSPropertyArray(
24 const gfx::Rect& bounds) { 43 const gfx::Rect& bounds) {
25 auto cssProperties = Array<CSS::CSSProperty>::create(); 44 auto cssProperties = Array<CSS::CSSProperty>::create();
26 cssProperties->addItem(BuildCSSProperty("height", bounds.height())); 45 cssProperties->addItem(BuildCSSProperty(kHeight, bounds.height()));
27 cssProperties->addItem(BuildCSSProperty("width", bounds.width())); 46 cssProperties->addItem(BuildCSSProperty(kWidth, bounds.width()));
28 cssProperties->addItem(BuildCSSProperty("x", bounds.x())); 47 cssProperties->addItem(BuildCSSProperty(kX, bounds.x()));
29 cssProperties->addItem(BuildCSSProperty("y", bounds.y())); 48 cssProperties->addItem(BuildCSSProperty(kY, bounds.y()));
30 return cssProperties; 49 return cssProperties;
31 } 50 }
32 51
33 std::unique_ptr<CSS::CSSStyle> BuildCSSStyle(int node_id, 52 std::unique_ptr<CSS::CSSStyle> BuildCSSStyle(int node_id,
34 const gfx::Rect& bounds) { 53 const gfx::Rect& bounds) {
35 return CSS::CSSStyle::create() 54 return CSS::CSSStyle::create()
55 .setRange(BuildDefaultSourceRange())
56 .setStyleSheetId(base::IntToString(node_id))
36 .setCssProperties(BuildBoundsCSSPropertyArray(bounds)) 57 .setCssProperties(BuildBoundsCSSPropertyArray(bounds))
37 .setShorthandEntries(Array<std::string>::create()) 58 .setShorthandEntries(Array<std::string>::create())
38 .build(); 59 .build();
39 } 60 }
40 61
62 Response ParseBounds(const std::string& style_text, gfx::Rect& bounds) {
63 std::vector<std::string> tokens = base::SplitString(
64 style_text, ":;", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
65 for (size_t i = 0; i < tokens.size() - 1; i += 2) {
66 std::string property = tokens.at(i);
sadrul 2016/12/06 20:56:30 Use const & to avoid extra string copy
Sarmad Hashmi 2016/12/07 01:23:27 Done.
67 int value;
68 if (!base::StringToInt(tokens.at(i + 1), &value))
69 return Response::Error("Unable to parse value for property=" + property);
70
71 if (property == kHeight) {
72 bounds.set_height(value);
73 } else if (property == kWidth) {
74 bounds.set_width(value);
75 } else if (property == kX)
76 bounds.set_x(value);
77 else if (property == kY)
sadrul 2016/12/06 20:56:30 Use {} for all, or none.
Sarmad Hashmi 2016/12/07 01:23:27 Removed {}
78 bounds.set_y(value);
79 else
80 return Response::Error("Unsupported property=" + property);
81 }
82 return Response::OK();
83 }
84
41 } // namespace 85 } // namespace
42 86
43 AshDevToolsCSSAgent::AshDevToolsCSSAgent(AshDevToolsDOMAgent* dom_agent) 87 AshDevToolsCSSAgent::AshDevToolsCSSAgent(
44 : dom_agent_(dom_agent) { 88 AshDevToolsDOMAgent* dom_agent,
89 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
90 : main_thread_task_runner_(main_thread_task_runner), dom_agent_(dom_agent) {
45 DCHECK(dom_agent_); 91 DCHECK(dom_agent_);
92 DCHECK(main_thread_task_runner_);
46 } 93 }
47 94
48 AshDevToolsCSSAgent::~AshDevToolsCSSAgent() { 95 AshDevToolsCSSAgent::~AshDevToolsCSSAgent() {
49 disable(); 96 disable();
50 } 97 }
51 98
52 ui::devtools::protocol::Response AshDevToolsCSSAgent::enable() { 99 ui::devtools::protocol::Response AshDevToolsCSSAgent::enable() {
53 dom_agent_->AddObserver(this); 100 dom_agent_->AddObserver(this);
54 return ui::devtools::protocol::Response::OK(); 101 return ui::devtools::protocol::Response::OK();
55 } 102 }
56 103
57 ui::devtools::protocol::Response AshDevToolsCSSAgent::disable() { 104 ui::devtools::protocol::Response AshDevToolsCSSAgent::disable() {
58 dom_agent_->RemoveObserver(this); 105 dom_agent_->RemoveObserver(this);
59 return ui::devtools::protocol::Response::OK(); 106 return ui::devtools::protocol::Response::OK();
60 } 107 }
61 108
62 ui::devtools::protocol::Response AshDevToolsCSSAgent::getMatchedStylesForNode( 109 ui::devtools::protocol::Response AshDevToolsCSSAgent::getMatchedStylesForNode(
63 int node_id, 110 int node_id,
64 ui::devtools::protocol::Maybe<ui::devtools::protocol::CSS::CSSStyle>* 111 ui::devtools::protocol::Maybe<ui::devtools::protocol::CSS::CSSStyle>*
65 inline_style) { 112 inline_style) {
66 *inline_style = GetStylesForNode(node_id); 113 *inline_style = GetStylesForNode(node_id);
67 if (!inline_style) { 114 if (!inline_style) {
68 return ui::devtools::protocol::Response::Error( 115 return ui::devtools::protocol::Response::Error(
69 "Node with that id not found"); 116 "Node with that id not found");
70 } 117 }
71 return ui::devtools::protocol::Response::OK(); 118 return ui::devtools::protocol::Response::OK();
72 } 119 }
73 120
121 ui::devtools::protocol::Response AshDevToolsCSSAgent::setStyleTexts(
122 std::unique_ptr<ui::devtools::protocol::Array<
123 ui::devtools::protocol::CSS::StyleDeclarationEdit>> edits,
124 std::unique_ptr<
125 ui::devtools::protocol::Array<ui::devtools::protocol::CSS::CSSStyle>>*
126 result) {
127 std::unique_ptr<
128 ui::devtools::protocol::Array<ui::devtools::protocol::CSS::CSSStyle>>
129 updated_styles = ui::devtools::protocol::Array<
130 ui::devtools::protocol::CSS::CSSStyle>::create();
131 for (size_t i = 0; i < edits->length(); i++) {
132 auto edit = edits->get(i);
sadrul 2016/12/06 20:56:30 auto&?
Sarmad Hashmi 2016/12/07 01:23:27 Done.
133 int node_id;
134 if (!base::StringToInt(edit->getStyleSheetId(), &node_id))
135 return ui::devtools::protocol::Response::Error("Invalid node id");
136
137 gfx::Rect updated_bounds;
138 if (!GetBoundsForNodeId(node_id, updated_bounds)) {
139 return ui::devtools::protocol::Response::Error(
140 "No node found with that id");
141 }
142
143 ui::devtools::protocol::Response response(
144 ParseBounds(edit->getText(), updated_bounds));
145 if (!response.isSuccess())
146 return response;
147
148 updated_styles->addItem(BuildCSSStyle(node_id, updated_bounds));
149 main_thread_task_runner_->PostTask(
150 FROM_HERE, base::Bind(&AshDevToolsCSSAgent::UpdateBounds,
151 base::Unretained(this), node_id, updated_bounds));
sadrul 2016/12/06 20:56:30 Why post-task?
Sarmad Hashmi 2016/12/07 01:23:27 As discussed, removed.
152 }
153
154 *result = std::move(updated_styles);
155 return ui::devtools::protocol::Response::OK();
156 }
157
74 void AshDevToolsCSSAgent::OnWindowBoundsChanged(WmWindow* window) { 158 void AshDevToolsCSSAgent::OnWindowBoundsChanged(WmWindow* window) {
75 InvalidateStyleSheet(dom_agent_->GetNodeIdFromWindow(window)); 159 InvalidateStyleSheet(dom_agent_->GetNodeIdFromWindow(window));
76 } 160 }
77 161
78 void AshDevToolsCSSAgent::OnWidgetBoundsChanged(views::Widget* widget) { 162 void AshDevToolsCSSAgent::OnWidgetBoundsChanged(views::Widget* widget) {
79 InvalidateStyleSheet(dom_agent_->GetNodeIdFromWidget(widget)); 163 InvalidateStyleSheet(dom_agent_->GetNodeIdFromWidget(widget));
80 } 164 }
81 165
82 void AshDevToolsCSSAgent::OnViewBoundsChanged(views::View* view) { 166 void AshDevToolsCSSAgent::OnViewBoundsChanged(views::View* view) {
83 InvalidateStyleSheet(dom_agent_->GetNodeIdFromView(view)); 167 InvalidateStyleSheet(dom_agent_->GetNodeIdFromView(view));
84 } 168 }
85 169
86 std::unique_ptr<ui::devtools::protocol::CSS::CSSStyle> 170 std::unique_ptr<ui::devtools::protocol::CSS::CSSStyle>
87 AshDevToolsCSSAgent::GetStylesForNode(int node_id) { 171 AshDevToolsCSSAgent::GetStylesForNode(int node_id) {
88 WmWindow* window = dom_agent_->GetWindowFromNodeId(node_id); 172 gfx::Rect bounds;
89 if (window) 173 return GetBoundsForNodeId(node_id, bounds) ? BuildCSSStyle(node_id, bounds)
90 return BuildCSSStyle(node_id, window->GetBounds()); 174 : nullptr;
91
92 views::Widget* widget = dom_agent_->GetWidgetFromNodeId(node_id);
93 if (widget)
94 return BuildCSSStyle(node_id, widget->GetWindowBoundsInScreen());
95
96 views::View* view = dom_agent_->GetViewFromNodeId(node_id);
97 if (view)
98 return BuildCSSStyle(node_id, view->bounds());
99
100 return nullptr;
101 } 175 }
102 176
103 void AshDevToolsCSSAgent::InvalidateStyleSheet(int node_id) { 177 void AshDevToolsCSSAgent::InvalidateStyleSheet(int node_id) {
104 // The stylesheetId for each node is equivalent to its node_id (as a string). 178 // The stylesheetId for each node is equivalent to its node_id (as a string).
105 frontend()->styleSheetChanged(base::IntToString(node_id)); 179 frontend()->styleSheetChanged(base::IntToString(node_id));
106 } 180 }
107 181
182 bool AshDevToolsCSSAgent::GetBoundsForNodeId(int node_id, gfx::Rect& bounds) {
183 WmWindow* window = dom_agent_->GetWindowFromNodeId(node_id);
184 if (window) {
185 bounds = window->GetBounds();
186 return true;
187 }
188
189 views::Widget* widget = dom_agent_->GetWidgetFromNodeId(node_id);
190 if (widget) {
191 bounds = widget->GetRestoredBounds();
192 return true;
193 }
194
195 views::View* view = dom_agent_->GetViewFromNodeId(node_id);
196 if (view) {
197 bounds = view->bounds();
198 return true;
199 }
200
201 return false;
202 }
203
204 void AshDevToolsCSSAgent::UpdateBounds(int node_id, const gfx::Rect& bounds) {
205 WmWindow* window = dom_agent_->GetWindowFromNodeId(node_id);
206 if (window)
207 window->SetBounds(bounds);
sadrul 2016/12/06 20:56:30 return too from here, right?
Sarmad Hashmi 2016/12/07 01:23:27 Done.
208
209 views::Widget* widget = dom_agent_->GetWidgetFromNodeId(node_id);
210 if (widget)
211 widget->SetBounds(bounds);
sadrul 2016/12/06 20:56:30 ditto
Sarmad Hashmi 2016/12/07 01:23:27 Done.
212
213 views::View* view = dom_agent_->GetViewFromNodeId(node_id);
214 if (view)
215 view->SetBoundsRect(bounds);
216 }
217
108 } // namespace devtools 218 } // namespace devtools
109 } // namespace ash 219 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698