From f3aeeab64f6a5ae0639805b2c71e13323258e2c1 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Fri, 2 Feb 2018 20:51:18 +0100 Subject: Support for css-color-4 (finish) Issue #4 --- browser/components/extensions/ext-browserAction.js | 8 ++--- browser/components/extensions/ext-utils.js | 4 --- .../client/inspector/shared/tooltips-overlay.js | 4 ++- devtools/client/shared/output-parser.js | 17 +++++++---- .../client/shared/test/unit/test_cssColor-03.js | 6 ++-- .../widgets/tooltip/SwatchColorPickerTooltip.js | 11 +++++-- devtools/server/actors/css-properties.js | 6 +++- devtools/shared/css/color.js | 32 +++++++++++++------- devtools/shared/fronts/css-properties.js | 34 ++++++++++++++++++++++ 9 files changed, 90 insertions(+), 32 deletions(-) diff --git a/browser/components/extensions/ext-browserAction.js b/browser/components/extensions/ext-browserAction.js index 97c6fd22c..407366e2c 100644 --- a/browser/components/extensions/ext-browserAction.js +++ b/browser/components/extensions/ext-browserAction.js @@ -9,9 +9,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "clearTimeout", XPCOMUtils.defineLazyModuleGetter(this, "setTimeout", "resource://gre/modules/Timer.jsm"); -XPCOMUtils.defineLazyGetter(this, "colorUtils", () => { - return require("devtools/shared/css/color").colorUtils; -}); +XPCOMUtils.defineLazyServiceGetter(this, "DOMUtils", + "@mozilla.org/inspector/dom-utils;1", + "inIDOMUtils"); Cu.import("resource://devtools/shared/event-emitter.js"); Cu.import("resource://gre/modules/ExtensionUtils.jsm"); @@ -511,7 +511,7 @@ extensions.registerSchemaAPI("browserAction", "addon_parent", context => { let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null; let color = details.color; if (!Array.isArray(color)) { - let col = colorUtils.colorToRGBA(color); + let col = DOMUtils.colorToRGBA(color); color = col && [col.r, col.g, col.b, Math.round(col.a * 255)]; } BrowserAction.for(extension).setProperty(tab, "badgeBackgroundColor", color); diff --git a/browser/components/extensions/ext-utils.js b/browser/components/extensions/ext-utils.js index 57c38a339..75b2f4bd4 100644 --- a/browser/components/extensions/ext-utils.js +++ b/browser/components/extensions/ext-utils.js @@ -17,10 +17,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "styleSheetService", "@mozilla.org/content/style-sheet-service;1", "nsIStyleSheetService"); -XPCOMUtils.defineLazyGetter(this, "colorUtils", () => { - return require("devtools/shared/css/color").colorUtils; -}); - Cu.import("resource://gre/modules/ExtensionUtils.jsm"); Cu.import("resource://gre/modules/AppConstants.jsm"); diff --git a/devtools/client/inspector/shared/tooltips-overlay.js b/devtools/client/inspector/shared/tooltips-overlay.js index 8a02d7e3d..336dae05b 100644 --- a/devtools/client/inspector/shared/tooltips-overlay.js +++ b/devtools/client/inspector/shared/tooltips-overlay.js @@ -88,7 +88,9 @@ TooltipsOverlay.prototype = { if (this.isRuleView) { // Color picker tooltip - this.colorPicker = new SwatchColorPickerTooltip(toolbox.doc, this.view.inspector); + this.colorPicker = new SwatchColorPickerTooltip(toolbox.doc, + this.view.inspector, + this._cssProperties); // Cubic bezier tooltip this.cubicBezier = new SwatchCubicBezierTooltip(toolbox.doc); // Filter editor tooltip diff --git a/devtools/client/shared/output-parser.js b/devtools/client/shared/output-parser.js index 726c93b8b..b4fb1c6aa 100644 --- a/devtools/client/shared/output-parser.js +++ b/devtools/client/shared/output-parser.js @@ -40,8 +40,11 @@ const CSS_GRID_ENABLED_PREF = "layout.css.grid.enabled"; * where CSS_TYPES is defined in devtools/shared/css/properties-db.js * @param {Function} isValidOnClient - A function that checks if a css property * name/value combo is valid. + * @param {Function} supportsCssColor4ColorFunction - A function for checking + * the supporting of css-color-4 color function. */ -function OutputParser(document, {supportsType, isValidOnClient}) { +function OutputParser(document, + {supportsType, isValidOnClient, supportsCssColor4ColorFunction}) { this.parsed = []; this.doc = document; this.supportsType = supportsType; @@ -50,6 +53,8 @@ function OutputParser(document, {supportsType, isValidOnClient}) { this.angleSwatches = new WeakMap(); this._onColorSwatchMouseDown = this._onColorSwatchMouseDown.bind(this); this._onAngleSwatchMouseDown = this._onAngleSwatchMouseDown.bind(this); + + this.cssColor4 = supportsCssColor4ColorFunction(); } exports.OutputParser = OutputParser; @@ -188,7 +193,8 @@ OutputParser.prototype = { if (options.expectCubicBezier && token.text === "cubic-bezier") { this._appendCubicBezier(functionText, options); - } else if (colorOK() && colorUtils.isValidCSSColor(functionText)) { + } else if (colorOK() && + colorUtils.isValidCSSColor(functionText, this.cssColor4)) { this._appendColor(functionText, options); } else { this._appendTextNode(functionText); @@ -205,7 +211,8 @@ OutputParser.prototype = { options.expectDisplay && token.text === "grid" && text === token.text) { this._appendGrid(token.text, options); - } else if (colorOK() && colorUtils.isValidCSSColor(token.text)) { + } else if (colorOK() && + colorUtils.isValidCSSColor(token.text, this.cssColor4)) { this._appendColor(token.text, options); } else if (angleOK(token.text)) { this._appendAngle(token.text, options); @@ -218,7 +225,7 @@ OutputParser.prototype = { case "id": case "hash": { let original = text.substring(token.startOffset, token.endOffset); - if (colorOK() && colorUtils.isValidCSSColor(original)) { + if (colorOK() && colorUtils.isValidCSSColor(original, this.cssColor4)) { this._appendColor(original, options); } else { this._appendTextNode(original); @@ -394,7 +401,7 @@ OutputParser.prototype = { * _mergeOptions(). */ _appendColor: function (color, options = {}) { - let colorObj = new colorUtils.CssColor(color); + let colorObj = new colorUtils.CssColor(color, this.cssColor4); if (this._isValidColor(colorObj)) { let container = this._createNode("span", { diff --git a/devtools/client/shared/test/unit/test_cssColor-03.js b/devtools/client/shared/test/unit/test_cssColor-03.js index c3ef5a5c2..a081f7698 100644 --- a/devtools/client/shared/test/unit/test_cssColor-03.js +++ b/devtools/client/shared/test/unit/test_cssColor-03.js @@ -42,15 +42,15 @@ const CSS_COLOR_4_TESTS = [ function run_test() { for (let test of OLD_STYLE_TESTS) { - let ours = colorUtils.colorToRGBA(test, true); + let ours = colorUtils.colorToRGBA(test, false); let platform = DOMUtils.colorToRGBA(test); deepEqual(ours, platform, "color " + test + " matches DOMUtils"); ok(ours !== null, "'" + test + "' is a color"); } for (let test of CSS_COLOR_4_TESTS) { - let oursOld = colorUtils.colorToRGBA(test, true); - let oursNew = colorUtils.colorToRGBA(test, false); + let oursOld = colorUtils.colorToRGBA(test, false); + let oursNew = colorUtils.colorToRGBA(test, true); let platform = DOMUtils.colorToRGBA(test); notEqual(oursOld, platform, "old style parser for color " + test + " should not match DOMUtils"); diff --git a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js index bf211b8b9..6a18ec12c 100644 --- a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js +++ b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js @@ -28,8 +28,12 @@ const XHTML_NS = "http://www.w3.org/1999/xhtml"; * inline editor. * @param {InspectorPanel} inspector * The inspector panel, needed for the eyedropper. + * @param {Function} supportsCssColor4ColorFunction + * A function for checking the supporting of css-color-4 color function. */ -function SwatchColorPickerTooltip(document, inspector) { +function SwatchColorPickerTooltip(document, + inspector, + {supportsCssColor4ColorFunction}) { let stylesheet = "chrome://devtools/content/shared/widgets/spectrum.css"; SwatchBasedEditorTooltip.call(this, document, stylesheet); @@ -40,6 +44,7 @@ function SwatchColorPickerTooltip(document, inspector) { this.spectrum = this.setColorPickerContent([0, 0, 0, 1]); this._onSpectrumColorChange = this._onSpectrumColorChange.bind(this); this._openEyeDropper = this._openEyeDropper.bind(this); + this.cssColor4 = supportsCssColor4ColorFunction(); } SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.prototype, { @@ -159,14 +164,14 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr }, _colorToRgba: function (color) { - color = new colorUtils.CssColor(color); + color = new colorUtils.CssColor(color, this.cssColor4); let rgba = color._getRGBATuple(); return [rgba.r, rgba.g, rgba.b, rgba.a]; }, _toDefaultType: function (color) { let colorObj = new colorUtils.CssColor(color); - colorObj.setAuthoredUnitFromColor(this._originalColor); + colorObj.setAuthoredUnitFromColor(this._originalColor, this.cssColor4); return colorObj.toString(); }, diff --git a/devtools/server/actors/css-properties.js b/devtools/server/actors/css-properties.js index d24c133d4..b22d8005f 100644 --- a/devtools/server/actors/css-properties.js +++ b/devtools/server/actors/css-properties.js @@ -31,8 +31,12 @@ exports.CssPropertiesActor = ActorClassWithSpec(cssPropertiesSpec, { getCSSDatabase() { const properties = generateCssProperties(); const pseudoElements = DOMUtils.getCSSPseudoElementNames(); + const supportedFeature = { + // checking for css-color-4 color function support. + "css-color-4-color-function": DOMUtils.isValidCSSColor("rgb(1 1 1 / 100%)"), + }; - return { properties, pseudoElements }; + return { properties, pseudoElements, supportedFeature }; } }); diff --git a/devtools/shared/css/color.js b/devtools/shared/css/color.js index b354043d7..98ddeff19 100644 --- a/devtools/shared/css/color.js +++ b/devtools/shared/css/color.js @@ -28,6 +28,10 @@ const SPECIALVALUES = new Set([ * Usage: * let {colorUtils} = require("devtools/shared/css/color"); * let color = new colorUtils.CssColor("red"); + * // In order to support css-color-4 color function, pass true to the + * // second argument. + * // e.g. + * // let color = new colorUtils.CssColor("red", true); * * color.authored === "red" * color.hasAlpha === false @@ -58,8 +62,9 @@ const SPECIALVALUES = new Set([ * Valid values for COLOR_UNIT_PREF are contained in CssColor.COLORUNIT. */ -function CssColor(colorValue) { +function CssColor(colorValue, supportsCssColor4ColorFunction = false) { this.newColor(colorValue); + this.cssColor4 = supportsCssColor4ColorFunction; } module.exports.colorUtils = { @@ -92,6 +97,9 @@ CssColor.prototype = { // A lower-cased copy of |authored|. lowerCased: null, + // Whether the value should be parsed using css-color-4 rules. + cssColor4: false, + _setColorUnitUppercase: function (color) { // Specifically exclude the case where the color is // case-insensitive. This makes it so that "#000" isn't @@ -136,7 +144,7 @@ CssColor.prototype = { }, get valid() { - return isValidCSSColor(this.authored); + return isValidCSSColor(this.authored, this.cssColor4); }, /** @@ -393,7 +401,7 @@ CssColor.prototype = { * appropriate. */ _getRGBATuple: function () { - let tuple = colorToRGBA(this.authored); + let tuple = colorToRGBA(this.authored, this.cssColor4); tuple.a = parseFloat(tuple.a.toFixed(1)); @@ -481,11 +489,13 @@ function roundTo(number, digits) { * Color in the form of hex, hsl, hsla, rgb, rgba. * @param {Number} alpha * Alpha value for the color, between 0 and 1. + * @param {Boolean} useCssColor4ColorFunction + * use css-color-4 color function or not. * @return {String} * Converted color with `alpha` value in rgba form. */ -function setAlpha(colorValue, alpha) { - let color = new CssColor(colorValue); +function setAlpha(colorValue, alpha, useCssColor4ColorFunction = false) { + let color = new CssColor(colorValue, useCssColor4ColorFunction); // Throw if the color supplied is not valid. if (!color.valid) { @@ -1049,12 +1059,11 @@ function parseOldStyleRgb(lexer, hasAlpha) { * color's components. Any valid CSS color form can be passed in. * * @param {String} name the color - * @param {Boolean} oldColorFunctionSyntax use old color function syntax or the - * css-color-4 syntax + * @param {Boolean} useCssColor4ColorFunction use css-color-4 color function or not. * @return {Object} an object of the form {r, g, b, a}; or null if the * name was not a valid color */ -function colorToRGBA(name, oldColorFunctionSyntax = true) { +function colorToRGBA(name, useCssColor4ColorFunction = false) { name = name.trim().toLowerCase(); if (name in cssColors) { @@ -1089,7 +1098,7 @@ function colorToRGBA(name, oldColorFunctionSyntax = true) { let hsl = func.text === "hsl" || func.text === "hsla"; let vals; - if (oldColorFunctionSyntax) { + if (!useCssColor4ColorFunction) { let hasAlpha = (func.text === "rgba" || func.text === "hsla"); vals = hsl ? parseOldStyleHsl(lexer, hasAlpha) : parseOldStyleRgb(lexer, hasAlpha); } else { @@ -1110,8 +1119,9 @@ function colorToRGBA(name, oldColorFunctionSyntax = true) { * Check whether a string names a valid CSS color. * * @param {String} name The string to check + * @param {Boolean} useCssColor4ColorFunction use css-color-4 color function or not. * @return {Boolean} True if the string is a CSS color name. */ -function isValidCSSColor(name) { - return colorToRGBA(name) !== null; +function isValidCSSColor(name, useCssColor4ColorFunction = false) { + return colorToRGBA(name, useCssColor4ColorFunction) !== null; } diff --git a/devtools/shared/fronts/css-properties.js b/devtools/shared/fronts/css-properties.js index 9b3172a22..d61bb4b07 100644 --- a/devtools/shared/fronts/css-properties.js +++ b/devtools/shared/fronts/css-properties.js @@ -46,6 +46,20 @@ const CssPropertiesFront = FrontClassWithSpec(cssPropertiesSpec, { } }); +/** + * Query the feature supporting status in the featureSet. + * + * @param {Hashmap} featureSet the feature set hashmap + * @param {String} feature the feature name string + * @return {Boolean} has the feature or not + */ +function hasFeature(featureSet, feature) { + if (feature in featureSet) { + return featureSet[feature]; + } + return false; +} + /** * Ask questions to a CSS database. This class does not care how the database * gets loaded in, only the questions that you can ask to it. @@ -62,10 +76,16 @@ function CssProperties(db) { this.properties = db.properties; this.pseudoElements = db.pseudoElements; + // supported feature + this.cssColor4ColorFunction = hasFeature(db.supportedFeature, + "css-color-4-color-function"); + this.isKnown = this.isKnown.bind(this); this.isInherited = this.isInherited.bind(this); this.supportsType = this.supportsType.bind(this); this.isValidOnClient = this.isValidOnClient.bind(this); + this.supportsCssColor4ColorFunction = + this.supportsCssColor4ColorFunction.bind(this); // A weakly held dummy HTMLDivElement to test CSS properties on the client. this._dummyElements = new WeakMap(); @@ -181,6 +201,15 @@ CssProperties.prototype = { } return []; }, + + /** + * Checking for the css-color-4 color function support. + * + * @return {Boolean} Return true if the server supports css-color-4 color function. + */ + supportsCssColor4ColorFunction() { + return this.cssColor4ColorFunction; + }, }; /** @@ -292,6 +321,11 @@ function normalizeCssData(db) { reattachCssColorValues(db); + // If there is no supportedFeature in db, create an empty one. + if (!db.supportedFeature) { + db.supportedFeature = {}; + } + return db; } -- cgit v1.2.3