| OLD | NEW |
| (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 */ |
| 8 WebInspector.CSSShadowModel = function() |
| 9 { |
| 10 this._inset = false; |
| 11 this._offsetX = WebInspector.CSSLength.zero(); |
| 12 this._offsetY = WebInspector.CSSLength.zero(); |
| 13 this._blurRadius = WebInspector.CSSLength.zero(); |
| 14 this._spreadRadius = WebInspector.CSSLength.zero(); |
| 15 this._color = /** @type {!WebInspector.Color} */ (WebInspector.Color.parse("
black")); |
| 16 this._format = [WebInspector.CSSShadowModel._Part.OffsetX, WebInspector.CSSS
hadowModel._Part.OffsetY]; |
| 17 } |
| 18 |
| 19 /** |
| 20 * @enum {string} |
| 21 */ |
| 22 WebInspector.CSSShadowModel._Part = { |
| 23 Inset: "I", |
| 24 OffsetX: "X", |
| 25 OffsetY: "Y", |
| 26 BlurRadius: "B", |
| 27 SpreadRadius: "S", |
| 28 Color: "C" |
| 29 } |
| 30 |
| 31 /** |
| 32 * @param {string} text |
| 33 * @return {!Array<!WebInspector.CSSShadowModel>} |
| 34 */ |
| 35 WebInspector.CSSShadowModel.parseTextShadow = function(text) |
| 36 { |
| 37 return WebInspector.CSSShadowModel._parseShadow(text, false); |
| 38 } |
| 39 |
| 40 /** |
| 41 * @param {string} text |
| 42 * @return {!Array<!WebInspector.CSSShadowModel>} |
| 43 */ |
| 44 WebInspector.CSSShadowModel.parseBoxShadow = function(text) |
| 45 { |
| 46 return WebInspector.CSSShadowModel._parseShadow(text, true); |
| 47 } |
| 48 |
| 49 WebInspector.CSSShadowModel.prototype = { |
| 50 /** |
| 51 * @param {boolean} inset |
| 52 */ |
| 53 setInset: function(inset) |
| 54 { |
| 55 this._inset = inset; |
| 56 if (this._format.indexOf(WebInspector.CSSShadowModel._Part.Inset) === -1
) |
| 57 this._format.unshift(WebInspector.CSSShadowModel._Part.Inset); |
| 58 }, |
| 59 |
| 60 /** |
| 61 * @param {!WebInspector.CSSLength} offsetX |
| 62 * @param {!WebInspector.CSSLength} offsetY |
| 63 */ |
| 64 setOffset: function(offsetX, offsetY) |
| 65 { |
| 66 this._offsetX = offsetX; |
| 67 this._offsetY = offsetY; |
| 68 }, |
| 69 |
| 70 /** |
| 71 * @param {!WebInspector.CSSLength} blurRadius |
| 72 */ |
| 73 setBlurRadius: function(blurRadius) |
| 74 { |
| 75 this._blurRadius = blurRadius; |
| 76 if (this._format.indexOf(WebInspector.CSSShadowModel._Part.BlurRadius) =
== -1) { |
| 77 var yIndex = this._format.indexOf(WebInspector.CSSShadowModel._Part.
OffsetY); |
| 78 this._format.splice(yIndex + 1, 0, WebInspector.CSSShadowModel._Part
.BlurRadius); |
| 79 } |
| 80 }, |
| 81 |
| 82 /** |
| 83 * @param {!WebInspector.CSSLength} spreadRadius |
| 84 */ |
| 85 setSpreadRadius: function(spreadRadius) |
| 86 { |
| 87 this._spreadRadius = spreadRadius; |
| 88 if (this._format.indexOf(WebInspector.CSSShadowModel._Part.SpreadRadius)
=== -1) { |
| 89 this.setBlurRadius(this._blurRadius); |
| 90 var blurIndex = this._format.indexOf(WebInspector.CSSShadowModel._Pa
rt.BlurRadius); |
| 91 this._format.splice(blurIndex + 1, 0, WebInspector.CSSShadowModel._P
art.SpreadRadius); |
| 92 } |
| 93 }, |
| 94 |
| 95 /** |
| 96 * @param {!WebInspector.Color} color |
| 97 */ |
| 98 setColor: function(color) |
| 99 { |
| 100 this._color = color; |
| 101 if (this._format.indexOf(WebInspector.CSSShadowModel._Part.Color) === -1
) |
| 102 this._format.push(WebInspector.CSSShadowModel._Part.Color); |
| 103 }, |
| 104 |
| 105 /** |
| 106 * @return {boolean} |
| 107 */ |
| 108 inset: function() |
| 109 { |
| 110 return this._inset; |
| 111 }, |
| 112 |
| 113 /** |
| 114 * @return {!WebInspector.CSSLength} |
| 115 */ |
| 116 offsetX: function() |
| 117 { |
| 118 return this._offsetX; |
| 119 }, |
| 120 |
| 121 /** |
| 122 * @return {!WebInspector.CSSLength} |
| 123 */ |
| 124 offsetY: function() |
| 125 { |
| 126 return this._offsetY; |
| 127 }, |
| 128 |
| 129 /** |
| 130 * @return {!WebInspector.CSSLength} |
| 131 */ |
| 132 blurRadius: function() |
| 133 { |
| 134 return this._blurRadius; |
| 135 }, |
| 136 |
| 137 /** |
| 138 * @return {!WebInspector.CSSLength} |
| 139 */ |
| 140 spreadRadius: function() |
| 141 { |
| 142 return this._spreadRadius; |
| 143 }, |
| 144 |
| 145 /** |
| 146 * @return {!WebInspector.Color} |
| 147 */ |
| 148 color: function() |
| 149 { |
| 150 return this._color; |
| 151 }, |
| 152 |
| 153 /** |
| 154 * @return {string} |
| 155 */ |
| 156 asCSSText: function() |
| 157 { |
| 158 var parts = []; |
| 159 for (var i = 0; i < this._format.length; i++) { |
| 160 var part = this._format[i]; |
| 161 if (part === WebInspector.CSSShadowModel._Part.Inset && this._inset) |
| 162 parts.push("inset"); |
| 163 else if (part === WebInspector.CSSShadowModel._Part.OffsetX) |
| 164 parts.push(this._offsetX.asCSSText()); |
| 165 else if (part === WebInspector.CSSShadowModel._Part.OffsetY) |
| 166 parts.push(this._offsetY.asCSSText()); |
| 167 else if (part === WebInspector.CSSShadowModel._Part.BlurRadius) |
| 168 parts.push(this._blurRadius.asCSSText()); |
| 169 else if (part === WebInspector.CSSShadowModel._Part.SpreadRadius) |
| 170 parts.push(this._spreadRadius.asCSSText()); |
| 171 else if (part === WebInspector.CSSShadowModel._Part.Color) |
| 172 parts.push(this._color.asString(this._color.format())); |
| 173 } |
| 174 return parts.join(" "); |
| 175 } |
| 176 } |
| 177 |
| 178 /** |
| 179 * @param {string} text |
| 180 * @param {boolean} isBoxShadow |
| 181 * @return {!Array<!WebInspector.CSSShadowModel>} |
| 182 */ |
| 183 WebInspector.CSSShadowModel._parseShadow = function(text, isBoxShadow) |
| 184 { |
| 185 var shadowTexts = []; |
| 186 // Split by commas that aren't inside of color values to get the individual
shadow values. |
| 187 var splits = WebInspector.TextUtils.splitStringByRegexes(text, [WebInspector
.Color.Regex, /,/g]); |
| 188 var currentIndex = 0; |
| 189 for (var i = 0; i < splits.length; i++) { |
| 190 if (splits[i].regexIndex === 1) { |
| 191 var comma = splits[i]; |
| 192 shadowTexts.push(text.substring(currentIndex, comma.position)); |
| 193 currentIndex = comma.position + 1; |
| 194 } |
| 195 } |
| 196 shadowTexts.push(text.substring(currentIndex, text.length)); |
| 197 |
| 198 var shadows = []; |
| 199 for (var i = 0; i < shadowTexts.length; i++) { |
| 200 var shadow = new WebInspector.CSSShadowModel(); |
| 201 shadow._format = []; |
| 202 var nextPartAllowed = true; |
| 203 var regexes = [/inset/gi, WebInspector.Color.Regex, WebInspector.CSSLeng
th.Regex]; |
| 204 var results = WebInspector.TextUtils.splitStringByRegexes(shadowTexts[i]
, regexes); |
| 205 for (var j = 0; j < results.length; j++) { |
| 206 var result = results[j]; |
| 207 if (result.regexIndex === -1) { |
| 208 // Don't allow anything other than inset, color, length values,
and whitespace. |
| 209 if (/\S/.test(result.value)) |
| 210 return []; |
| 211 // All parts must be separated by whitespace. |
| 212 nextPartAllowed = true; |
| 213 } else { |
| 214 if (!nextPartAllowed) |
| 215 return []; |
| 216 nextPartAllowed = false; |
| 217 |
| 218 if (result.regexIndex === 0) { |
| 219 shadow._inset = true; |
| 220 shadow._format.push(WebInspector.CSSShadowModel._Part.Inset)
; |
| 221 } else if (result.regexIndex === 1) { |
| 222 var color = WebInspector.Color.parse(result.value); |
| 223 if (!color) |
| 224 return []; |
| 225 shadow._color = color; |
| 226 shadow._format.push(WebInspector.CSSShadowModel._Part.Color)
; |
| 227 } else if (result.regexIndex === 2) { |
| 228 var length = WebInspector.CSSLength.parse(result.value); |
| 229 if (!length) |
| 230 return []; |
| 231 var previousPart = shadow._format.length > 0 ? shadow._forma
t[shadow._format.length - 1] : ""; |
| 232 if (previousPart === WebInspector.CSSShadowModel._Part.Offse
tX) { |
| 233 shadow._offsetY = length; |
| 234 shadow._format.push(WebInspector.CSSShadowModel._Part.Of
fsetY); |
| 235 } else if (previousPart === WebInspector.CSSShadowModel._Par
t.OffsetY) { |
| 236 shadow._blurRadius = length; |
| 237 shadow._format.push(WebInspector.CSSShadowModel._Part.Bl
urRadius); |
| 238 } else if (previousPart === WebInspector.CSSShadowModel._Par
t.BlurRadius) { |
| 239 shadow._spreadRadius = length; |
| 240 shadow._format.push(WebInspector.CSSShadowModel._Part.Sp
readRadius); |
| 241 } else { |
| 242 shadow._offsetX = length; |
| 243 shadow._format.push(WebInspector.CSSShadowModel._Part.Of
fsetX); |
| 244 } |
| 245 } |
| 246 } |
| 247 } |
| 248 if (invalidCount(WebInspector.CSSShadowModel._Part.OffsetX, 1, 1) |
| 249 || invalidCount(WebInspector.CSSShadowModel._Part.OffsetY, 1, 1) |
| 250 || invalidCount(WebInspector.CSSShadowModel._Part.Color, 0, 1) |
| 251 || invalidCount(WebInspector.CSSShadowModel._Part.BlurRadius, 0,
1) |
| 252 || invalidCount(WebInspector.CSSShadowModel._Part.Inset, 0, isBo
xShadow ? 1 : 0) |
| 253 || invalidCount(WebInspector.CSSShadowModel._Part.SpreadRadius,
0, isBoxShadow ? 1 : 0)) |
| 254 return []; |
| 255 shadows.push(shadow); |
| 256 } |
| 257 return shadows; |
| 258 |
| 259 /** |
| 260 * @param {string} part |
| 261 * @param {number} min |
| 262 * @param {number} max |
| 263 * @return {boolean} |
| 264 */ |
| 265 function invalidCount(part, min, max) |
| 266 { |
| 267 var count = 0; |
| 268 for (var i = 0; i < shadow._format.length; i++) { |
| 269 if (shadow._format[i] === part) |
| 270 count++; |
| 271 } |
| 272 return count < min || count > max; |
| 273 } |
| 274 } |
| 275 |
| 276 /** |
| 277 * @constructor |
| 278 * @param {number} amount |
| 279 * @param {string} unit |
| 280 */ |
| 281 WebInspector.CSSLength = function(amount, unit) |
| 282 { |
| 283 this.amount = amount; |
| 284 this.unit = unit; |
| 285 } |
| 286 |
| 287 /** @type {!RegExp} */ |
| 288 WebInspector.CSSLength.Regex = (function() |
| 289 { |
| 290 var number = "([+-]?(?:[0-9]*[.])?[0-9]+(?:[eE][+-]?[0-9]+)?)"; |
| 291 var unit = "(ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmax|vmin|vw)"; |
| 292 var zero = "[+-]?(?:0*[.])?0+(?:[eE][+-]?[0-9]+)?"; |
| 293 return new RegExp(number + unit + "|" + zero, "gi"); |
| 294 })(); |
| 295 |
| 296 /** |
| 297 * @param {string} text |
| 298 * @return {?WebInspector.CSSLength} |
| 299 */ |
| 300 WebInspector.CSSLength.parse = function(text) |
| 301 { |
| 302 var lengthRegex = new RegExp("^(?:" + WebInspector.CSSLength.Regex.source +
")$", "i"); |
| 303 var match = text.match(lengthRegex); |
| 304 if (!match) |
| 305 return null; |
| 306 if (match.length > 2 && match[2]) |
| 307 return new WebInspector.CSSLength(parseFloat(match[1]), match[2]); |
| 308 return WebInspector.CSSLength.zero(); |
| 309 } |
| 310 |
| 311 /** |
| 312 * @return {!WebInspector.CSSLength} |
| 313 */ |
| 314 WebInspector.CSSLength.zero = function() |
| 315 { |
| 316 return new WebInspector.CSSLength(0, ""); |
| 317 } |
| 318 |
| 319 WebInspector.CSSLength.prototype = { |
| 320 /** |
| 321 * @return {string} |
| 322 */ |
| 323 asCSSText: function() |
| 324 { |
| 325 return this.amount + this.unit; |
| 326 } |
| 327 } |
| OLD | NEW |