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

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

Issue 2548103002: Make bounds editable through the CSS sidepanel (Closed)
Patch Set: sadruls comments 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
« no previous file with comments | « ash/common/devtools/ash_devtools_css_agent.h ('k') | components/ui_devtools/protocol.json » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
8 11
9 namespace ash { 12 namespace ash {
10 namespace devtools { 13 namespace devtools {
11 14
12 namespace { 15 namespace {
13 using namespace ui::devtools::protocol; 16 using namespace ui::devtools::protocol;
14 17
18 const char kHeight[] = "height";
19 const char kWidth[] = "width";
20 const char kX[] = "x";
21 const char kY[] = "y";
22
23 std::unique_ptr<CSS::SourceRange> BuildDefaultSourceRange() {
24 // These tell the frontend where in the stylesheet a certain style
25 // is located. Since we don't have stylesheets, this is all 0.
26 // We need this because CSS fields are not editable unless
27 // the range is provided.
28 return CSS::SourceRange::create()
29 .setStartLine(0)
30 .setEndLine(0)
31 .setStartColumn(0)
32 .setEndColumn(0)
33 .build();
34 }
35
15 std::unique_ptr<CSS::CSSProperty> BuildCSSProperty(const std::string& name, 36 std::unique_ptr<CSS::CSSProperty> BuildCSSProperty(const std::string& name,
16 int value) { 37 int value) {
17 return CSS::CSSProperty::create() 38 return CSS::CSSProperty::create()
39 .setRange(BuildDefaultSourceRange())
18 .setName(name) 40 .setName(name)
19 .setValue(base::IntToString(value)) 41 .setValue(base::IntToString(value))
20 .build(); 42 .build();
21 } 43 }
22 44
23 std::unique_ptr<Array<CSS::CSSProperty>> BuildBoundsCSSPropertyArray( 45 std::unique_ptr<Array<CSS::CSSProperty>> BuildBoundsCSSPropertyArray(
24 const gfx::Rect& bounds) { 46 const gfx::Rect& bounds) {
25 auto cssProperties = Array<CSS::CSSProperty>::create(); 47 auto cssProperties = Array<CSS::CSSProperty>::create();
26 cssProperties->addItem(BuildCSSProperty("height", bounds.height())); 48 cssProperties->addItem(BuildCSSProperty(kHeight, bounds.height()));
27 cssProperties->addItem(BuildCSSProperty("width", bounds.width())); 49 cssProperties->addItem(BuildCSSProperty(kWidth, bounds.width()));
28 cssProperties->addItem(BuildCSSProperty("x", bounds.x())); 50 cssProperties->addItem(BuildCSSProperty(kX, bounds.x()));
29 cssProperties->addItem(BuildCSSProperty("y", bounds.y())); 51 cssProperties->addItem(BuildCSSProperty(kY, bounds.y()));
30 return cssProperties; 52 return cssProperties;
31 } 53 }
32 54
33 std::unique_ptr<CSS::CSSStyle> BuildCSSStyle(int node_id, 55 std::unique_ptr<CSS::CSSStyle> BuildCSSStyle(int node_id,
34 const gfx::Rect& bounds) { 56 const gfx::Rect& bounds) {
35 return CSS::CSSStyle::create() 57 return CSS::CSSStyle::create()
58 .setRange(BuildDefaultSourceRange())
59 .setStyleSheetId(base::IntToString(node_id))
36 .setCssProperties(BuildBoundsCSSPropertyArray(bounds)) 60 .setCssProperties(BuildBoundsCSSPropertyArray(bounds))
37 .setShorthandEntries(Array<std::string>::create()) 61 .setShorthandEntries(Array<std::string>::create())
38 .build(); 62 .build();
39 } 63 }
40 64
65 Response ParseBounds(const std::string& style_text, gfx::Rect& bounds) {
66 std::vector<std::string> tokens = base::SplitString(
67 style_text, ":;", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
68 for (size_t i = 0; i < tokens.size() - 1; i += 2) {
69 const std::string& property = tokens.at(i);
70 int value;
71 if (!base::StringToInt(tokens.at(i + 1), &value))
72 return Response::Error("Unable to parse value for property=" + property);
73
74 if (property == kHeight)
75 bounds.set_height(std::max(0, value));
76 else if (property == kWidth)
77 bounds.set_width(std::max(0, value));
78 else if (property == kX)
79 bounds.set_x(value);
80 else if (property == kY)
81 bounds.set_y(value);
82 else
83 return Response::Error("Unsupported property=" + property);
84 }
85 return Response::OK();
86 }
87
41 } // namespace 88 } // namespace
42 89
43 AshDevToolsCSSAgent::AshDevToolsCSSAgent(AshDevToolsDOMAgent* dom_agent) 90 AshDevToolsCSSAgent::AshDevToolsCSSAgent(AshDevToolsDOMAgent* dom_agent)
44 : dom_agent_(dom_agent) { 91 : dom_agent_(dom_agent) {
45 DCHECK(dom_agent_); 92 DCHECK(dom_agent_);
46 } 93 }
47 94
48 AshDevToolsCSSAgent::~AshDevToolsCSSAgent() { 95 AshDevToolsCSSAgent::~AshDevToolsCSSAgent() {
49 disable(); 96 disable();
50 } 97 }
(...skipping 13 matching lines...) Expand all
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 const auto& edit = edits->get(i);
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 if (!UpdateBounds(node_id, updated_bounds)) {
150 return ui::devtools::protocol::Response::Error(
151 "No node found with that id");
152 }
153 }
154
155 *result = std::move(updated_styles);
156 return ui::devtools::protocol::Response::OK();
157 }
158
74 void AshDevToolsCSSAgent::OnWindowBoundsChanged(WmWindow* window) { 159 void AshDevToolsCSSAgent::OnWindowBoundsChanged(WmWindow* window) {
75 InvalidateStyleSheet(dom_agent_->GetNodeIdFromWindow(window)); 160 InvalidateStyleSheet(dom_agent_->GetNodeIdFromWindow(window));
76 } 161 }
77 162
78 void AshDevToolsCSSAgent::OnWidgetBoundsChanged(views::Widget* widget) { 163 void AshDevToolsCSSAgent::OnWidgetBoundsChanged(views::Widget* widget) {
79 InvalidateStyleSheet(dom_agent_->GetNodeIdFromWidget(widget)); 164 InvalidateStyleSheet(dom_agent_->GetNodeIdFromWidget(widget));
80 } 165 }
81 166
82 void AshDevToolsCSSAgent::OnViewBoundsChanged(views::View* view) { 167 void AshDevToolsCSSAgent::OnViewBoundsChanged(views::View* view) {
83 InvalidateStyleSheet(dom_agent_->GetNodeIdFromView(view)); 168 InvalidateStyleSheet(dom_agent_->GetNodeIdFromView(view));
84 } 169 }
85 170
86 std::unique_ptr<ui::devtools::protocol::CSS::CSSStyle> 171 std::unique_ptr<ui::devtools::protocol::CSS::CSSStyle>
87 AshDevToolsCSSAgent::GetStylesForNode(int node_id) { 172 AshDevToolsCSSAgent::GetStylesForNode(int node_id) {
88 WmWindow* window = dom_agent_->GetWindowFromNodeId(node_id); 173 gfx::Rect bounds;
89 if (window) 174 return GetBoundsForNodeId(node_id, &bounds) ? BuildCSSStyle(node_id, bounds)
90 return BuildCSSStyle(node_id, window->GetBounds()); 175 : 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 } 176 }
102 177
103 void AshDevToolsCSSAgent::InvalidateStyleSheet(int node_id) { 178 void AshDevToolsCSSAgent::InvalidateStyleSheet(int node_id) {
104 // The stylesheetId for each node is equivalent to its node_id (as a string). 179 // The stylesheetId for each node is equivalent to its node_id (as a string).
105 frontend()->styleSheetChanged(base::IntToString(node_id)); 180 frontend()->styleSheetChanged(base::IntToString(node_id));
106 } 181 }
107 182
183 bool AshDevToolsCSSAgent::GetBoundsForNodeId(int node_id, gfx::Rect* bounds) {
184 WmWindow* window = dom_agent_->GetWindowFromNodeId(node_id);
185 if (window) {
186 *bounds = window->GetBounds();
187 return true;
188 }
189
190 views::Widget* widget = dom_agent_->GetWidgetFromNodeId(node_id);
191 if (widget) {
192 *bounds = widget->GetRestoredBounds();
193 return true;
194 }
195
196 views::View* view = dom_agent_->GetViewFromNodeId(node_id);
197 if (view) {
198 *bounds = view->bounds();
199 return true;
200 }
201
202 return false;
203 }
204
205 bool AshDevToolsCSSAgent::UpdateBounds(int node_id, const gfx::Rect& bounds) {
206 WmWindow* window = dom_agent_->GetWindowFromNodeId(node_id);
207 if (window) {
208 window->SetBounds(bounds);
209 return true;
210 }
211
212 views::Widget* widget = dom_agent_->GetWidgetFromNodeId(node_id);
213 if (widget) {
214 widget->SetBounds(bounds);
215 return true;
216 }
217
218 views::View* view = dom_agent_->GetViewFromNodeId(node_id);
219 if (view) {
220 view->SetBoundsRect(bounds);
221 return true;
222 }
223
224 return false;
225 }
226
108 } // namespace devtools 227 } // namespace devtools
109 } // namespace ash 228 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/devtools/ash_devtools_css_agent.h ('k') | components/ui_devtools/protocol.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698