Web Inspector: Add colorpicker functionality to color swatches in Styles Sidebar
authorapavlov@chromium.org <apavlov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Feb 2012 13:18:01 +0000 (13:18 +0000)
committerapavlov@chromium.org <apavlov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Feb 2012 13:18:01 +0000 (13:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=71262

Patch by Brian Grinstead <briangrinstead@gmail.com> on 2012-02-13
Reviewed by Pavel Feldman.

* English.lproj/localizedStrings.js:
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* inspector/front-end/Settings.js:
* inspector/front-end/Spectrum.js: Added.
(WebInspector.Spectrum.hueDrag):
(WebInspector.Spectrum.colorDrag):
(WebInspector.Spectrum.alphaDrag):
(WebInspector.Spectrum):
(WebInspector.Spectrum.hsvaToRGBA):
(WebInspector.Spectrum.rgbaToHSVA):
(WebInspector.Spectrum.draggable.prevent):
(WebInspector.Spectrum.draggable.move):
(WebInspector.Spectrum.draggable.start):
(WebInspector.Spectrum.draggable.stop):
(WebInspector.Spectrum.draggable):
(WebInspector.Spectrum.prototype.set color):
(WebInspector.Spectrum.prototype.get color):
(WebInspector.Spectrum.prototype.get outputColorFormat):
(WebInspector.Spectrum.prototype.get colorHueOnly):
(WebInspector.Spectrum.prototype.set displayText):
(WebInspector.Spectrum.prototype._onchange):
(WebInspector.Spectrum.prototype._updateHelperLocations):
(WebInspector.Spectrum.prototype._updateUI):
(WebInspector.Spectrum.prototype.toggle):
(WebInspector.Spectrum.prototype.show):
(WebInspector.Spectrum.prototype.reposition):
(WebInspector.Spectrum.prototype.hide):
* inspector/front-end/StylesSidebarPane.js:
(WebInspector.StylesSidebarPane):
(WebInspector.StylePropertyTreeElement.prototype.updateTitle.):
* inspector/front-end/WebKit.qrc:
* inspector/front-end/inspector.css:
(.swatch):
(.swatch-inner):
(.spectrum-container):
(.spectrum-top):
(.spectrum-color):
(.spectrum-hue):
(.spectrum-fill):
(.spectrum-range-container):
(.spectrum-range-container *):
(.spectrum-range-container label):
(.spectrum-range-container input):
(.swatch, .spectrum-dragger, .spectrum-slider):
(.spectrum-sat):
(.spectrum-val):
(.spectrum-dragger):
(.spectrum-slider):
* inspector/front-end/inspector.html:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@107804 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/inspector/front-end/Settings.js
Source/WebCore/inspector/front-end/Spectrum.js [new file with mode: 0644]
Source/WebCore/inspector/front-end/StylesSidebarPane.js
Source/WebCore/inspector/front-end/WebKit.qrc
Source/WebCore/inspector/front-end/inspector.css
Source/WebCore/inspector/front-end/inspector.html

index a0d76b6..7eaff72 100644 (file)
@@ -1,3 +1,61 @@
+2012-02-13  Brian Grinstead  <briangrinstead@gmail.com>
+
+        Web Inspector: Add colorpicker functionality to color swatches in Styles Sidebar
+        https://bugs.webkit.org/show_bug.cgi?id=71262
+
+        Reviewed by Pavel Feldman.
+
+        * English.lproj/localizedStrings.js:
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * inspector/front-end/Settings.js:
+        * inspector/front-end/Spectrum.js: Added.
+        (WebInspector.Spectrum.hueDrag):
+        (WebInspector.Spectrum.colorDrag):
+        (WebInspector.Spectrum.alphaDrag):
+        (WebInspector.Spectrum):
+        (WebInspector.Spectrum.hsvaToRGBA):
+        (WebInspector.Spectrum.rgbaToHSVA):
+        (WebInspector.Spectrum.draggable.prevent):
+        (WebInspector.Spectrum.draggable.move):
+        (WebInspector.Spectrum.draggable.start):
+        (WebInspector.Spectrum.draggable.stop):
+        (WebInspector.Spectrum.draggable):
+        (WebInspector.Spectrum.prototype.set color):
+        (WebInspector.Spectrum.prototype.get color):
+        (WebInspector.Spectrum.prototype.get outputColorFormat):
+        (WebInspector.Spectrum.prototype.get colorHueOnly):
+        (WebInspector.Spectrum.prototype.set displayText):
+        (WebInspector.Spectrum.prototype._onchange):
+        (WebInspector.Spectrum.prototype._updateHelperLocations):
+        (WebInspector.Spectrum.prototype._updateUI):
+        (WebInspector.Spectrum.prototype.toggle):
+        (WebInspector.Spectrum.prototype.show):
+        (WebInspector.Spectrum.prototype.reposition):
+        (WebInspector.Spectrum.prototype.hide):
+        * inspector/front-end/StylesSidebarPane.js:
+        (WebInspector.StylesSidebarPane):
+        (WebInspector.StylePropertyTreeElement.prototype.updateTitle.):
+        * inspector/front-end/WebKit.qrc:
+        * inspector/front-end/inspector.css:
+        (.swatch):
+        (.swatch-inner):
+        (.spectrum-container):
+        (.spectrum-top):
+        (.spectrum-color):
+        (.spectrum-hue):
+        (.spectrum-fill):
+        (.spectrum-range-container):
+        (.spectrum-range-container *):
+        (.spectrum-range-container label):
+        (.spectrum-range-container input):
+        (.swatch, .spectrum-dragger, .spectrum-slider):
+        (.spectrum-sat):
+        (.spectrum-val):
+        (.spectrum-dragger):
+        (.spectrum-slider):
+        * inspector/front-end/inspector.html:
+
 2012-02-15  Kenneth Rohde Christiansen  <kenneth@webkit.org>
 
         [Qt] Be smarter with tile usages during tiling
index 0620456..4e6a2c6 100644 (file)
             'inspector/front-end/SourceHTMLTokenizer.js',
             'inspector/front-end/SourceJavaScriptTokenizer.js',
             'inspector/front-end/SourceTokenizer.js',
+            'inspector/front-end/Spectrum.js',
             'inspector/front-end/SplitView.js',
             'inspector/front-end/StatusBarButton.js',
             'inspector/front-end/StylesSidebarPane.js',
index 070ab3f..593c717 100755 (executable)
                                        >
                                </File>
                                <File
+                                       RelativePath="..\inspector\front-end\Spectrum.js"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\inspector\front-end\splitView.css"
                                        >
                                </File>
index 0aa4d01..4d4a63c 100644 (file)
@@ -44,7 +44,8 @@ var Preferences = {
     exposeWorkersInspection: false,
     applicationTitle: "Web Inspector - %s",
     showHeapSnapshotObjectsHiddenProperties: false,
-    showDockToRight: false
+    showDockToRight: false,
+    useSpectrum: true
 }
 
 var Capabilities = {
diff --git a/Source/WebCore/inspector/front-end/Spectrum.js b/Source/WebCore/inspector/front-end/Spectrum.js
new file mode 100644 (file)
index 0000000..27fc75a
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2011 Brian Grinstead All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.Spectrum = function(container)
+{
+    this._popover = new WebInspector.Popover();
+    this._popover.element.addEventListener("mousedown", stopPropagation, false);
+
+    this._containerElement = document.createElement('div');
+    this._containerElement.className = "spectrum-container";
+
+    var topElement = this._containerElement.createChild("div", "spectrum-top");
+    topElement.createChild("div", "spectrum-fill");
+
+    var topInnerElement = topElement.createChild("div", "spectrum-top-inner fill");
+    this._draggerElement = topInnerElement.createChild("div", "spectrum-color");
+    this._dragHelperElement = this._draggerElement.createChild("div", "spectrum-sat fill").createChild("div", "spectrum-val fill").createChild("div", "spectrum-dragger");
+
+    this._sliderElement = topInnerElement.createChild("div", "spectrum-hue");
+    this.slideHelper = this._sliderElement.createChild("div", "spectrum-slider");
+
+    var rangeContainer = this._containerElement.createChild("div", "spectrum-range-container");
+    var alphaLabel = rangeContainer.createChild("label");
+    alphaLabel.textContent = WebInspector.UIString("alpha: ");
+
+    this._alphaElement = rangeContainer.createChild("input", "spectrum-range");
+    this._alphaElement.setAttribute("type", "range");
+    this._alphaElement.setAttribute("min", "0");
+    this._alphaElement.setAttribute("max", "100");
+    this._alphaElement.addEventListener("change", alphaDrag.bind(this), false);
+
+    var swatchElement = document.createElement("span");
+    swatchElement.className = "swatch";
+    this._swatchInnerElement = swatchElement.createChild("span", "swatch-inner");
+
+    var displayContainer = rangeContainer.createChild("div");
+
+    var colorLabel = displayContainer.createChild("label");
+    colorLabel.textContent = WebInspector.UIString("color: ");
+
+    displayContainer.appendChild(swatchElement);
+
+    this._displayElement = displayContainer.createChild("span");
+
+    WebInspector.Spectrum.draggable(this._sliderElement, hueDrag.bind(this));
+    WebInspector.Spectrum.draggable(this._draggerElement, colorDrag.bind(this));
+
+    function hueDrag(element, dragX, dragY)
+    {
+        this.hsv[0] = (dragY / this.slideHeight);
+
+        this._onchange();
+    }
+
+    function colorDrag(element, dragX, dragY)
+    {
+        this.hsv[1] = dragX / this.dragWidth;
+        this.hsv[2] = (this.dragHeight - dragY) / this.dragHeight;
+
+        this._onchange();
+    }
+
+    function alphaDrag()
+    {
+        this.hsv[3] = this._alphaElement.value / 100;
+
+        this._onchange();
+    }
+
+    this._hideProxy = this.hide.bind(this);
+};
+
+WebInspector.Spectrum.Events = {
+    ColorChanged: "ColorChanged",
+    Hidden: "Hidden"
+};
+
+WebInspector.Spectrum.hsvaToRGBA = function(h, s, v, a)
+{
+    var r, g, b;
+
+    var i = Math.floor(h * 6);
+    var f = h * 6 - i;
+    var p = v * (1 - s);
+    var q = v * (1 - f * s);
+    var t = v * (1 - (1 - f) * s);
+
+    switch(i % 6) {
+    case 0:
+        r = v, g = t, b = p;
+        break;
+    case 1:
+        r = q, g = v, b = p;
+        break;
+    case 2:
+        r = p, g = v, b = t;
+        break;
+    case 3:
+        r = p, g = q, b = v;
+        break;
+    case 4:
+        r = t, g = p, b = v;
+        break;
+    case 5:
+        r = v, g = p, b = q;
+        break;
+    }
+
+    return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a];
+};
+
+WebInspector.Spectrum.rgbaToHSVA = function(r, g, b, a)
+{
+    r = r / 255;
+    g = g / 255;
+    b = b / 255;
+    
+    var max = Math.max(r, g, b);
+    var min = Math.min(r, g, b);
+    var h;
+    var s;
+    var v = max;
+
+    var d = max - min;
+    s = max ? d / max : 0;
+
+    if(max === min) {
+        // Achromatic.
+        h = 0;
+    } else {
+        switch(max) {
+        case r:
+            h = (g - b) / d + (g < b ? 6 : 0);
+            break;
+        case g:
+            h = (b - r) / d + 2;
+            break;
+        case b:
+            h = (r - g) / d + 4;
+            break;
+        }
+        h /= 6;
+    }
+    return [h, s, v, a];
+};
+
+//FIXME: migrate to WebInspector.elementDragStart
+WebInspector.Spectrum.draggable = function(element, onmove, onstart, onstop) {
+
+    var doc = document;
+    var dragging;
+    var offset;
+    var scrollOffset;
+    var maxHeight;
+    var maxWidth;
+
+    function prevent(e)
+    {
+        if (e.stopPropagation)
+            e.stopPropagation();
+
+        if (e.preventDefault)
+            e.preventDefault();
+    }
+
+    function move(e)
+    {
+        if (dragging) {
+            var dragX = Math.max(0, Math.min(e.pageX - offset.left + scrollOffset.left, maxWidth));
+            var dragY = Math.max(0, Math.min(e.pageY - offset.top + scrollOffset.top, maxHeight));
+
+            if (onmove)
+                onmove(element, dragX, dragY);
+        }
+    }
+
+    function start(e)
+    {
+        var rightClick = e.which ? (e.which === 3) : (e.button === 2);
+
+        if (!rightClick && !dragging) {
+
+            if (onstart)
+                onstart(element, e)
+
+            dragging = true;
+            maxHeight = element.clientHeight;
+            maxWidth = element.clientWidth;
+
+            scrollOffset = element.scrollOffset();
+            offset = element.totalOffset();
+
+            doc.addEventListener("selectstart", prevent, false);
+            doc.addEventListener("dragstart", prevent, false);
+            doc.addEventListener("mousemove", move, false);
+            doc.addEventListener("mouseup", stop, false);
+
+            move(e);
+            prevent(e);
+        }
+    }
+
+    function stop(e)
+    {
+        if (dragging) {
+            doc.removeEventListener("selectstart", prevent, false);
+            doc.removeEventListener("dragstart", prevent, false);
+            doc.removeEventListener("mousemove", move, false);
+            doc.removeEventListener("mouseup", stop, false);
+
+            if (onstop)
+                onstop(element, e);
+        }
+
+        dragging = false;
+    }
+
+    element.addEventListener("mousedown", start, false);
+};
+
+WebInspector.Spectrum.prototype = {
+    set color(color)
+    {
+        var rgba = (color.rgba || color.rgb).slice(0);
+        
+        if (rgba.length === 3)
+            rgba[3] = 1;
+        
+        this.hsv = WebInspector.Spectrum.rgbaToHSVA(rgba[0], rgba[1], rgba[2], rgba[3]);
+    },
+
+    get color()
+    {
+        var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], this.hsv[1], this.hsv[2], this.hsv[3]);
+        var color;
+
+        if (rgba[3] === 1)
+            color = WebInspector.Color.fromRGB(rgba[0], rgba[1], rgba[2]);
+        else
+            color = WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
+
+        var colorValue = color.toString(this.outputColorFormat);
+        if (!colorValue)
+            colorValue = color.toString(); // this.outputColorFormat can be invalid for current color (e.g. "nickname").
+        return new WebInspector.Color(colorValue);
+    },
+
+    get outputColorFormat()
+    {
+        var cf = WebInspector.StylesSidebarPane.ColorFormat;
+        var format = this._originalFormat;
+
+        if (this.hsv[3] === 1) {
+            // Simplify transparent formats.
+            if (format === cf.RGBA)
+                format = cf.RGB;
+            else if (format === cf.HSLA)
+                format = cf.HSL;
+        } else {
+            // Everything except HSL(A) should be returned as RGBA if transparency is involved.
+            if (format === cf.HSL || format === cf.HSLA)
+                format = cf.HSLA;
+            else
+                format = cf.RGBA;
+        }
+
+        return format;
+    },
+
+    get colorHueOnly()
+    {
+        var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], 1, 1, 1);
+        return WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
+    },
+
+    set displayText(text)
+    {
+        this._displayElement.textContent = text;
+    },
+
+    _onchange: function()
+    {
+        this._updateUI();
+        this.dispatchEventToListeners(WebInspector.Spectrum.Events.ColorChanged, this.color);
+    },
+
+    _updateHelperLocations: function()
+    {
+        var h = this.hsv[0];
+        var s = this.hsv[1];
+        var v = this.hsv[2];
+
+        // Where to show the little circle that displays your current selected color.
+        var dragX = s * this.dragWidth;
+        var dragY = this.dragHeight - (v * this.dragHeight);
+
+        dragX = Math.max(-this._dragHelperElementHeight,
+                        Math.min(this.dragWidth - this._dragHelperElementHeight, dragX - this._dragHelperElementHeight));
+        dragY = Math.max(-this._dragHelperElementHeight,
+                        Math.min(this.dragHeight - this._dragHelperElementHeight, dragY - this._dragHelperElementHeight));
+
+        this._dragHelperElement.positionAt(dragX, dragY);
+
+        // Where to show the bar that displays your current selected hue.
+        var slideY = (h * this.slideHeight) - this.slideHelperHeight;
+        this.slideHelper.style.top = slideY + "px";
+
+        this._alphaElement.value = this.hsv[3] * 100;
+    },
+
+    _updateUI: function()
+    {
+        this._updateHelperLocations();
+
+        var rgb = (this.color.rgba || this.color.rgb).slice(0);
+
+        if (rgb.length === 3)
+            rgb[3] = 1;
+
+        var rgbHueOnly = this.colorHueOnly.rgb;
+
+        var flatColor = "rgb(" + rgbHueOnly[0] + ", " + rgbHueOnly[1] + ", " + rgbHueOnly[2] + ")";
+        var fullColor = "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " + rgb[3] + ")";
+
+        this._draggerElement.style.backgroundColor = flatColor;
+        this._swatchInnerElement.style.backgroundColor = fullColor;
+
+        this._alphaElement.value = this.hsv[3] * 100;
+    },
+
+    toggle: function(element, color, format)
+    {
+        if (this._isShown)
+            this.hide();
+        else
+            this.show(element, color, format);
+
+        return this._isShown;
+    },
+
+    show: function(element, color, format)
+    {
+        if (this._isShown)
+            return;
+
+        this._isShown = true;
+        this.reposition(element);
+
+        document.addEventListener("mousedown", this._hideProxy);
+        window.addEventListener("blur", this._hideProxy);
+
+        this.slideHeight = this._sliderElement.offsetHeight;
+        this.dragWidth = this._draggerElement.offsetWidth;
+        this.dragHeight = this._draggerElement.offsetHeight;
+        this._dragHelperElementHeight = this._dragHelperElement.offsetHeight / 2;
+        this.slideHelperHeight = this.slideHelper.offsetHeight / 2;
+
+        this.color = color;
+        this._originalFormat = format || color.format;
+
+        this._updateUI();
+    },
+
+    reposition: function(element)
+    {
+        this._popover.show(this._containerElement, element);
+    },
+
+    hide: function()
+    {
+        delete this._isShown;
+        this._popover.hide();
+
+        document.removeEventListener("mousedown", this._hideProxy);
+        window.removeEventListener("blur", this._hideProxy);
+
+        this.dispatchEventToListeners(WebInspector.Spectrum.Events.Hidden);
+
+        // Only want to allow one instance to be open at a time, so clear out any
+        // existing event listeners.
+        this.removeAllListeners();
+    }
+};
+
+WebInspector.Spectrum.prototype.__proto__ = WebInspector.Object.prototype;
index e18d545..3455760 100644 (file)
@@ -90,6 +90,9 @@ WebInspector.StylesSidebarPane = function(computedStylePane)
     this._sectionsContainer = document.createElement("div");
     this.bodyElement.appendChild(this._sectionsContainer);
 
+    if (Preferences.useSpectrum)
+        this._spectrum = new WebInspector.Spectrum();
+
     WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetOrMediaQueryResultChanged, this);
     WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this._styleSheetOrMediaQueryResultChanged, this);
     WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributesModified, this);
@@ -1666,28 +1669,95 @@ WebInspector.StylePropertyTreeElement.prototype = {
                     return document.createTextNode(text);
                 }
 
+                var format = getFormat();
+                var hasColorpicker = self._parentPane;
+                var spectrum = hasColorpicker ? self._parentPane._spectrum : null;
+
                 var swatchElement = document.createElement("span");
-                swatchElement.title = WebInspector.UIString("Click to change color format");
-                swatchElement.className = "swatch";
-                swatchElement.style.setProperty("background-color", text);
-
-                swatchElement.addEventListener("click", changeColorDisplay, false);
-                swatchElement.addEventListener("dblclick", function(event) { event.stopPropagation() }, false);
-
-                var format;
-                var formatSetting = WebInspector.settings.colorFormat.get();
-                if (formatSetting === cf.Original)
-                    format = cf.Original;
-                else if (color.nickname)
-                    format = cf.Nickname;
-                else if (formatSetting === cf.RGB)
-                    format = (color.simple ? cf.RGB : cf.RGBA);
-                else if (formatSetting === cf.HSL)
-                    format = (color.simple ? cf.HSL : cf.HSLA);
-                else if (color.simple)
-                    format = (color.hasShortHex() ? cf.ShortHEX : cf.HEX);
+                var swatchInnerElement = swatchElement.createChild("span", "swatch-inner");
+                if (hasColorpicker)
+                    swatchElement.title = WebInspector.UIString("Click to open a colorpicker");
                 else
-                    format = cf.RGBA;
+                    swatchElement.title = WebInspector.UIString("Click to change color format");
+
+                swatchElement.className = "swatch";
+
+                swatchElement.addEventListener("mousedown", stopPropagation, false);
+                swatchElement.addEventListener("click", swatchClick, false);
+                swatchElement.addEventListener("dblclick", stopPropagation, false);
+
+                swatchInnerElement.style.backgroundColor = text;
+
+                var scrollerElement = hasColorpicker ? self._parentPane._computedStylePane.element.parentElement : null;
+
+                function spectrumChange(e)
+                {
+                    color = e.data;
+
+                    var colorString = color.toString();
+
+                    colorValueElement.textContent = colorString;
+                    spectrum.displayText = colorString;
+                    swatchInnerElement.style.backgroundColor = colorString;
+
+                    self.applyStyleText(nameElement.textContent + ": " + valueElement.textContent, false, false, false);
+                }
+
+                function spectrumHide()
+                {
+                    scrollerElement.removeEventListener("scroll", repositionSpectrum, false);
+                    self.applyStyleText(nameElement.textContent + ": " + valueElement.textContent, true, true, false);
+                    spectrum.removeEventListener(WebInspector.Spectrum.Events.ColorChanged, spectrumChange);
+                    spectrum.removeEventListener(WebInspector.Spectrum.Events.Hidden, spectrumHide);
+
+                    delete self._parentPane._isEditingStyle;
+                }
+
+                function repositionSpectrum()
+                {
+                    spectrum.reposition(swatchElement);
+                }
+
+                function swatchClick(e)
+                {
+                    // Alt + click toggles color formats.
+                    // Click opens colorpicker, only if the element is not in computed styles section.
+
+                    if (!spectrum || e.altKey)
+                        changeColorDisplay(e);
+                    else if (hasColorpicker) {
+                        var isShown = spectrum.toggle(swatchElement, color, format);
+
+                        if (isShown) {
+                            spectrum.displayText = color.toString(format);
+                            self._parentPane._isEditingStyle = true;
+                            spectrum.addEventListener(WebInspector.Spectrum.Events.ColorChanged, spectrumChange);
+                            spectrum.addEventListener(WebInspector.Spectrum.Events.Hidden, spectrumHide);
+
+                            scrollerElement.addEventListener("scroll", repositionSpectrum, false);
+                        }
+                    }
+                }
+
+                function getFormat()
+                {
+                    var format;
+                    var formatSetting = WebInspector.settings.colorFormat.get();
+                    if (formatSetting === cf.Original)
+                        format = cf.Original;
+                    else if (color.nickname)
+                        format = cf.Nickname;
+                    else if (formatSetting === cf.RGB)
+                        format = (color.simple ? cf.RGB : cf.RGBA);
+                    else if (formatSetting === cf.HSL)
+                        format = (color.simple ? cf.HSL : cf.HSLA);
+                    else if (color.simple)
+                        format = (color.hasShortHex() ? cf.ShortHEX : cf.HEX);
+                    else
+                        format = cf.RGBA;
+
+                    return format;
+                }
 
                 var colorValueElement = document.createElement("span");
                 colorValueElement.textContent = color.toString(format);
index 7dd08cb..a87c633 100644 (file)
     <file>SourceHTMLTokenizer.js</file>
     <file>SourceJavaScriptTokenizer.js</file>
     <file>SourceTokenizer.js</file>
+    <file>Spectrum.js</file>
     <file>SplitView.js</file>
     <file>StatusBarButton.js</file>
     <file>StylesSidebarPane.js</file>
index 70f0e13..1bb8abd 100644 (file)
@@ -1445,6 +1445,13 @@ li.editing .swatch, li.editing .enabled-button,  li.editing-sub-part .delete-but
     width: 1em;
     height: 1em;
     border: 1px solid rgba(128, 128, 128, 0.6);
+    background-image: url(Images/checker.png);
+}
+
+.swatch-inner {
+    width: 100%;
+    height: 100%;
+    display: block;
 }
 
 .swatch:hover {
@@ -2645,3 +2652,102 @@ body.platform-mac #drawer-status-bar .search-status-bar-progress {
     border-color: transparent;
     border-width: 0 0 11px 0;
 }
+
+/* https://github.com/bgrins/spectrum */
+.spectrum-container {
+    position: absolute;
+    top: 0;
+    left: 0;
+    display: inline-block;
+    background: rgba(230, 230, 230, 1) !important;
+    border: 1px solid #646464;
+    padding: 10px;
+    width: 200px;
+    z-index: 10;
+    -webkit-user-select: none;
+}
+
+.spectrum-top {
+    position: relative;
+    width: 100%;
+    display: inline-block;
+}
+
+.spectrum-color {
+    position: absolute;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 20%;
+}
+
+.spectrum-hue {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 83%;
+}
+
+.spectrum-fill {
+    /* Same as spectrum-color width to force aspect ratio. */
+    margin-top: 80%;
+}
+
+.spectrum-range-container {
+    position: relative;
+    padding-top: 10px;
+}
+
+.spectrum-range-container * {
+    font-size: 9px;
+    vertical-align: middle;
+}
+
+.spectrum-range-container label {
+    width: 32px;
+    display: inline-block;
+}
+
+.spectrum-range-container input {
+    width: 130px;
+}
+
+.swatch, .spectrum-dragger, .spectrum-slider {
+    -webkit-user-select: none;
+}
+
+.spectrum-sat {
+    background-image: -webkit-linear-gradient(left, white, rgba(204, 154, 129, 0));
+}
+
+.spectrum-val {
+    background-image: -webkit-linear-gradient(bottom, black, rgba(204, 154, 129, 0));
+}
+
+.spectrum-hue {
+    background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
+}
+
+.spectrum-dragger {
+    border-radius: 5px;
+    height: 5px;
+    width: 5px;
+    border: 1px solid white;
+    cursor: pointer;
+    position: absolute;
+    top: 0;
+    left: 0;
+    background: black;
+}
+
+.spectrum-slider {
+    position: absolute;
+    top: 0;
+    cursor: pointer;
+    height: 5px;
+    width: 110%;
+    margin-left: -5%;
+    background: white;
+    opacity: .8;
+}
index d82f9cc..94f7c80 100644 (file)
@@ -83,6 +83,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     <script type="text/javascript" src="ApplicationCacheItemsView.js"></script>
     <script type="text/javascript" src="IndexedDBModel.js"></script>
     <script type="text/javascript" src="Script.js"></script>
+    <script type="text/javascript" src="Spectrum.js"></script>
     <script type="text/javascript" src="SidebarPane.js"></script>
     <script type="text/javascript" src="ElementsTreeOutline.js"></script>
     <script type="text/javascript" src="DOMPresentationUtils.js"></script>