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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/common/CSSShadowModel.js
diff --git a/third_party/WebKit/Source/devtools/front_end/common/CSSShadowModel.js b/third_party/WebKit/Source/devtools/front_end/common/CSSShadowModel.js
new file mode 100644
index 0000000000000000000000000000000000000000..c0099b3474020cd75e038795b5126e56fe9633fe
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/common/CSSShadowModel.js
@@ -0,0 +1,343 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @param {boolean} inset
+ * @param {!WebInspector.CSSLength} offsetX
+ * @param {!WebInspector.CSSLength} offsetY
+ * @param {!WebInspector.CSSLength} blurRadius
+ * @param {!WebInspector.CSSLength} spreadRadius
+ * @param {!WebInspector.Color} color
+ */
+WebInspector.CSSShadowModel = function(inset, offsetX, offsetY, blurRadius, spreadRadius, color)
+{
+ this._inset = inset;
+ this._offsetX = offsetX;
+ this._offsetY = offsetY;
+ this._blurRadius = blurRadius;
+ this._spreadRadius = spreadRadius;
+ this._color = color;
+ this._format = "XYB";
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.CSSShadowModel.FormatParts = {
+ Inset: "I",
+ OffsetX: "X",
+ OffsetY: "Y",
+ BlurRadius: "B",
+ SpreadRadius: "S",
+ Color: "C"
+}
+
+/**
+ * @param {string} text
+ * @return {!Array<!WebInspector.CSSShadowModel>}
+ */
+WebInspector.CSSShadowModel.parseTextShadow = function(text)
+{
+ return WebInspector.CSSShadowModel._parseShadow(text, false);
+}
+
+/**
+ * @param {string} text
+ * @return {!Array<!WebInspector.CSSShadowModel>}
+ */
+WebInspector.CSSShadowModel.parseBoxShadow = function(text)
+{
+ return WebInspector.CSSShadowModel._parseShadow(text, true);
+}
+
+WebInspector.CSSShadowModel.prototype = {
+ /**
+ * @param {boolean} inset
+ */
+ setInset: function(inset)
+ {
+ this._inset = inset;
+ },
+
+ /**
+ * @param {!WebInspector.CSSLength} offsetX
+ * @param {!WebInspector.CSSLength} offsetY
+ */
+ setOffset: function(offsetX, offsetY)
+ {
+ this._offsetX = offsetX;
+ this._offsetY = offsetY;
+ },
+
+ /**
+ * @param {!WebInspector.CSSLength} blurRadius
+ */
+ setBlurRadius: function(blurRadius)
+ {
+ this._blurRadius = blurRadius;
+ },
+
+ /**
+ * @param {!WebInspector.CSSLength} spreadRadius
+ */
+ setSpreadRadius: function(spreadRadius)
+ {
+ 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,
+ },
+
+ /**
+ * @param {!WebInspector.Color} color
+ */
+ setColor: function(color)
+ {
+ this._color = color;
+ },
+
+ /**
+ * @param {string} format
+ */
+ setFormat: function(format)
+ {
+ 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
+ },
+
+ /**
+ * @return {!WebInspector.CSSLength}
+ */
+ offsetX: function()
+ {
+ return this._offsetX;
+ },
+
+ /**
+ * @return {!WebInspector.CSSLength}
+ */
+ offsetY: function()
+ {
+ return this._offsetY;
+ },
+
+ /**
+ * @return {string}
+ */
+ asCSSText: function()
+ {
+ var parts = [];
+ for (var i = 0; i < this._format.length; i++) {
+ var part = this._format.charAt(i);
+ if (part === WebInspector.CSSShadowModel.FormatParts.Inset && this._inset)
+ parts.push("inset");
+ else if (part === WebInspector.CSSShadowModel.FormatParts.OffsetX)
+ parts.push(this._offsetX.asCSSText());
+ else if (part === WebInspector.CSSShadowModel.FormatParts.OffsetY)
+ parts.push(this._offsetY.asCSSText());
+ else if (part === WebInspector.CSSShadowModel.FormatParts.BlurRadius)
+ parts.push(this._blurRadius.asCSSText());
+ else if (part === WebInspector.CSSShadowModel.FormatParts.SpreadRadius)
+ parts.push(this._spreadRadius.asCSSText());
+ else if (part === WebInspector.CSSShadowModel.FormatParts.Color)
+ parts.push(this._color.asString(this._color.format()));
+ }
+ return parts.join(" ");
+ }
+}
+
+/**
+ * @param {string} text
+ * @param {boolean} isBoxShadow
+ * @return {!Array<!WebInspector.CSSShadowModel>}
+ */
+WebInspector.CSSShadowModel._parseShadow = function(text, isBoxShadow)
+{
+ var shadowTexts = [];
+ // Split by commas that aren't inside of color values to get the individual shadow values.
+ var splits = WebInspector.TextUtils.splitStringByRegexes(text, [WebInspector.Color.Regex, /,/g]);
+ var currentIndex = 0;
+ for (var i = 0; i < splits.length; i++) {
+ if (splits[i].regexIndex === 1) {
+ var comma = splits[i];
+ shadowTexts.push(text.substring(currentIndex, comma.position));
+ currentIndex = comma.position + 1;
+ }
+ }
+ shadowTexts.push(text.substring(currentIndex, text.length));
+
+ var shadows = [];
+ for (var i = 0; i < shadowTexts.length; i++) {
+ var shadow = new WebInspector.CSSShadowModel(false, WebInspector.CSSLength.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.
+ WebInspector.CSSLength.zero(), WebInspector.CSSLength.zero(), /** @type {!WebInspector.Color} */ (WebInspector.Color.parse("black")));
+ var format = "";
+ var nextPartAllowed = true;
+ var regexes = [/inset/gi, WebInspector.Color.Regex, WebInspector.CSSLength.regex()];
+ var results = WebInspector.TextUtils.splitStringByRegexes(shadowTexts[i], regexes);
+ for (var j = 0; j < results.length; j++) {
+ var result = results[j];
+ if (result.regexIndex === -1) {
+ // Don't allow anything other than inset, color, length values, and whitespace.
+ if (/\S/.test(result.value))
+ return [];
+ // All parts must be separated by whitespace.
+ nextPartAllowed = true;
+ } else {
+ if (!nextPartAllowed)
+ return [];
+ nextPartAllowed = false;
+
+ if (result.regexIndex === 0) {
+ shadow.setInset(true);
+ format += WebInspector.CSSShadowModel.FormatParts.Inset;
+ } else if (result.regexIndex === 1) {
+ var color = WebInspector.Color.parse(result.value);
+ if (!color)
+ return [];
+ shadow.setColor(color);
+ format += WebInspector.CSSShadowModel.FormatParts.Color;
+ } else if (result.regexIndex === 2) {
+ var length = WebInspector.CSSLength.parse(result.value);
+ if (!length)
+ return [];
+ var previousPart = format.length > 0 ? format.charAt(format.length - 1) : "";
+ if (previousPart === WebInspector.CSSShadowModel.FormatParts.OffsetX) {
+ shadow.setOffset(shadow.offsetX(), length);
dgozman 2016/08/22 16:56:41 Use fields, not setters.
flandy 2016/08/22 19:42:20 Done.
+ format += WebInspector.CSSShadowModel.FormatParts.OffsetY;
+ } else if (previousPart === WebInspector.CSSShadowModel.FormatParts.OffsetY) {
+ shadow.setBlurRadius(length);
+ format += WebInspector.CSSShadowModel.FormatParts.BlurRadius;
+ } else if (previousPart === WebInspector.CSSShadowModel.FormatParts.BlurRadius) {
+ shadow.setSpreadRadius(length);
+ format += WebInspector.CSSShadowModel.FormatParts.SpreadRadius;
+ } else {
+ shadow.setOffset(length, shadow.offsetY());
+ format += WebInspector.CSSShadowModel.FormatParts.OffsetX;
+ }
+ }
+ }
+ }
+ if (invalidCount(WebInspector.CSSShadowModel.FormatParts.OffsetX, 1, 1)
+ || invalidCount(WebInspector.CSSShadowModel.FormatParts.OffsetY, 1, 1)
+ || invalidCount(WebInspector.CSSShadowModel.FormatParts.Color, 0, 1)
+ || invalidCount(WebInspector.CSSShadowModel.FormatParts.BlurRadius, 0, 1)
+ || invalidCount(WebInspector.CSSShadowModel.FormatParts.Inset, 0, isBoxShadow ? 1 : 0)
+ || invalidCount(WebInspector.CSSShadowModel.FormatParts.SpreadRadius, 0, isBoxShadow ? 1 : 0))
+ return [];
+ 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
+ shadows.push(shadow);
+ }
+ return shadows;
+
+ /**
+ * @param {string} character
+ * @param {number} min
+ * @param {number} max
+ * @return {boolean}
+ */
+ function invalidCount(character, min, max)
+ {
+ var count = 0;
+ for (var i = 0; i < format.length; i++) {
+ if (format.charAt(i) === character)
+ count++;
+ }
+ return count < min || count > max;
+ }
+}
+
+/**
+ * @constructor
+ * @param {number} amount
+ * @param {!WebInspector.CSSLengthUnit} unit
+ */
+WebInspector.CSSLength = function(amount, unit)
+{
+ this.amount = amount;
+ this.unit = unit;
+}
+
+/** @type {!RegExp} */
+WebInspector.CSSNumberRegex = /[+-]?(?:[0-9]*[.])?[0-9]+/;
+/** @type {!RegExp} */
+WebInspector.CSSZeroRegex = /[+-]?(?:0*[.])?0+/;
+/** @type {!RegExp} */
+WebInspector.CSSExponentRegex = /(?:[eE][+-]?[0-9]+)?/;
+
+/**
+ * @return {!RegExp}
+ */
+WebInspector.CSSLength.regex = function()
+{
+ var number = WebInspector.CSSNumberRegex.source + WebInspector.CSSExponentRegex.source;
+ var unit = WebInspector.CSSLengthUnit.regex().source;
+ var zero = WebInspector.CSSZeroRegex.source + WebInspector.CSSExponentRegex.source;
+ 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.
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.CSSLengthUnit = {
+ Ch: "ch",
+ Cm: "cm",
+ Em: "em",
+ Ex: "ex",
+ In: "in",
+ Mm: "mm",
+ Pc: "pc",
+ Pt: "pt",
+ Px: "px",
+ Rem: "rem",
+ Vh: "vh",
+ Vmax: "vmax",
+ Vmin: "vmin",
+ Vw: "vw",
+ None: ""
+}
+
+/**
+ * @return {!RegExp}
+ */
+WebInspector.CSSLengthUnit.regex = function()
+{
+ var units = [];
+ var keys = Object.keys(WebInspector.CSSLengthUnit);
+ for (var i = 0; i < keys.length; i++) {
+ var unit = WebInspector.CSSLengthUnit[keys[i]];
+ 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.
+ units.push(unit);
+ }
+ 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.
+}
+
+/**
+ * @param {string} text
+ * @return {?WebInspector.CSSLength}
+ */
+WebInspector.CSSLength.parse = function(text)
+{
+ 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
+ var match = text.match(lengthRegex) || [];
+ if (match.length > 2 && match[2])
+ return new WebInspector.CSSLength(parseFloat(match[1]), match[2]);
+ else if (match.length > 0)
+ return WebInspector.CSSLength.zero();
+ return null;
+}
+
+/**
+ * @return {!WebInspector.CSSLength}
+ */
+WebInspector.CSSLength.zero = function()
+{
+ return new WebInspector.CSSLength(0, WebInspector.CSSLengthUnit.None);
+}
+
+WebInspector.CSSLength.prototype = {
+ /**
+ * @return {string}
+ */
+ asCSSText: function()
+ {
+ return this.amount + this.unit;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698