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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/common/CSSShadowModel.js

Issue 2259433005: DevTools: Add CSSShadowModel and CSSLength (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months 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
(Empty)
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
5 /**
6 * @constructor
7 * @param {boolean} inset
8 * @param {!WebInspector.CSSLength} offsetX
9 * @param {!WebInspector.CSSLength} offsetY
10 * @param {!WebInspector.CSSLength} blurRadius
11 * @param {!WebInspector.CSSLength} spreadRadius
12 * @param {!WebInspector.Color} color
13 */
14 WebInspector.CSSShadowModel = function(inset, offsetX, offsetY, blurRadius, spre adRadius, color)
15 {
16 this._inset = inset;
17 this._offsetX = offsetX;
18 this._offsetY = offsetY;
19 this._blurRadius = blurRadius;
20 this._spreadRadius = spreadRadius;
21 this._color = color;
22 this._format = "XYB";
23 }
24
25 /**
26 * @enum {string}
27 */
28 WebInspector.CSSShadowModel.FormatParts = {
29 Inset: "I",
30 OffsetX: "X",
31 OffsetY: "Y",
32 BlurRadius: "B",
33 SpreadRadius: "S",
34 Color: "C"
35 }
36
37 /**
38 * @param {string} text
39 * @return {!Array<!WebInspector.CSSShadowModel>}
40 */
41 WebInspector.CSSShadowModel.parseTextShadow = function(text)
42 {
43 return WebInspector.CSSShadowModel._parseShadow(text, false);
44 }
45
46 /**
47 * @param {string} text
48 * @return {!Array<!WebInspector.CSSShadowModel>}
49 */
50 WebInspector.CSSShadowModel.parseBoxShadow = function(text)
51 {
52 return WebInspector.CSSShadowModel._parseShadow(text, true);
53 }
54
55 WebInspector.CSSShadowModel.prototype = {
56 /**
57 * @param {boolean} inset
58 */
59 setInset: function(inset)
60 {
61 this._inset = inset;
62 },
63
64 /**
65 * @param {!WebInspector.CSSLength} offsetX
66 * @param {!WebInspector.CSSLength} offsetY
67 */
68 setOffset: function(offsetX, offsetY)
69 {
70 this._offsetX = offsetX;
71 this._offsetY = offsetY;
72 },
73
74 /**
75 * @param {!WebInspector.CSSLength} blurRadius
76 */
77 setBlurRadius: function(blurRadius)
78 {
79 this._blurRadius = blurRadius;
80 },
81
82 /**
83 * @param {!WebInspector.CSSLength} spreadRadius
84 */
85 setSpreadRadius: function(spreadRadius)
86 {
87 this._spreadRadius = spreadRadius;
dgozman 2016/08/22 16:56:41 Don't you want to add "S" to format here?
flandy 2016/08/22 19:42:20 Yes, if it is not included in the format already,
88 },
89
90 /**
91 * @param {!WebInspector.Color} color
92 */
93 setColor: function(color)
94 {
95 this._color = color;
96 },
97
98 /**
99 * @param {string} format
100 */
101 setFormat: function(format)
102 {
103 this._format = format;
dgozman 2016/08/22 16:56:41 Do we intend to switch between formats?
flandy 2016/08/22 19:42:20 No. Removed
104 },
105
106 /**
107 * @return {!WebInspector.CSSLength}
108 */
109 offsetX: function()
110 {
111 return this._offsetX;
112 },
113
114 /**
115 * @return {!WebInspector.CSSLength}
116 */
117 offsetY: function()
118 {
119 return this._offsetY;
120 },
121
122 /**
123 * @return {string}
124 */
125 asCSSText: function()
126 {
127 var parts = [];
128 for (var i = 0; i < this._format.length; i++) {
129 var part = this._format.charAt(i);
130 if (part === WebInspector.CSSShadowModel.FormatParts.Inset && this._ inset)
131 parts.push("inset");
132 else if (part === WebInspector.CSSShadowModel.FormatParts.OffsetX)
133 parts.push(this._offsetX.asCSSText());
134 else if (part === WebInspector.CSSShadowModel.FormatParts.OffsetY)
135 parts.push(this._offsetY.asCSSText());
136 else if (part === WebInspector.CSSShadowModel.FormatParts.BlurRadius )
137 parts.push(this._blurRadius.asCSSText());
138 else if (part === WebInspector.CSSShadowModel.FormatParts.SpreadRadi us)
139 parts.push(this._spreadRadius.asCSSText());
140 else if (part === WebInspector.CSSShadowModel.FormatParts.Color)
141 parts.push(this._color.asString(this._color.format()));
142 }
143 return parts.join(" ");
144 }
145 }
146
147 /**
148 * @param {string} text
149 * @param {boolean} isBoxShadow
150 * @return {!Array<!WebInspector.CSSShadowModel>}
151 */
152 WebInspector.CSSShadowModel._parseShadow = function(text, isBoxShadow)
153 {
154 var shadowTexts = [];
155 // Split by commas that aren't inside of color values to get the individual shadow values.
156 var splits = WebInspector.TextUtils.splitStringByRegexes(text, [WebInspector .Color.Regex, /,/g]);
157 var currentIndex = 0;
158 for (var i = 0; i < splits.length; i++) {
159 if (splits[i].regexIndex === 1) {
160 var comma = splits[i];
161 shadowTexts.push(text.substring(currentIndex, comma.position));
162 currentIndex = comma.position + 1;
163 }
164 }
165 shadowTexts.push(text.substring(currentIndex, text.length));
166
167 var shadows = [];
168 for (var i = 0; i < shadowTexts.length; i++) {
169 var shadow = new WebInspector.CSSShadowModel(false, WebInspector.CSSLeng th.zero(), WebInspector.CSSLength.zero(),
dgozman 2016/08/22 16:56:41 If you never create with meaningful parameters, ju
flandy 2016/08/22 19:42:20 Done.
170 WebInspector.CSSLength.zero(), WebInspector.CSSLength.zero(), /** @t ype {!WebInspector.Color} */ (WebInspector.Color.parse("black")));
171 var format = "";
172 var nextPartAllowed = true;
173 var regexes = [/inset/gi, WebInspector.Color.Regex, WebInspector.CSSLeng th.regex()];
174 var results = WebInspector.TextUtils.splitStringByRegexes(shadowTexts[i] , regexes);
175 for (var j = 0; j < results.length; j++) {
176 var result = results[j];
177 if (result.regexIndex === -1) {
178 // Don't allow anything other than inset, color, length values, and whitespace.
179 if (/\S/.test(result.value))
180 return [];
181 // All parts must be separated by whitespace.
182 nextPartAllowed = true;
183 } else {
184 if (!nextPartAllowed)
185 return [];
186 nextPartAllowed = false;
187
188 if (result.regexIndex === 0) {
189 shadow.setInset(true);
190 format += WebInspector.CSSShadowModel.FormatParts.Inset;
191 } else if (result.regexIndex === 1) {
192 var color = WebInspector.Color.parse(result.value);
193 if (!color)
194 return [];
195 shadow.setColor(color);
196 format += WebInspector.CSSShadowModel.FormatParts.Color;
197 } else if (result.regexIndex === 2) {
198 var length = WebInspector.CSSLength.parse(result.value);
199 if (!length)
200 return [];
201 var previousPart = format.length > 0 ? format.charAt(format. length - 1) : "";
202 if (previousPart === WebInspector.CSSShadowModel.FormatParts .OffsetX) {
203 shadow.setOffset(shadow.offsetX(), length);
dgozman 2016/08/22 16:56:41 Use fields, not setters.
flandy 2016/08/22 19:42:20 Done.
204 format += WebInspector.CSSShadowModel.FormatParts.Offset Y;
205 } else if (previousPart === WebInspector.CSSShadowModel.Form atParts.OffsetY) {
206 shadow.setBlurRadius(length);
207 format += WebInspector.CSSShadowModel.FormatParts.BlurRa dius;
208 } else if (previousPart === WebInspector.CSSShadowModel.Form atParts.BlurRadius) {
209 shadow.setSpreadRadius(length);
210 format += WebInspector.CSSShadowModel.FormatParts.Spread Radius;
211 } else {
212 shadow.setOffset(length, shadow.offsetY());
213 format += WebInspector.CSSShadowModel.FormatParts.Offset X;
214 }
215 }
216 }
217 }
218 if (invalidCount(WebInspector.CSSShadowModel.FormatParts.OffsetX, 1, 1)
219 || invalidCount(WebInspector.CSSShadowModel.FormatParts.OffsetY, 1, 1)
220 || invalidCount(WebInspector.CSSShadowModel.FormatParts.Color, 0 , 1)
221 || invalidCount(WebInspector.CSSShadowModel.FormatParts.BlurRadi us, 0, 1)
222 || invalidCount(WebInspector.CSSShadowModel.FormatParts.Inset, 0 , isBoxShadow ? 1 : 0)
223 || invalidCount(WebInspector.CSSShadowModel.FormatParts.SpreadRa dius, 0, isBoxShadow ? 1 : 0))
224 return [];
225 shadow.setFormat(format);
dgozman 2016/08/22 16:56:41 We can set fields here directly, and not expose se
flandy 2016/08/22 19:42:20 Setters will still be used by the Shadow Editor to
226 shadows.push(shadow);
227 }
228 return shadows;
229
230 /**
231 * @param {string} character
232 * @param {number} min
233 * @param {number} max
234 * @return {boolean}
235 */
236 function invalidCount(character, min, max)
237 {
238 var count = 0;
239 for (var i = 0; i < format.length; i++) {
240 if (format.charAt(i) === character)
241 count++;
242 }
243 return count < min || count > max;
244 }
245 }
246
247 /**
248 * @constructor
249 * @param {number} amount
250 * @param {!WebInspector.CSSLengthUnit} unit
251 */
252 WebInspector.CSSLength = function(amount, unit)
253 {
254 this.amount = amount;
255 this.unit = unit;
256 }
257
258 /** @type {!RegExp} */
259 WebInspector.CSSNumberRegex = /[+-]?(?:[0-9]*[.])?[0-9]+/;
260 /** @type {!RegExp} */
261 WebInspector.CSSZeroRegex = /[+-]?(?:0*[.])?0+/;
262 /** @type {!RegExp} */
263 WebInspector.CSSExponentRegex = /(?:[eE][+-]?[0-9]+)?/;
264
265 /**
266 * @return {!RegExp}
267 */
268 WebInspector.CSSLength.regex = function()
269 {
270 var number = WebInspector.CSSNumberRegex.source + WebInspector.CSSExponentR egex.source;
271 var unit = WebInspector.CSSLengthUnit.regex().source;
272 var zero = WebInspector.CSSZeroRegex.source + WebInspector.CSSExponentRegex. source;
273 return new RegExp("(" + number + ")(" + unit + ")|" + zero, "gi");
dgozman 2016/08/22 16:56:41 All this regexp magic is hard to understand. Can w
flandy 2016/08/22 19:42:21 I've now inlined the regexes.
274 }
275
276 /**
277 * @enum {string}
278 */
279 WebInspector.CSSLengthUnit = {
280 Ch: "ch",
281 Cm: "cm",
282 Em: "em",
283 Ex: "ex",
284 In: "in",
285 Mm: "mm",
286 Pc: "pc",
287 Pt: "pt",
288 Px: "px",
289 Rem: "rem",
290 Vh: "vh",
291 Vmax: "vmax",
292 Vmin: "vmin",
293 Vw: "vw",
294 None: ""
295 }
296
297 /**
298 * @return {!RegExp}
299 */
300 WebInspector.CSSLengthUnit.regex = function()
301 {
302 var units = [];
303 var keys = Object.keys(WebInspector.CSSLengthUnit);
304 for (var i = 0; i < keys.length; i++) {
305 var unit = WebInspector.CSSLengthUnit[keys[i]];
306 if (unit && typeof unit === "string")
dgozman 2016/08/22 16:56:41 How could it be not string?
flandy 2016/08/22 19:42:20 Removed.
307 units.push(unit);
308 }
309 return new RegExp(units.join("|"), "i");
dgozman 2016/08/22 16:56:41 Let's cache this one.
flandy 2016/08/22 19:42:20 Removed.
310 }
311
312 /**
313 * @param {string} text
314 * @return {?WebInspector.CSSLength}
315 */
316 WebInspector.CSSLength.parse = function(text)
317 {
318 var lengthRegex = new RegExp("^(?:" + WebInspector.CSSLength.regex().source + ")$", "i");
dgozman 2016/08/22 16:56:41 Let's cache this one as well. Why don't we inline
flandy 2016/08/22 19:42:20 I use WI.CSSLength.Regex in the parse function as
319 var match = text.match(lengthRegex) || [];
320 if (match.length > 2 && match[2])
321 return new WebInspector.CSSLength(parseFloat(match[1]), match[2]);
322 else if (match.length > 0)
323 return WebInspector.CSSLength.zero();
324 return null;
325 }
326
327 /**
328 * @return {!WebInspector.CSSLength}
329 */
330 WebInspector.CSSLength.zero = function()
331 {
332 return new WebInspector.CSSLength(0, WebInspector.CSSLengthUnit.None);
333 }
334
335 WebInspector.CSSLength.prototype = {
336 /**
337 * @return {string}
338 */
339 asCSSText: function()
340 {
341 return this.amount + this.unit;
342 }
343 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698