Bug 1332085 - Add Color Name Field to Color Widget. r=gl
authorMicah Tigley <tigleym@gmail.com>
Mon, 08 May 2017 20:31:37 -0600
changeset 357460 c40129d19820fbf3cef1a70cb0c1a3ef1b8a69c5
parent 357459 50453d163a13558a677737bcaa97af00fe03800c
child 357461 3d157ccbc5a793ab96cc6a2c2b8aca2bd57f5056
push id31792
push usercbook@mozilla.com
push dateWed, 10 May 2017 13:07:59 +0000
treeherdermozilla-central@ebbcdaa5b580 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgl
bugs1332085
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1332085 - Add Color Name Field to Color Widget. r=gl MozReview-Commit-ID: AYFulQcvBwv
devtools/client/inspector/inspector.xhtml
devtools/client/locales/en-US/inspector.properties
devtools/client/shared/widgets/ColorWidget.js
devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
devtools/server/actors/highlighters/eye-dropper.js
devtools/shared/css/color.js
--- a/devtools/client/inspector/inspector.xhtml
+++ b/devtools/client/inspector/inspector.xhtml
@@ -4,17 +4,16 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 <!DOCTYPE html>
 
 <html xmlns="http://www.w3.org/1999/xhtml" dir="">
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 
   <link rel="stylesheet" href="chrome://devtools/skin/widgets.css"/>
-  <link rel="stylesheet" href="chrome://devtools/content/shared/widgets/color-widget.css"/>
   <link rel="stylesheet" href="chrome://devtools/skin/inspector.css"/>
   <link rel="stylesheet" href="chrome://devtools/skin/rules.css"/>
   <link rel="stylesheet" href="chrome://devtools/skin/computed.css"/>
   <link rel="stylesheet" href="chrome://devtools/skin/fonts.css"/>
   <link rel="stylesheet" href="chrome://devtools/skin/boxmodel.css"/>
   <link rel="stylesheet" href="chrome://devtools/skin/layout.css"/>
   <link rel="stylesheet" href="chrome://devtools/skin/animationinspector.css"/>
   <link rel="stylesheet" href="resource://devtools/client/shared/components/sidebar-toggle.css"/>
--- a/devtools/client/locales/en-US/inspector.properties
+++ b/devtools/client/locales/en-US/inspector.properties
@@ -349,16 +349,20 @@ inspector.sidebar.layoutViewTitle2=Layou
 # This is the title shown in a tab in the side panel of the Inspector panel
 # that corresponds to the tool displaying animations defined in the page.
 inspector.sidebar.animationInspectorTitle=Animations
 
 # LOCALIZATION NOTE (inspector.eyedropper.label): A string displayed as the tooltip of
 # a button in the inspector which toggles the Eyedropper tool
 inspector.eyedropper.label=Grab a color from the page
 
+# LOCALIZATION NOTE (inspector.colorwidget.colorNameLabel):
+# The label for the current color widget's color name field.
+inspector.colorwidget.colorNameLabel=Color Name:
+
 # LOCALIZATION NOTE (inspector.colorwidget.contrastRatio.header):
 # This string is used as a header to indicate the contrast section of the
 # color widget.
 inspector.colorwidget.contrastRatio.header=Contrast Ratio
 
 # LOCALIZATION NOTE (inspector.colorwidget.contrastRatio.invalidColor):
 # This string is used when an invalid color is passed as a background color
 # to the color widget.
--- a/devtools/client/shared/widgets/ColorWidget.js
+++ b/devtools/client/shared/widgets/ColorWidget.js
@@ -255,16 +255,17 @@ ColorWidget.prototype = {
 
   get rgbCssString() {
     let rgb = this.rgb;
     return "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " +
       rgb[3] + ")";
   },
 
   initializeColorWidget: function () {
+    let colorNameLabel = L10N.getStr("inspector.colorwidget.colorNameLabel");
     this.parentEl.innerHTML = "";
     this.element = this.parentEl.ownerDocument.createElementNS(XHTML_NS, "div");
 
     this.element.className = "colorwidget-container";
     this.element.innerHTML = `
       <div class="colorwidget-top">
         <div class="colorwidget-fill"></div>
         <div class="colorwidget-top-inner">
@@ -302,16 +303,20 @@ ColorWidget.prototype = {
         </div>
         <div class="colorwidget-hsla colorwidget-hidden">
           <input class="colorwidget-hsla-h" data-id="h" />
           <input class="colorwidget-hsla-s" data-id="s" />
           <input class="colorwidget-hsla-l" data-id="l" />
           <input class="colorwidget-hsla-a" data-id="a" />
         </div>
       </div>
+      <div class="colorwidget-colorname">
+        <label class="colorwidget-colorname-label">${colorNameLabel}</label>
+        <span class="colorwidget-colorname-value"></span>
+      </div>
     <div class="colorwidget-contrast">
       <div class="colorwidget-contrast-info"></div>
       <div class="colorwidget-contrast-inner">
         <span class="colorwidget-colorswatch"></span>
         <span class="colorwidget-contrast-ratio"></span>
         <span class="colorwidget-contrast-grade"></span>
         <button class="colorwidget-contrast-help devtools-button"></button>
       </div>
@@ -319,16 +324,18 @@ ColorWidget.prototype = {
     `;
 
     this.element.addEventListener("click", this.onElementClick);
 
     this.parentEl.appendChild(this.element);
 
     this.closestBackgroundColor = "rgba(255, 255, 255, 1)";
 
+    this.colorName = this.element.querySelector(".colorwidget-colorname-value");
+
     this.contrast = this.element.querySelector(".colorwidget-contrast");
     this.contrastInfo = this.element.querySelector(".colorwidget-contrast-info");
     this.contrastInfo.textContent = L10N.getStr(
       "inspector.colorwidget.contrastRatio.header"
     );
 
     this.contrastInner = this.element.querySelector(".colorwidget-contrast-inner");
     this.contrastSwatch = this.contrastInner.querySelector(".colorwidget-colorswatch");
@@ -562,17 +569,17 @@ ColorWidget.prototype = {
       this.contrastGrade.textContent = "";
       this.contrastHelp.removeAttribute("title");
       return;
     }
     if (!this.rgbaColor) {
       this.rgbaColor = new colorUtils.CssColor(this.closestBackgroundColor);
     }
     this.rgbaColor.newColor(this.closestBackgroundColor);
-    let rgba = this.rgbaColor._getRGBATuple();
+    let rgba = this.rgbaColor.getRGBATuple();
     let backgroundColor = [rgba.r, rgba.g, rgba.b, rgba.a];
 
     let textColor = this.rgb;
 
     let ratio = colorUtils.calculateContrastRatio(backgroundColor, textColor);
 
     let contrastDetails = ColorWidget.calculateGradeAndTitle(ratio,
                         this.rgbaColor.toString());
@@ -653,22 +660,26 @@ ColorWidget.prototype = {
 
     this.dragger.style.backgroundColor = flatColor;
 
     let rgbNoAlpha = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";
     let rgbAlpha0 = "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ", 0)";
     let alphaGradient = "linear-gradient(to right, " + rgbAlpha0 + ", " +
       rgbNoAlpha + ")";
     this.alphaSliderInner.style.background = alphaGradient;
+
+    let colorName = colorUtils.rgbToColorName(rgb[0], rgb[1], rgb[2]);
+    this.colorName.textContent = colorName || "---";
   },
 
   destroy: function () {
     this.element.removeEventListener("click", this.onElementClick);
 
     this.parentEl.removeChild(this.element);
 
     this.slider = null;
     this.dragger = null;
     this.alphaSlider = this.alphaSliderInner = this.alphaSliderHelper = null;
     this.parentEl = null;
     this.element = null;
+    this.colorName = null;
   }
 };
--- a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
+++ b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
@@ -34,20 +34,19 @@ const XHTML_NS = "http://www.w3.org/1999
  *        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,
                                   {supportsCssColor4ColorFunction}) {
   let stylesheet = NEW_COLOR_WIDGET ?
-    null :
+    "chrome://devtools/content/shared/widgets/color-widget.css" :
     "chrome://devtools/content/shared/widgets/spectrum.css";
-  let tooltipDocument = NEW_COLOR_WIDGET ? inspector.panelDoc : document;
-  SwatchBasedEditorTooltip.call(this, tooltipDocument, stylesheet, NEW_COLOR_WIDGET);
+  SwatchBasedEditorTooltip.call(this, document, stylesheet);
 
   this.inspector = inspector;
 
   // Creating a spectrum instance. this.spectrum will always be a promise that
   // resolves to the spectrum instance
   this.spectrum = this.setColorPickerContent([0, 0, 0, 1]);
   this._onSpectrumColorChange = this._onSpectrumColorChange.bind(this);
   this._openEyeDropper = this._openEyeDropper.bind(this);
--- a/devtools/server/actors/highlighters/eye-dropper.js
+++ b/devtools/server/actors/highlighters/eye-dropper.js
@@ -505,22 +505,17 @@ function toColorString(rgb, format) {
     case "hex":
       return hexString(rgb);
     case "rgb":
       return "rgb(" + r + ", " + g + ", " + b + ")";
     case "hsl":
       let [h, s, l] = rgbToHsl(rgb);
       return "hsl(" + h + ", " + s + "%, " + l + "%)";
     case "name":
-      let str;
-      try {
-        str = rgbToColorName(r, g, b);
-      } catch (e) {
-        str = hexString(rgb);
-      }
+      let str = rgbToColorName(r, g, b) || hexString(rgb);
       return str;
     default:
       return hexString(rgb);
   }
 }
 
 /**
  * Produce a hex-formatted color string from rgb values.
--- a/devtools/shared/css/color.js
+++ b/devtools/shared/css/color.js
@@ -165,27 +165,23 @@ CssColor.prototype = {
   },
 
   get name() {
     let invalidOrSpecialValue = this._getInvalidOrSpecialValue();
     if (invalidOrSpecialValue !== false) {
       return invalidOrSpecialValue;
     }
 
-    try {
-      let tuple = this.getRGBATuple();
+    let tuple = this.getRGBATuple();
 
-      if (tuple.a !== 1) {
-        return this.hex;
-      }
-      let {r, g, b} = tuple;
-      return rgbToColorName(r, g, b);
-    } catch (e) {
+    if (tuple.a !== 1) {
       return this.hex;
     }
+    let {r, g, b} = tuple;
+    return rgbToColorName(r, g, b) || this.hex;
   },
 
   get hex() {
     let invalidOrSpecialValue = this._getInvalidOrSpecialValue();
     if (invalidOrSpecialValue !== false) {
       return invalidOrSpecialValue;
     }
     if (this.hasAlpha) {
@@ -448,17 +444,17 @@ CssColor.prototype = {
   },
 
   /**
    * Check whether the color is fully transparent (alpha === 0).
    *
    * @return {Boolean} True if the color is transparent and valid.
    */
   isTransparent: function () {
-    return this._getRGBATuple().a === 0;
+    return this.getRGBATuple().a === 0;
   },
 };
 
 /**
  * Convert rgb value to hsl
  *
  * @param {array} rgb
  *         Array of rgb values
@@ -559,37 +555,33 @@ function classifyColor(value) {
   return CssColor.COLORUNIT.name;
 }
 
 // This holds a map from colors back to color names for use by
 // rgbToColorName.
 var cssRGBMap;
 
 /**
- * Given a color, return its name, if it has one.  Throws an exception
- * if the color does not have a name.
+ * Given a color, return its name, if it has one. Otherwise
+ * returns an empty string.
  *
  * @param {Number} r, g, b  The color components.
- * @return {String} the name of the color
+ * @return {String} the name of the color or an empty string
  */
 function rgbToColorName(r, g, b) {
   if (!cssRGBMap) {
     cssRGBMap = {};
     for (let name in cssColors) {
       let key = JSON.stringify(cssColors[name]);
       if (!(key in cssRGBMap)) {
         cssRGBMap[key] = name;
       }
     }
   }
-  let value = cssRGBMap[JSON.stringify([r, g, b, 1])];
-  if (!value) {
-    throw new Error("no such color");
-  }
-  return value;
+  return cssRGBMap[JSON.stringify([r, g, b, 1])] || "";
 }
 
 // Translated from nsColor.cpp.
 function _hslValue(m1, m2, h) {
   if (h < 0.0) {
     h += 1.0;
   }
   if (h > 1.0) {