Log Message
Web Inspector: color picker should feature an editable CSS value https://bugs.webkit.org/show_bug.cgi?id=124356
Patch by Devin Rousso <[email protected]> on 2017-01-23 Reviewed by Timothy Hatcher. * UserInterface/Views/ColorPicker.css: (.color-picker): (.color-picker.hide-inputs): (.color-picker > .color-inputs): (.color-picker > .color-inputs > div): (.color-picker > .color-inputs > div[hidden]): (.color-picker > .color-inputs input): * UserInterface/Views/ColorPicker.js: (WebInspector.ColorPicker.createColorInput): (WebInspector.ColorPicker): (WebInspector.ColorPicker.prototype.set color): (WebInspector.ColorPicker.prototype.set enableColorComponentInputs): (WebInspector.ColorPicker.prototype._updateColor): (WebInspector.ColorPicker.prototype._handleFormatChange): (WebInspector.ColorPicker.prototype._showColorComponentInputs.updateColorInput): (WebInspector.ColorPicker.prototype._showColorComponentInputs): (WebInspector.ColorPicker.prototype._handleColorInputInput): Add an input element (with a label for the component name and its units) for each component as part of the current color format (e.g. R, G, B, A). If any of these inputs are changed then the color is also changed and the "ColorChanged" event is fired. * UserInterface/Controllers/CodeMirrorColorEditingController.js: (WebInspector.CodeMirrorColorEditingController.prototype.popoverWillPresent): * UserInterface/Views/InlineSwatch.js: (WebInspector.InlineSwatch.prototype._swatchElementClicked): Add FormatChanged event that fires whenever a new color is set with a different format or the color value is set for the first time (there is no old format to compare to). This is needed because if the format becomes RGB, RGBA, HSL, or HSLA from something not in that list then the size of the containing popover needs to change since the newly added color inputs will be displayed. * UserInterface/Views/GradientEditor.js: (WebInspector.GradientEditor): Prevent the color inputs from displaying at all, since there aren't individual swatches for each color in a gradient.
Modified Paths
- trunk/Source/WebInspectorUI/ChangeLog
- trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorColorEditingController.js
- trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.css
- trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js
- trunk/Source/WebInspectorUI/UserInterface/Views/GradientEditor.js
- trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js
Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (211056 => 211057)
--- trunk/Source/WebInspectorUI/ChangeLog 2017-01-23 21:22:13 UTC (rev 211056)
+++ trunk/Source/WebInspectorUI/ChangeLog 2017-01-23 21:27:26 UTC (rev 211057)
@@ -1,3 +1,47 @@
+2017-01-23 Devin Rousso <[email protected]>
+
+ Web Inspector: color picker should feature an editable CSS value
+ https://bugs.webkit.org/show_bug.cgi?id=124356
+
+ Reviewed by Timothy Hatcher.
+
+ * UserInterface/Views/ColorPicker.css:
+ (.color-picker):
+ (.color-picker.hide-inputs):
+ (.color-picker > .color-inputs):
+ (.color-picker > .color-inputs > div):
+ (.color-picker > .color-inputs > div[hidden]):
+ (.color-picker > .color-inputs input):
+
+ * UserInterface/Views/ColorPicker.js:
+ (WebInspector.ColorPicker.createColorInput):
+ (WebInspector.ColorPicker):
+ (WebInspector.ColorPicker.prototype.set color):
+ (WebInspector.ColorPicker.prototype.set enableColorComponentInputs):
+ (WebInspector.ColorPicker.prototype._updateColor):
+ (WebInspector.ColorPicker.prototype._handleFormatChange):
+ (WebInspector.ColorPicker.prototype._showColorComponentInputs.updateColorInput):
+ (WebInspector.ColorPicker.prototype._showColorComponentInputs):
+ (WebInspector.ColorPicker.prototype._handleColorInputInput):
+ Add an input element (with a label for the component name and its units) for each component
+ as part of the current color format (e.g. R, G, B, A). If any of these inputs are changed
+ then the color is also changed and the "ColorChanged" event is fired.
+
+ * UserInterface/Controllers/CodeMirrorColorEditingController.js:
+ (WebInspector.CodeMirrorColorEditingController.prototype.popoverWillPresent):
+ * UserInterface/Views/InlineSwatch.js:
+ (WebInspector.InlineSwatch.prototype._swatchElementClicked):
+ Add FormatChanged event that fires whenever a new color is set with a different format or
+ the color value is set for the first time (there is no old format to compare to). This is
+ needed because if the format becomes RGB, RGBA, HSL, or HSLA from something not in that list
+ then the size of the containing popover needs to change since the newly added color inputs
+ will be displayed.
+
+ * UserInterface/Views/GradientEditor.js:
+ (WebInspector.GradientEditor):
+ Prevent the color inputs from displaying at all, since there aren't individual swatches for
+ each color in a gradient.
+
2017-01-20 Devin Rousso <[email protected]>
Web Inspector: Search Tab should display search results immediately when closing and reopening Inspector
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorColorEditingController.js (211056 => 211057)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorColorEditingController.js 2017-01-23 21:22:13 UTC (rev 211056)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorColorEditingController.js 2017-01-23 21:27:26 UTC (rev 211057)
@@ -46,6 +46,7 @@
{
this._colorPicker = new WebInspector.ColorPicker;
this._colorPicker.addEventListener(WebInspector.ColorPicker.Event.ColorChanged, this._colorPickerColorChanged, this);
+ this._colorPicker.addEventListener(WebInspector.ColorPicker.Event.FormatChanged, (event) => popover.update());
popover.content = this._colorPicker.element;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.css (211056 => 211057)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.css 2017-01-23 21:22:13 UTC (rev 211056)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.css 2017-01-23 21:27:26 UTC (rev 211057)
@@ -26,10 +26,14 @@
.color-picker {
position: relative;
width: 256px;
- height: 210px;
+ height: 236px;
padding: 5px;
}
+.color-picker.hide-inputs {
+ height: 210px;
+}
+
.color-picker > * {
position: absolute;
}
@@ -53,3 +57,27 @@
.color-picker > .opacity {
left: 238px;
}
+
+.color-picker > .color-inputs {
+ display: flex;
+ justify-content: space-between;
+ top: 212px;
+ right: 0;
+ left: 0;
+}
+
+.color-picker > .color-inputs > div {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ margin: 0 4px;
+}
+
+.color-picker > .color-inputs > div[hidden] {
+ display: none;
+}
+
+.color-picker > .color-inputs input {
+ width: 100%;
+ margin: 0 0.25em;
+}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js (211056 => 211057)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js 2017-01-23 21:22:13 UTC (rev 211056)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js 2017-01-23 21:27:26 UTC (rev 211057)
@@ -41,19 +41,53 @@
this._opacitySlider.delegate = this;
this._opacitySlider.element.classList.add("opacity");
+ let colorInputsContainerElement = document.createElement("div");
+ colorInputsContainerElement.classList.add("color-inputs");
+
+ function createColorInput(label, {min: min = 0, max: max = 100, step: step = 1, units} = {}) {
+ let containerElement = colorInputsContainerElement.createChild("div");
+
+ containerElement.append(label);
+
+ let numberInputElement = containerElement.createChild("input");
+ numberInputElement.type = "number";
+ numberInputElement.min = min;
+ numberInputElement.max = max;
+ numberInputElement.step = step;
+ numberInputElement.addEventListener("input", this._handleColorInputInput.bind(this));
+
+ if (units && units.length)
+ containerElement.append(units);
+
+ return {containerElement, numberInputElement};
+ }
+
+ this._colorInputs = new Map([
+ ["R", createColorInput.call(this, "R", {max: 255})],
+ ["G", createColorInput.call(this, "G", {max: 255})],
+ ["B", createColorInput.call(this, "B", {max: 255})],
+ ["H", createColorInput.call(this, "H", {max: 360})],
+ ["S", createColorInput.call(this, "S", {units: "%"})],
+ ["L", createColorInput.call(this, "L", {units: "%"})],
+ ["A", createColorInput.call(this, "A"), {max: 1, step: 0.01}]
+ ]);
+
this._element = document.createElement("div");
- this._element.className = "color-picker";
+ this._element.classList.add("color-picker");
this._element.appendChild(this._colorWheel.element);
this._element.appendChild(this._brightnessSlider.element);
this._element.appendChild(this._opacitySlider.element);
+ this._element.appendChild(colorInputsContainerElement);
this._opacity = 0;
this._opacityPattern = "url(Images/Checkers.svg)";
- this._color = "white";
+ this._color = WebInspector.Color.fromString("white");
this._dontUpdateColor = false;
+
+ this._enableColorComponentInputs = true;
}
// Public
@@ -95,19 +129,35 @@
set color(color)
{
+ console.assert(color instanceof WebInspector.Color);
+
this._dontUpdateColor = true;
- this._colorFormat = color.format;
+ let formatChanged = !this._color || this._color.format !== color.format;
- this._colorWheel.tintedColor = color;
+ this._color = color;
+
+ this._colorWheel.tintedColor = this._color;
this._brightnessSlider.value = this._colorWheel.brightness;
- this._opacitySlider.value = color.alpha;
- this._updateSliders(this._colorWheel.rawColor, color);
+ this._opacitySlider.value = this._color.alpha;
+ this._updateSliders(this._colorWheel.rawColor, this._color);
+ this._showColorComponentInputs();
+
+ if (formatChanged)
+ this._handleFormatChange();
+
this._dontUpdateColor = false;
}
+ set enableColorComponentInputs(value)
+ {
+ this._enableColorComponentInputs = value;
+
+ this._showColorComponentInputs();
+ }
+
colorWheelColorDidChange(colorWheel)
{
this._updateColor();
@@ -129,16 +179,30 @@
if (this._dontUpdateColor)
return;
- var opacity = Math.round(this._opacity * 100) / 100;
+ let opacity = Math.round(this._opacity * 100) / 100;
- var components;
- if (this._colorFormat === WebInspector.Color.Format.HSL || this._colorFormat === WebInspector.Color.Format.HSLA)
+ let format = this._color.format;
+ let components = null;
+ if (format === WebInspector.Color.Format.HSL || format === WebInspector.Color.Format.HSLA) {
components = this._colorWheel.tintedColor.hsl.concat(opacity);
- else
+ if (opacity !== 1)
+ format = WebInspector.Color.Format.HSLA;
+ } else {
components = this._colorWheel.tintedColor.rgb.concat(opacity);
+ if (opacity !== 1 && format === WebInspector.Color.Format.RGB)
+ format = WebInspector.Color.Format.RGBA;
+ }
- this._color = new WebInspector.Color(this._colorFormat, components);
+ let formatChanged = this._color.format === format;
+
+ this._color = new WebInspector.Color(format, components);
+
+ this._showColorComponentInputs();
+
this.dispatchEventToListeners(WebInspector.ColorPicker.Event.ColorChanged, {color: this._color});
+
+ if (formatChanged)
+ this._handleFormatChange();
}
_updateSliders(rawColor, tintedColor)
@@ -150,8 +214,124 @@
this._opacitySlider.element.style.backgroundImage = "linear-gradient(90deg, " + transparent + ", " + opaque + "), " + this._opacityPattern;
this._brightnessSlider.element.style.backgroundImage = "linear-gradient(90deg, black, " + rawColor + ")";
}
+
+ _handleFormatChange()
+ {
+ this._element.classList.toggle("hide-inputs", this._color.format !== WebInspector.Color.Format.Keyword
+ && this._color.format !== WebInspector.Color.Format.RGB
+ && this._color.format !== WebInspector.Color.Format.RGBA
+ && this._color.format !== WebInspector.Color.Format.HEX
+ && this._color.format !== WebInspector.Color.Format.ShortHEX
+ && this._color.format !== WebInspector.Color.Format.HEXAlpha
+ && this._color.format !== WebInspector.Color.Format.ShortHEXAlpha
+ && this._color.format !== WebInspector.Color.Format.HSL
+ && this._color.format !== WebInspector.Color.Format.HSLA);
+
+ this.dispatchEventToListeners(WebInspector.ColorPicker.Event.FormatChanged);
+ }
+
+ _showColorComponentInputs()
+ {
+ for (let {containerElement} of this._colorInputs.values())
+ containerElement.hidden = true;
+
+ if (!this._enableColorComponentInputs)
+ return;
+
+ function updateColorInput(key, value) {
+ let {containerElement, numberInputElement} = this._colorInputs.get(key);
+ numberInputElement.value = value;
+ containerElement.hidden = false;
+ }
+
+ switch (this._color.format) {
+ case WebInspector.Color.Format.RGB:
+ case WebInspector.Color.Format.RGBA:
+ case WebInspector.Color.Format.HEX:
+ case WebInspector.Color.Format.ShortHEX:
+ case WebInspector.Color.Format.HEXAlpha:
+ case WebInspector.Color.Format.ShortHEXAlpha:
+ case WebInspector.Color.Format.Keyword:
+ var [r, g, b] = this._color.rgb;
+ updateColorInput.call(this, "R", r);
+ updateColorInput.call(this, "G", g);
+ updateColorInput.call(this, "B", b);
+ break;
+
+ case WebInspector.Color.Format.HSL:
+ case WebInspector.Color.Format.HSLA:
+ var [h, s, l] = this._color.hsl;
+ updateColorInput.call(this, "H", h);
+ updateColorInput.call(this, "S", s);
+ updateColorInput.call(this, "L", l);
+ break;
+
+ default:
+ return;
+ }
+
+ if ((this._color.format === WebInspector.Color.Format.Keyword && this._color.alpha !== 1)
+ || this._color.format === WebInspector.Color.Format.RGBA
+ || this._color.format === WebInspector.Color.Format.HSLA
+ || this._color.format === WebInspector.Color.Format.HEXAlpha
+ || this._color.format === WebInspector.Color.Format.ShortHEXAlpha) {
+ updateColorInput.call(this, "A", this._color.alpha);
+ }
+ }
+
+ _handleColorInputInput(event)
+ {
+ if (!this._enableColorComponentInputs) {
+ WebInspector.reportInternalError("Input event fired for disabled color component input");
+ return;
+ }
+
+ let r = this._colorInputs.get("R").numberInputElement.value;
+ let g = this._colorInputs.get("G").numberInputElement.value;
+ let b = this._colorInputs.get("B").numberInputElement.value;
+ let h = this._colorInputs.get("H").numberInputElement.value;
+ let s = this._colorInputs.get("S").numberInputElement.value;
+ let l = this._colorInputs.get("L").numberInputElement.value;
+ let a = this._colorInputs.get("A").numberInputElement.value;
+
+ let colorString = "";
+ let oldFormat = this._color.format;
+
+ switch (oldFormat) {
+ case WebInspector.Color.Format.RGB:
+ case WebInspector.Color.Format.HEX:
+ case WebInspector.Color.Format.ShortHEX:
+ case WebInspector.Color.Format.Keyword:
+ colorString = `rgb(${r}, ${g}, ${b})`;
+ break;
+
+ case WebInspector.Color.Format.RGBA:
+ case WebInspector.Color.Format.HEXAlpha:
+ case WebInspector.Color.Format.ShortHEXAlpha:
+ colorString = `rgba(${r}, ${g}, ${b}, ${a})`;
+ break;
+
+ case WebInspector.Color.Format.HSL:
+ colorString = `hsl(${h}, ${s}%, ${l}%)`;
+ break;
+
+ case WebInspector.Color.Format.HSLA:
+ colorString = `hsla(${h}, ${s}%, ${l}%, ${a})`;
+ break;
+
+ default:
+ WebInspector.reportInternalError(`Input event fired for invalid color format "${this._color.format}"`);
+ return;
+ }
+
+ this.color = WebInspector.Color.fromString(colorString);
+ this._color.format = oldFormat;
+
+ this.dispatchEventToListeners(WebInspector.ColorPicker.Event.ColorChanged, {color: this._color});
+ }
};
WebInspector.ColorPicker.Event = {
- ColorChanged: "css-color-picker-color-changed"
+ ColorChanged: "css-color-picker-color-changed",
+ FormatChanged: "css-color-picker-format-changed",
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/GradientEditor.js (211056 => 211057)
--- trunk/Source/WebInspectorUI/UserInterface/Views/GradientEditor.js 2017-01-23 21:22:13 UTC (rev 211056)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/GradientEditor.js 2017-01-23 21:27:26 UTC (rev 211057)
@@ -72,6 +72,7 @@
this._colorPicker = new WebInspector.ColorPicker;
this._colorPicker.colorWheel.dimension = 190;
+ this._colorPicker.enableColorComponentInputs = false;
this._colorPicker.addEventListener(WebInspector.ColorPicker.Event.ColorChanged, this._colorPickerColorChanged, this);
let angleLabel = this._element.appendChild(document.createElement("label"));
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js (211056 => 211057)
--- trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js 2017-01-23 21:22:13 UTC (rev 211056)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js 2017-01-23 21:27:26 UTC (rev 211057)
@@ -165,6 +165,7 @@
} else {
this._valueEditor = new WebInspector.ColorPicker;
this._valueEditor.addEventListener(WebInspector.ColorPicker.Event.ColorChanged, this._valueEditorValueDidChange, this);
+ this._valueEditor.addEventListener(WebInspector.ColorPicker.Event.FormatChanged, (event) => popover.update());
}
popover.content = this._valueEditor.element;
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
