| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2011 Brian Grinstead All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions | |
| 6 * are met: | |
| 7 * | |
| 8 * 1. Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | |
| 11 * notice, this list of conditions and the following disclaimer in the | |
| 12 * documentation and/or other materials provided with the distribution. | |
| 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of | |
| 14 * its contributors may be used to endorse or promote products derived | |
| 15 * from this software without specific prior written permission. | |
| 16 * | |
| 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | |
| 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | |
| 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
| 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 27 */ | |
| 28 | |
| 29 /** | |
| 30 * @constructor | |
| 31 * @extends {WebInspector.VBox} | |
| 32 */ | |
| 33 WebInspector.Spectrum = function() | |
| 34 { | |
| 35 /** | |
| 36 * @param {!Element} parentElement | |
| 37 */ | |
| 38 function appendSwitcherIcon(parentElement) | |
| 39 { | |
| 40 var icon = parentElement.createSVGChild("svg"); | |
| 41 icon.setAttribute("height", 16); | |
| 42 icon.setAttribute("width", 16); | |
| 43 var path = icon.createSVGChild("path"); | |
| 44 path.setAttribute("d", "M5,6 L11,6 L8,2 Z M5,10 L11,10 L8,14 Z"); | |
| 45 return icon; | |
| 46 } | |
| 47 | |
| 48 WebInspector.VBox.call(this, true); | |
| 49 this.registerRequiredCSS("elements/spectrum.css"); | |
| 50 this.contentElement.tabIndex = 0; | |
| 51 | |
| 52 this._colorElement = this.contentElement.createChild("div", "spectrum-color"
); | |
| 53 this._colorDragElement = this._colorElement.createChild("div", "spectrum-sat
fill").createChild("div", "spectrum-val fill").createChild("div", "spectrum-dra
gger"); | |
| 54 var contrastRatioSVG = this._colorElement.createSVGChild("svg", "spectrum-co
ntrast-container fill"); | |
| 55 this._contrastRatioLine = contrastRatioSVG.createSVGChild("path", "spectrum-
contrast-line"); | |
| 56 | |
| 57 var toolbar = new WebInspector.Toolbar("spectrum-eye-dropper", this.contentE
lement); | |
| 58 this._colorPickerButton = new WebInspector.ToolbarToggle(WebInspector.UIStri
ng("Toggle color picker"), "eyedropper-toolbar-item"); | |
| 59 this._colorPickerButton.setToggled(true); | |
| 60 this._colorPickerButton.addEventListener("click", this._toggleColorPicker.bi
nd(this, undefined)); | |
| 61 toolbar.appendToolbarItem(this._colorPickerButton); | |
| 62 | |
| 63 var swatchElement = this.contentElement.createChild("span", "swatch"); | |
| 64 this._swatchInnerElement = swatchElement.createChild("span", "swatch-inner")
; | |
| 65 | |
| 66 this._hueElement = this.contentElement.createChild("div", "spectrum-hue"); | |
| 67 this._hueSlider = this._hueElement.createChild("div", "spectrum-slider"); | |
| 68 this._alphaElement = this.contentElement.createChild("div", "spectrum-alpha"
); | |
| 69 this._alphaElementBackground = this._alphaElement.createChild("div", "spectr
um-alpha-background"); | |
| 70 this._alphaSlider = this._alphaElement.createChild("div", "spectrum-slider")
; | |
| 71 | |
| 72 var displaySwitcher = this.contentElement.createChild("div", "spectrum-displ
ay-switcher spectrum-switcher"); | |
| 73 appendSwitcherIcon(displaySwitcher); | |
| 74 displaySwitcher.addEventListener("click", this._formatViewSwitch.bind(this))
; | |
| 75 | |
| 76 // RGBA/HSLA display. | |
| 77 this._displayContainer = this.contentElement.createChild("div", "spectrum-te
xt source-code"); | |
| 78 this._textValues = []; | |
| 79 for (var i = 0; i < 4; ++i) { | |
| 80 var inputValue = this._displayContainer.createChild("input", "spectrum-t
ext-value"); | |
| 81 inputValue.maxLength = 4; | |
| 82 this._textValues.push(inputValue); | |
| 83 inputValue.addEventListener("keydown", this._inputChanged.bind(this), fa
lse); | |
| 84 inputValue.addEventListener("input", this._inputChanged.bind(this), fals
e); | |
| 85 inputValue.addEventListener("mousewheel", this._inputChanged.bind(this),
false); | |
| 86 } | |
| 87 | |
| 88 this._textLabels = this._displayContainer.createChild("div", "spectrum-text-
label"); | |
| 89 | |
| 90 // HEX display. | |
| 91 this._hexContainer = this.contentElement.createChild("div", "spectrum-text s
pectrum-text-hex source-code"); | |
| 92 this._hexValue = this._hexContainer.createChild("input", "spectrum-text-valu
e"); | |
| 93 this._hexValue.maxLength = 9; | |
| 94 this._hexValue.addEventListener("keydown", this._inputChanged.bind(this), fa
lse); | |
| 95 this._hexValue.addEventListener("input", this._inputChanged.bind(this), fals
e); | |
| 96 this._hexValue.addEventListener("mousewheel", this._inputChanged.bind(this),
false); | |
| 97 | |
| 98 var label = this._hexContainer.createChild("div", "spectrum-text-label"); | |
| 99 label.textContent = "HEX"; | |
| 100 | |
| 101 WebInspector.installDragHandle(this._hueElement, dragStart.bind(this, positi
onHue.bind(this)), positionHue.bind(this), null, "default"); | |
| 102 WebInspector.installDragHandle(this._alphaElement, dragStart.bind(this, posi
tionAlpha.bind(this)), positionAlpha.bind(this), null, "default"); | |
| 103 WebInspector.installDragHandle(this._colorElement, dragStart.bind(this, posi
tionColor.bind(this)), positionColor.bind(this), null, "default"); | |
| 104 | |
| 105 this.element.classList.add("palettes-enabled"); | |
| 106 /** @type {!Map.<string, !WebInspector.Spectrum.Palette>} */ | |
| 107 this._palettes = new Map(); | |
| 108 this._palettePanel = this.contentElement.createChild("div", "palette-panel")
; | |
| 109 this._palettePanelShowing = false; | |
| 110 this._paletteContainer = this.contentElement.createChild("div", "spectrum-pa
lette"); | |
| 111 this._paletteContainer.addEventListener("contextmenu", this._showPaletteColo
rContextMenu.bind(this, -1)); | |
| 112 this._shadesContainer = this.contentElement.createChild("div", "palette-colo
r-shades hidden"); | |
| 113 WebInspector.installDragHandle(this._paletteContainer, this._paletteDragStar
t.bind(this), this._paletteDrag.bind(this), this._paletteDragEnd.bind(this), "de
fault"); | |
| 114 var paletteSwitcher = this.contentElement.createChild("div", "spectrum-palet
te-switcher spectrum-switcher"); | |
| 115 appendSwitcherIcon(paletteSwitcher); | |
| 116 paletteSwitcher.addEventListener("click", this._togglePalettePanel.bind(this
, true)); | |
| 117 | |
| 118 this._deleteIconToolbar = new WebInspector.Toolbar("delete-color-toolbar"); | |
| 119 this._deleteButton = new WebInspector.ToolbarButton("", "garbage-collect-too
lbar-item"); | |
| 120 this._deleteIconToolbar.appendToolbarItem(this._deleteButton); | |
| 121 | |
| 122 var overlay = this.contentElement.createChild("div", "spectrum-overlay fill"
); | |
| 123 overlay.addEventListener("click", this._togglePalettePanel.bind(this, false)
); | |
| 124 | |
| 125 this._addColorToolbar = new WebInspector.Toolbar("add-color-toolbar"); | |
| 126 var addColorButton = new WebInspector.ToolbarButton(WebInspector.UIString("A
dd to palette"), "add-toolbar-item"); | |
| 127 addColorButton.addEventListener("click", this._addColorToCustomPalette.bind(
this)); | |
| 128 this._addColorToolbar.appendToolbarItem(addColorButton); | |
| 129 | |
| 130 this._loadPalettes(); | |
| 131 new WebInspector.Spectrum.PaletteGenerator(this._generatedPaletteLoaded.bind
(this)); | |
| 132 | |
| 133 /** | |
| 134 * @param {function(!Event)} callback | |
| 135 * @param {!Event} event | |
| 136 * @return {boolean} | |
| 137 * @this {WebInspector.Spectrum} | |
| 138 */ | |
| 139 function dragStart(callback, event) | |
| 140 { | |
| 141 this._hueAlphaLeft = this._hueElement.totalOffsetLeft(); | |
| 142 this._colorOffset = this._colorElement.totalOffset(); | |
| 143 callback(event); | |
| 144 return true; | |
| 145 } | |
| 146 | |
| 147 /** | |
| 148 * @param {!Event} event | |
| 149 * @this {WebInspector.Spectrum} | |
| 150 */ | |
| 151 function positionHue(event) | |
| 152 { | |
| 153 var hsva = this._hsv.slice(); | |
| 154 hsva[0] = Number.constrain(1 - (event.x - this._hueAlphaLeft) / this._hu
eAlphaWidth, 0, 1); | |
| 155 this._innerSetColor(hsva, "", undefined, WebInspector.Spectrum._ChangeS
ource.Other); | |
| 156 } | |
| 157 | |
| 158 /** | |
| 159 * @param {!Event} event | |
| 160 * @this {WebInspector.Spectrum} | |
| 161 */ | |
| 162 function positionAlpha(event) | |
| 163 { | |
| 164 var newAlpha = Math.round((event.x - this._hueAlphaLeft) / this._hueAlph
aWidth * 100) / 100; | |
| 165 var hsva = this._hsv.slice(); | |
| 166 hsva[3] = Number.constrain(newAlpha, 0, 1); | |
| 167 var colorFormat = undefined; | |
| 168 if (hsva[3] !== 1 && this._colorFormat === WebInspector.Color.Format.Nic
kname) | |
| 169 colorFormat = WebInspector.Color.Format.HEX; | |
| 170 this._innerSetColor(hsva, "", colorFormat, WebInspector.Spectrum._Change
Source.Other); | |
| 171 } | |
| 172 | |
| 173 /** | |
| 174 * @param {!Event} event | |
| 175 * @this {WebInspector.Spectrum} | |
| 176 */ | |
| 177 function positionColor(event) | |
| 178 { | |
| 179 var hsva = this._hsv.slice(); | |
| 180 hsva[1] = Number.constrain((event.x - this._colorOffset.left) / this.dra
gWidth, 0, 1); | |
| 181 hsva[2] = Number.constrain(1 - (event.y - this._colorOffset.top) / this.
dragHeight, 0, 1); | |
| 182 this._innerSetColor(hsva, "", undefined, WebInspector.Spectrum._ChangeS
ource.Other); | |
| 183 } | |
| 184 } | |
| 185 | |
| 186 WebInspector.Spectrum._ChangeSource = { | |
| 187 Input: "Input", | |
| 188 Model: "Model", | |
| 189 Other: "Other" | |
| 190 } | |
| 191 | |
| 192 WebInspector.Spectrum.Events = { | |
| 193 ColorChanged: "ColorChanged", | |
| 194 SizeChanged: "SizeChanged" | |
| 195 }; | |
| 196 | |
| 197 WebInspector.Spectrum._colorChipSize = 24; | |
| 198 WebInspector.Spectrum._itemsPerPaletteRow = 8; | |
| 199 | |
| 200 WebInspector.Spectrum.prototype = { | |
| 201 _updatePalettePanel: function() | |
| 202 { | |
| 203 this._palettePanel.removeChildren(); | |
| 204 var title = this._palettePanel.createChild("div", "palette-title"); | |
| 205 title.textContent = WebInspector.UIString("Color Palettes"); | |
| 206 var toolbar = new WebInspector.Toolbar("", this._palettePanel); | |
| 207 var closeButton = new WebInspector.ToolbarButton("Return to color picker
", "delete-toolbar-item"); | |
| 208 closeButton.addEventListener("click", this._togglePalettePanel.bind(this
, false)); | |
| 209 toolbar.appendToolbarItem(closeButton); | |
| 210 for (var palette of this._palettes.values()) | |
| 211 this._palettePanel.appendChild(this._createPreviewPaletteElement(pal
ette)); | |
| 212 }, | |
| 213 | |
| 214 /** | |
| 215 * @param {boolean} show | |
| 216 */ | |
| 217 _togglePalettePanel: function(show) | |
| 218 { | |
| 219 if (this._palettePanelShowing === show) | |
| 220 return; | |
| 221 if (show) | |
| 222 this._updatePalettePanel(); | |
| 223 this._focus(); | |
| 224 this._palettePanelShowing = show; | |
| 225 this.contentElement.classList.toggle("palette-panel-showing", show); | |
| 226 }, | |
| 227 | |
| 228 _focus: function() | |
| 229 { | |
| 230 if (this.isShowing() && WebInspector.currentFocusElement() !== this.cont
entElement) | |
| 231 WebInspector.setCurrentFocusElement(this.contentElement); | |
| 232 }, | |
| 233 | |
| 234 /** | |
| 235 * @param {string} colorText | |
| 236 * @param {number=} animationDelay | |
| 237 * @return {!Element} | |
| 238 */ | |
| 239 _createPaletteColor: function(colorText, animationDelay) | |
| 240 { | |
| 241 var element = createElementWithClass("div", "spectrum-palette-color"); | |
| 242 element.style.background = String.sprintf("linear-gradient(%s, %s), url(
Images/checker.png)", colorText, colorText); | |
| 243 if (animationDelay) | |
| 244 element.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 100, d
elay: animationDelay, fill: "backwards" }); | |
| 245 element.title = colorText; | |
| 246 return element; | |
| 247 }, | |
| 248 | |
| 249 /** | |
| 250 * @param {!WebInspector.Spectrum.Palette} palette | |
| 251 * @param {boolean} animate | |
| 252 * @param {!Event=} event | |
| 253 */ | |
| 254 _showPalette: function(palette, animate, event) | |
| 255 { | |
| 256 this._resizeForSelectedPalette(); | |
| 257 this._paletteContainer.removeChildren(); | |
| 258 for (var i = 0; i < palette.colors.length; i++) { | |
| 259 var animationDelay = animate ? i * 100 / palette.colors.length : 0; | |
| 260 var colorElement = this._createPaletteColor(palette.colors[i], anima
tionDelay); | |
| 261 colorElement.addEventListener("mousedown", this._paletteColorSelecte
d.bind(this, palette.colors[i], palette.matchUserFormat)); | |
| 262 if (palette.mutable) { | |
| 263 colorElement.__mutable = true; | |
| 264 colorElement.__color = palette.colors[i]; | |
| 265 colorElement.addEventListener("contextmenu", this._showPaletteCo
lorContextMenu.bind(this, i)); | |
| 266 } else if (palette === WebInspector.Spectrum.MaterialPalette) { | |
| 267 colorElement.classList.add("has-material-shades"); | |
| 268 var shadow = colorElement.createChild("div", "spectrum-palette-c
olor spectrum-palette-color-shadow"); | |
| 269 shadow.style.background = palette.colors[i]; | |
| 270 shadow = colorElement.createChild("div", "spectrum-palette-color
spectrum-palette-color-shadow"); | |
| 271 shadow.style.background = palette.colors[i]; | |
| 272 colorElement.title = WebInspector.UIString(palette.colors[i] + "
. Long-click to show alternate shades."); | |
| 273 new WebInspector.LongClickController(colorElement, this._showLig
htnessShades.bind(this, colorElement, palette.colors[i])); | |
| 274 } | |
| 275 this._paletteContainer.appendChild(colorElement); | |
| 276 } | |
| 277 this._paletteContainerMutable = palette.mutable; | |
| 278 | |
| 279 var numItems = palette.colors.length; | |
| 280 if (palette.mutable) | |
| 281 numItems++; | |
| 282 if (palette.mutable) { | |
| 283 this._paletteContainer.appendChild(this._addColorToolbar.element); | |
| 284 this._paletteContainer.appendChild(this._deleteIconToolbar.element); | |
| 285 } else { | |
| 286 this._addColorToolbar.element.remove(); | |
| 287 this._deleteIconToolbar.element.remove(); | |
| 288 } | |
| 289 | |
| 290 this._togglePalettePanel(false); | |
| 291 this._focus(); | |
| 292 }, | |
| 293 | |
| 294 /** | |
| 295 * @param {!Element} colorElement | |
| 296 * @param {string} colorText | |
| 297 * @param {!Event} event | |
| 298 */ | |
| 299 _showLightnessShades: function(colorElement, colorText, event) | |
| 300 { | |
| 301 /** | |
| 302 * @param {!Element} element | |
| 303 * @this {!WebInspector.Spectrum} | |
| 304 */ | |
| 305 function closeLightnessShades(element) | |
| 306 { | |
| 307 this._shadesContainer.classList.add("hidden"); | |
| 308 element.classList.remove("spectrum-shades-shown"); | |
| 309 this._shadesContainer.ownerDocument.removeEventListener("mousedown",
this._shadesCloseHandler, true); | |
| 310 delete this._shadesCloseHandler; | |
| 311 } | |
| 312 | |
| 313 if (this._shadesCloseHandler) | |
| 314 this._shadesCloseHandler(); | |
| 315 | |
| 316 this._shadesContainer.classList.remove("hidden"); | |
| 317 this._shadesContainer.removeChildren(); | |
| 318 this._shadesContainer.animate([{ transform: "scaleY(0)", opacity: "0" },
{ transform: "scaleY(1)", opacity: "1" }], { duration: 200, easing: "cubic-bezi
er(0.4, 0, 0.2, 1)" }); | |
| 319 this._shadesContainer.style.top = colorElement.offsetTop + colorElement.
parentElement.offsetTop + "px"; | |
| 320 this._shadesContainer.style.left = colorElement.offsetLeft + "px"; | |
| 321 colorElement.classList.add("spectrum-shades-shown"); | |
| 322 | |
| 323 var shades = WebInspector.Spectrum.MaterialPaletteShades[colorText]; | |
| 324 for (var i = shades.length - 1; i >= 0; i--) { | |
| 325 var shadeElement = this._createPaletteColor(shades[i], i * 200 / sha
des.length + 100); | |
| 326 shadeElement.addEventListener("mousedown", this._paletteColorSelecte
d.bind(this, shades[i], false)); | |
| 327 this._shadesContainer.appendChild(shadeElement); | |
| 328 } | |
| 329 | |
| 330 WebInspector.setCurrentFocusElement(this._shadesContainer); | |
| 331 this._shadesCloseHandler = closeLightnessShades.bind(this, colorElement)
; | |
| 332 this._shadesContainer.ownerDocument.addEventListener("mousedown", this._
shadesCloseHandler, true); | |
| 333 }, | |
| 334 | |
| 335 /** | |
| 336 * @param {!Event} e | |
| 337 * @return {number} | |
| 338 */ | |
| 339 _slotIndexForEvent: function(e) | |
| 340 { | |
| 341 var localX = e.pageX - this._paletteContainer.totalOffsetLeft(); | |
| 342 var localY = e.pageY - this._paletteContainer.totalOffsetTop(); | |
| 343 var col = Math.min(localX / WebInspector.Spectrum._colorChipSize | 0, We
bInspector.Spectrum._itemsPerPaletteRow - 1); | |
| 344 var row = (localY / WebInspector.Spectrum._colorChipSize) | 0; | |
| 345 return Math.min(row * WebInspector.Spectrum._itemsPerPaletteRow + col, t
his._customPaletteSetting.get().colors.length - 1); | |
| 346 }, | |
| 347 | |
| 348 /** | |
| 349 * @param {!Event} e | |
| 350 * @return {boolean} | |
| 351 */ | |
| 352 _isDraggingToBin: function(e) | |
| 353 { | |
| 354 return e.pageX > this._deleteIconToolbar.element.totalOffsetLeft(); | |
| 355 }, | |
| 356 | |
| 357 /** | |
| 358 * @param {!Event} e | |
| 359 * @return {boolean} | |
| 360 */ | |
| 361 _paletteDragStart: function(e) | |
| 362 { | |
| 363 var element = e.deepElementFromPoint(); | |
| 364 if (!element || !element.__mutable) | |
| 365 return false; | |
| 366 | |
| 367 var index = this._slotIndexForEvent(e); | |
| 368 this._dragElement = element; | |
| 369 this._dragHotSpotX = e.pageX - (index % WebInspector.Spectrum._itemsPerP
aletteRow) * WebInspector.Spectrum._colorChipSize; | |
| 370 this._dragHotSpotY = e.pageY - (index / WebInspector.Spectrum._itemsPerP
aletteRow | 0) * WebInspector.Spectrum._colorChipSize; | |
| 371 return true; | |
| 372 }, | |
| 373 | |
| 374 /** | |
| 375 * @param {!Event} e | |
| 376 */ | |
| 377 _paletteDrag: function(e) | |
| 378 { | |
| 379 if (e.pageX < this._paletteContainer.totalOffsetLeft() || e.pageY < this
._paletteContainer.totalOffsetTop()) | |
| 380 return; | |
| 381 var newIndex = this._slotIndexForEvent(e); | |
| 382 var offsetX = e.pageX - (newIndex % WebInspector.Spectrum._itemsPerPalet
teRow) * WebInspector.Spectrum._colorChipSize; | |
| 383 var offsetY = e.pageY - (newIndex / WebInspector.Spectrum._itemsPerPalet
teRow | 0) * WebInspector.Spectrum._colorChipSize; | |
| 384 | |
| 385 var isDeleting = this._isDraggingToBin(e); | |
| 386 this._deleteIconToolbar.element.classList.add("dragging"); | |
| 387 this._deleteIconToolbar.element.classList.toggle("delete-color-toolbar-a
ctive", isDeleting); | |
| 388 var dragElementTransform = "translateX(" + (offsetX - this._dragHotSpotX
) + "px) translateY(" + (offsetY - this._dragHotSpotY) + "px)"; | |
| 389 this._dragElement.style.transform = isDeleting ? dragElementTransform +
" scale(0.8)" : dragElementTransform; | |
| 390 var children = Array.prototype.slice.call(this._paletteContainer.childre
n); | |
| 391 var index = children.indexOf(this._dragElement); | |
| 392 /** @type {!Map.<!Element, {left: number, top: number}>} */ | |
| 393 var swatchOffsets = new Map(); | |
| 394 for (var swatch of children) | |
| 395 swatchOffsets.set(swatch, swatch.totalOffset()); | |
| 396 | |
| 397 if (index !== newIndex) | |
| 398 this._paletteContainer.insertBefore(this._dragElement, children[newI
ndex > index ? newIndex + 1 : newIndex]); | |
| 399 | |
| 400 for (var swatch of children) { | |
| 401 if (swatch === this._dragElement) | |
| 402 continue; | |
| 403 var before = swatchOffsets.get(swatch); | |
| 404 var after = swatch.totalOffset(); | |
| 405 if (before.left !== after.left || before.top !== after.top) { | |
| 406 swatch.animate([ | |
| 407 { transform: "translateX(" + (before.left - after.left) + "p
x) translateY(" + (before.top - after.top) + "px)" }, | |
| 408 { transform: "none" }], { duration: 100, easing: "cubic-bezi
er(0, 0, 0.2, 1)" }); | |
| 409 } | |
| 410 } | |
| 411 }, | |
| 412 | |
| 413 /** | |
| 414 * @param {!Event} e | |
| 415 */ | |
| 416 _paletteDragEnd: function(e) | |
| 417 { | |
| 418 if (this._isDraggingToBin(e)) | |
| 419 this._dragElement.remove(); | |
| 420 this._dragElement.style.removeProperty("transform"); | |
| 421 var children = this._paletteContainer.children; | |
| 422 var colors = []; | |
| 423 for (var i = 0; i < children.length; ++i) { | |
| 424 if (children[i].__color) | |
| 425 colors.push(children[i].__color); | |
| 426 } | |
| 427 var palette = this._customPaletteSetting.get(); | |
| 428 palette.colors = colors; | |
| 429 this._customPaletteSetting.set(palette); | |
| 430 this._showPalette(this._customPaletteSetting.get(), false); | |
| 431 | |
| 432 this._deleteIconToolbar.element.classList.remove("dragging"); | |
| 433 this._deleteIconToolbar.element.classList.remove("delete-color-toolbar-a
ctive"); | |
| 434 }, | |
| 435 | |
| 436 _loadPalettes: function() | |
| 437 { | |
| 438 this._palettes.set(WebInspector.Spectrum.MaterialPalette.title, WebInspe
ctor.Spectrum.MaterialPalette); | |
| 439 /** @type {!WebInspector.Spectrum.Palette} */ | |
| 440 var defaultCustomPalette = { title: "Custom", colors: [], mutable: true
}; | |
| 441 this._customPaletteSetting = WebInspector.settings.createSetting("custom
ColorPalette", defaultCustomPalette); | |
| 442 this._palettes.set(this._customPaletteSetting.get().title, this._customP
aletteSetting.get()); | |
| 443 | |
| 444 this._selectedColorPalette = WebInspector.settings.createSetting("select
edColorPalette", WebInspector.Spectrum.GeneratedPaletteTitle); | |
| 445 var palette = this._palettes.get(this._selectedColorPalette.get()); | |
| 446 if (palette) | |
| 447 this._showPalette(palette, true); | |
| 448 }, | |
| 449 | |
| 450 /** | |
| 451 * @param {!WebInspector.Spectrum.Palette} generatedPalette | |
| 452 */ | |
| 453 _generatedPaletteLoaded: function(generatedPalette) | |
| 454 { | |
| 455 if (generatedPalette.colors.length) | |
| 456 this._palettes.set(generatedPalette.title, generatedPalette); | |
| 457 if (this._selectedColorPalette.get() !== generatedPalette.title) { | |
| 458 return; | |
| 459 } else if (!generatedPalette.colors.length) { | |
| 460 this._paletteSelected(WebInspector.Spectrum.MaterialPalette); | |
| 461 return; | |
| 462 } | |
| 463 this._showPalette(generatedPalette, true); | |
| 464 }, | |
| 465 | |
| 466 /** | |
| 467 * @param {!WebInspector.Spectrum.Palette} palette | |
| 468 * @return {!Element} | |
| 469 */ | |
| 470 _createPreviewPaletteElement: function(palette) | |
| 471 { | |
| 472 var colorsPerPreviewRow = 5; | |
| 473 var previewElement = createElementWithClass("div", "palette-preview"); | |
| 474 var titleElement = previewElement.createChild("div", "palette-preview-ti
tle"); | |
| 475 titleElement.textContent = palette.title; | |
| 476 for (var i = 0; i < colorsPerPreviewRow && i < palette.colors.length; i+
+) | |
| 477 previewElement.appendChild(this._createPaletteColor(palette.colors[i
])); | |
| 478 for (; i < colorsPerPreviewRow; i++) | |
| 479 previewElement.createChild("div", "spectrum-palette-color empty-colo
r"); | |
| 480 previewElement.addEventListener("click", this._paletteSelected.bind(this
, palette)); | |
| 481 return previewElement; | |
| 482 }, | |
| 483 | |
| 484 /** | |
| 485 * @param {!WebInspector.Spectrum.Palette} palette | |
| 486 */ | |
| 487 _paletteSelected: function(palette) | |
| 488 { | |
| 489 this._selectedColorPalette.set(palette.title); | |
| 490 this._showPalette(palette, true); | |
| 491 }, | |
| 492 | |
| 493 _resizeForSelectedPalette: function() | |
| 494 { | |
| 495 var palette = this._palettes.get(this._selectedColorPalette.get()); | |
| 496 if (!palette) | |
| 497 return; | |
| 498 var numColors = palette.colors.length; | |
| 499 if (palette === this._customPaletteSetting.get()) | |
| 500 numColors++; | |
| 501 var rowsNeeded = Math.max(1, Math.ceil(numColors / WebInspector.Spectrum
._itemsPerPaletteRow)); | |
| 502 if (this._numPaletteRowsShown === rowsNeeded) | |
| 503 return; | |
| 504 this._numPaletteRowsShown = rowsNeeded; | |
| 505 var paletteColorHeight = 12; | |
| 506 var paletteMargin = 12; | |
| 507 var paletteTop = 235; | |
| 508 this.element.style.height = (paletteTop + paletteMargin + (paletteColorH
eight + paletteMargin) * rowsNeeded) + "px"; | |
| 509 this.dispatchEventToListeners(WebInspector.Spectrum.Events.SizeChanged); | |
| 510 }, | |
| 511 | |
| 512 /** | |
| 513 * @param {string} colorText | |
| 514 * @param {boolean} matchUserFormat | |
| 515 */ | |
| 516 _paletteColorSelected: function(colorText, matchUserFormat) | |
| 517 { | |
| 518 var color = WebInspector.Color.parse(colorText); | |
| 519 if (!color) | |
| 520 return; | |
| 521 this._innerSetColor(color.hsva(), colorText, matchUserFormat ? this._col
orFormat : color.format(), WebInspector.Spectrum._ChangeSource.Other); | |
| 522 }, | |
| 523 | |
| 524 _addColorToCustomPalette: function() | |
| 525 { | |
| 526 var palette = this._customPaletteSetting.get(); | |
| 527 palette.colors.push(this.colorString()); | |
| 528 this._customPaletteSetting.set(palette); | |
| 529 this._showPalette(this._customPaletteSetting.get(), false); | |
| 530 }, | |
| 531 | |
| 532 /** | |
| 533 * @param {number} colorIndex | |
| 534 * @param {!Event} event | |
| 535 */ | |
| 536 _showPaletteColorContextMenu: function(colorIndex, event) | |
| 537 { | |
| 538 if (!this._paletteContainerMutable) | |
| 539 return; | |
| 540 var contextMenu = new WebInspector.ContextMenu(event); | |
| 541 if (colorIndex !== -1) { | |
| 542 contextMenu.appendItem(WebInspector.UIString("Remove color"), this._
deletePaletteColors.bind(this, colorIndex, false)); | |
| 543 contextMenu.appendItem(WebInspector.UIString("Remove all to the righ
t"), this._deletePaletteColors.bind(this, colorIndex, true)); | |
| 544 } | |
| 545 contextMenu.appendItem(WebInspector.UIString("Clear palette"), this._del
etePaletteColors.bind(this, -1, true)); | |
| 546 contextMenu.show(); | |
| 547 }, | |
| 548 | |
| 549 /** | |
| 550 * @param {number} colorIndex | |
| 551 * @param {boolean} toRight | |
| 552 */ | |
| 553 _deletePaletteColors: function(colorIndex, toRight) | |
| 554 { | |
| 555 var palette = this._customPaletteSetting.get(); | |
| 556 if (toRight) | |
| 557 palette.colors.splice(colorIndex + 1, palette.colors.length - colorI
ndex - 1); | |
| 558 else | |
| 559 palette.colors.splice(colorIndex, 1); | |
| 560 this._customPaletteSetting.set(palette); | |
| 561 this._showPalette(this._customPaletteSetting.get(), false); | |
| 562 }, | |
| 563 | |
| 564 /** | |
| 565 * @param {!WebInspector.Color} color | |
| 566 * @param {string} colorFormat | |
| 567 */ | |
| 568 setColor: function(color, colorFormat) | |
| 569 { | |
| 570 this._originalFormat = colorFormat; | |
| 571 this._innerSetColor(color.hsva(), "", colorFormat, WebInspector.Spectrum
._ChangeSource.Model); | |
| 572 }, | |
| 573 | |
| 574 /** | |
| 575 * @param {!Array<number>|undefined} hsva | |
| 576 * @param {string|undefined} colorString | |
| 577 * @param {string|undefined} colorFormat | |
| 578 * @param {string} changeSource | |
| 579 */ | |
| 580 _innerSetColor: function(hsva, colorString, colorFormat, changeSource) | |
| 581 { | |
| 582 if (hsva !== undefined) | |
| 583 this._hsv = hsva; | |
| 584 if (colorString !== undefined) | |
| 585 this._colorString = colorString; | |
| 586 if (colorFormat !== undefined) { | |
| 587 var cf = WebInspector.Color.Format; | |
| 588 console.assert(colorFormat !== cf.Original, "Spectrum's color format
cannot be Original"); | |
| 589 if (colorFormat === cf.RGBA) | |
| 590 colorFormat = cf.RGB; | |
| 591 else if (colorFormat === cf.HSLA) | |
| 592 colorFormat = cf.HSL; | |
| 593 else if (colorFormat === cf.HEXA) | |
| 594 colorFormat = cf.HEX; | |
| 595 else if (colorFormat === cf.ShortHEXA) | |
| 596 colorFormat = cf.ShortHEX; | |
| 597 this._colorFormat = colorFormat; | |
| 598 } | |
| 599 | |
| 600 this._updateHelperLocations(); | |
| 601 this._updateUI(); | |
| 602 | |
| 603 if (changeSource !== WebInspector.Spectrum._ChangeSource.Input) | |
| 604 this._updateInput(); | |
| 605 if (changeSource !== WebInspector.Spectrum._ChangeSource.Model) | |
| 606 this.dispatchEventToListeners(WebInspector.Spectrum.Events.ColorChan
ged, this.colorString()); | |
| 607 }, | |
| 608 | |
| 609 /** | |
| 610 * @param {!WebInspector.Color} color | |
| 611 */ | |
| 612 setContrastColor: function(color) | |
| 613 { | |
| 614 this._contrastColor = color; | |
| 615 this._updateUI(); | |
| 616 }, | |
| 617 | |
| 618 /** | |
| 619 * @return {!WebInspector.Color} | |
| 620 */ | |
| 621 _color: function() | |
| 622 { | |
| 623 return WebInspector.Color.fromHSVA(this._hsv); | |
| 624 }, | |
| 625 | |
| 626 /** | |
| 627 * @return {string} | |
| 628 */ | |
| 629 colorString: function() | |
| 630 { | |
| 631 if (this._colorString) | |
| 632 return this._colorString; | |
| 633 var cf = WebInspector.Color.Format; | |
| 634 var color = this._color(); | |
| 635 var colorString = color.asString(this._colorFormat); | |
| 636 if (colorString) | |
| 637 return colorString; | |
| 638 | |
| 639 if (this._colorFormat === cf.Nickname) { | |
| 640 colorString = color.asString(cf.HEX); | |
| 641 if (colorString) | |
| 642 return colorString; | |
| 643 } | |
| 644 | |
| 645 if (this._colorFormat === cf.ShortHEX) | |
| 646 colorString = color.asString(color.detectHEXFormat()); | |
| 647 else if (this._colorFormat === cf.HEX) | |
| 648 colorString = color.asString(color.hasAlpha() ? cf.HEXA : cf.HEX); | |
| 649 else if (this._colorFormat === cf.HSL) | |
| 650 colorString = color.asString(cf.HSLA); | |
| 651 else | |
| 652 colorString = color.asString(cf.RGBA); | |
| 653 | |
| 654 console.assert(colorString); | |
| 655 return colorString || ""; | |
| 656 }, | |
| 657 | |
| 658 _updateHelperLocations: function() | |
| 659 { | |
| 660 var h = this._hsv[0]; | |
| 661 var s = this._hsv[1]; | |
| 662 var v = this._hsv[2]; | |
| 663 var alpha = this._hsv[3]; | |
| 664 | |
| 665 // Where to show the little circle that displays your current selected c
olor. | |
| 666 var dragX = s * this.dragWidth; | |
| 667 var dragY = this.dragHeight - (v * this.dragHeight); | |
| 668 | |
| 669 dragX = Math.max(-this._colorDragElementHeight, | |
| 670 Math.min(this.dragWidth - this._colorDragElementHeight,
dragX - this._colorDragElementHeight)); | |
| 671 dragY = Math.max(-this._colorDragElementHeight, | |
| 672 Math.min(this.dragHeight - this._colorDragElementHeight,
dragY - this._colorDragElementHeight)); | |
| 673 | |
| 674 this._colorDragElement.positionAt(dragX, dragY); | |
| 675 | |
| 676 // Where to show the bar that displays your current selected hue. | |
| 677 var hueSlideX = (1 - h) * this._hueAlphaWidth - this.slideHelperWidth; | |
| 678 this._hueSlider.style.left = hueSlideX + "px"; | |
| 679 var alphaSlideX = alpha * this._hueAlphaWidth - this.slideHelperWidth; | |
| 680 this._alphaSlider.style.left = alphaSlideX + "px"; | |
| 681 }, | |
| 682 | |
| 683 _updateInput: function() | |
| 684 { | |
| 685 var cf = WebInspector.Color.Format; | |
| 686 if (this._colorFormat === cf.HEX || this._colorFormat === cf.ShortHEX ||
this._colorFormat === cf.Nickname) { | |
| 687 this._hexContainer.hidden = false; | |
| 688 this._displayContainer.hidden = true; | |
| 689 if (this._colorFormat === cf.ShortHEX) | |
| 690 this._hexValue.value = this._color().asString(this._color().dete
ctHEXFormat()); | |
| 691 else | |
| 692 // Don't use short HEX if original was not in that format. | |
| 693 this._hexValue.value = this._color().asString(this._color().hasA
lpha() ? cf.HEXA : cf.HEX); | |
| 694 } else { | |
| 695 // RGBA, HSLA display. | |
| 696 this._hexContainer.hidden = true; | |
| 697 this._displayContainer.hidden = false; | |
| 698 var isRgb = this._colorFormat === cf.RGB; | |
| 699 this._textLabels.textContent = isRgb ? "RGBA" : "HSLA"; | |
| 700 var colorValues = isRgb ? this._color().canonicalRGBA() : this._colo
r().canonicalHSLA(); | |
| 701 for (var i = 0; i < 3; ++i) { | |
| 702 this._textValues[i].value = colorValues[i]; | |
| 703 if (!isRgb && (i === 1 || i === 2)) | |
| 704 this._textValues[i].value += "%"; | |
| 705 } | |
| 706 this._textValues[3].value = Math.round(colorValues[3] * 100) / 100; | |
| 707 } | |
| 708 }, | |
| 709 | |
| 710 /** | |
| 711 * @param {number} requiredContrast | |
| 712 */ | |
| 713 _drawContrastRatioLine: function(requiredContrast) | |
| 714 { | |
| 715 if (!this._contrastColor || !this.dragWidth || !this.dragHeight) | |
| 716 return; | |
| 717 | |
| 718 /** const */ var width = this.dragWidth; | |
| 719 /** const */ var height = this.dragHeight; | |
| 720 /** const */ var dS = 0.02; | |
| 721 /** const */ var epsilon = 0.002; | |
| 722 /** const */ var H = 0; | |
| 723 /** const */ var S = 1; | |
| 724 /** const */ var V = 2; | |
| 725 /** const */ var A = 3; | |
| 726 | |
| 727 var fgRGBA = []; | |
| 728 WebInspector.Color.hsva2rgba(this._hsv, fgRGBA); | |
| 729 var fgLuminance = WebInspector.Color.luminance(fgRGBA); | |
| 730 var bgRGBA = this._contrastColor.rgba(); | |
| 731 var bgLuminance = WebInspector.Color.luminance(bgRGBA); | |
| 732 var fgIsLighter = fgLuminance > bgLuminance; | |
| 733 var desiredLuminance = WebInspector.Color.desiredLuminance(bgLuminance,
requiredContrast, fgIsLighter); | |
| 734 | |
| 735 var lastV = this._hsv[V]; | |
| 736 var currentSlope = 0; | |
| 737 var candidateHSVA = [this._hsv[H], 0, 0, this._hsv[A]]; | |
| 738 var pathBuilder = []; | |
| 739 var candidateRGBA = []; | |
| 740 WebInspector.Color.hsva2rgba(candidateHSVA, candidateRGBA); | |
| 741 var blendedRGBA = []; | |
| 742 WebInspector.Color.blendColors(candidateRGBA, bgRGBA, blendedRGBA); | |
| 743 | |
| 744 /** | |
| 745 * Approach the desired contrast ratio by modifying the given component | |
| 746 * from the given starting value. | |
| 747 * @param {number} index | |
| 748 * @param {number} x | |
| 749 * @param {boolean} onAxis | |
| 750 * @return {?number} | |
| 751 */ | |
| 752 function approach(index, x, onAxis) | |
| 753 { | |
| 754 while (0 <= x && x <= 1) { | |
| 755 candidateHSVA[index] = x; | |
| 756 WebInspector.Color.hsva2rgba(candidateHSVA, candidateRGBA); | |
| 757 WebInspector.Color.blendColors(candidateRGBA, bgRGBA, blendedRGB
A); | |
| 758 var fgLuminance = WebInspector.Color.luminance(blendedRGBA); | |
| 759 var dLuminance = fgLuminance - desiredLuminance; | |
| 760 | |
| 761 if (Math.abs(dLuminance) < (onAxis ? epsilon / 10 : epsilon)) | |
| 762 return x; | |
| 763 else | |
| 764 x += (index === V ? -dLuminance : dLuminance); | |
| 765 } | |
| 766 return null; | |
| 767 } | |
| 768 | |
| 769 for (var s = 0; s < 1 + dS; s += dS) { | |
| 770 s = Math.min(1, s); | |
| 771 candidateHSVA[S] = s; | |
| 772 | |
| 773 var v = lastV; | |
| 774 v = lastV + currentSlope * dS; | |
| 775 | |
| 776 v = approach(V, v, s === 0); | |
| 777 if (v === null) | |
| 778 break; | |
| 779 | |
| 780 currentSlope = (v - lastV) / dS; | |
| 781 | |
| 782 pathBuilder.push(pathBuilder.length ? "L" : "M"); | |
| 783 pathBuilder.push(s * width); | |
| 784 pathBuilder.push((1 - v) * height); | |
| 785 } | |
| 786 | |
| 787 if (s < 1 + dS) { | |
| 788 s -= dS; | |
| 789 candidateHSVA[V] = 1; | |
| 790 s = approach(S, s, true); | |
| 791 if (s !== null) | |
| 792 pathBuilder = pathBuilder.concat(["L", s * width, -1]) | |
| 793 } | |
| 794 | |
| 795 this._contrastRatioLine.setAttribute("d", pathBuilder.join(" ")); | |
| 796 }, | |
| 797 | |
| 798 _updateUI: function() | |
| 799 { | |
| 800 var h = WebInspector.Color.fromHSVA([this._hsv[0], 1, 1, 1]); | |
| 801 this._colorElement.style.backgroundColor = /** @type {string} */ (h.asSt
ring(WebInspector.Color.Format.RGB)); | |
| 802 if (Runtime.experiments.isEnabled("colorContrastRatio")) { | |
| 803 // TODO(samli): Determine size of text and switch between AA/AAA rat
ings. | |
| 804 this._drawContrastRatioLine(4.5); | |
| 805 } | |
| 806 this._swatchInnerElement.style.backgroundColor = /** @type {string} */ (
this._color().asString(WebInspector.Color.Format.RGBA)); | |
| 807 // Show border if the swatch is white. | |
| 808 this._swatchInnerElement.classList.toggle("swatch-inner-white", this._co
lor().hsla()[2] > 0.9); | |
| 809 this._colorDragElement.style.backgroundColor = /** @type {string} */ (th
is._color().asString(WebInspector.Color.Format.RGBA)); | |
| 810 var noAlpha = WebInspector.Color.fromHSVA(this._hsv.slice(0,3).concat(1)
); | |
| 811 this._alphaElementBackground.style.backgroundImage = String.sprintf("lin
ear-gradient(to right, rgba(0,0,0,0), %s)", noAlpha.asString(WebInspector.Color.
Format.RGB)); | |
| 812 }, | |
| 813 | |
| 814 _formatViewSwitch: function() | |
| 815 { | |
| 816 var cf = WebInspector.Color.Format; | |
| 817 var format = cf.RGB; | |
| 818 if (this._colorFormat === cf.RGB) | |
| 819 format = cf.HSL; | |
| 820 else if (this._colorFormat === cf.HSL) | |
| 821 format = this._originalFormat === cf.ShortHEX ? cf.ShortHEX : cf.HEX
; | |
| 822 this._innerSetColor(undefined, "", format, WebInspector.Spectrum._Change
Source.Other); | |
| 823 }, | |
| 824 | |
| 825 /** | |
| 826 * @param {!Event} event | |
| 827 */ | |
| 828 _inputChanged: function(event) | |
| 829 { | |
| 830 /** | |
| 831 * @param {!Element} element | |
| 832 * @return {string} | |
| 833 */ | |
| 834 function elementValue(element) | |
| 835 { | |
| 836 return element.value; | |
| 837 } | |
| 838 | |
| 839 var inputElement = /** @type {!Element} */(event.currentTarget); | |
| 840 var arrowKeyOrMouseWheelEvent = (event.key === "ArrowUp" || event.key ==
= "ArrowDown" || event.type === "mousewheel"); | |
| 841 var pageKeyPressed = (event.key === "PageUp" || event.key === "PageDown"
); | |
| 842 if (arrowKeyOrMouseWheelEvent || pageKeyPressed) { | |
| 843 var newValue = WebInspector.createReplacementString(inputElement.val
ue, event); | |
| 844 if (newValue) { | |
| 845 inputElement.value = newValue; | |
| 846 inputElement.selectionStart = 0; | |
| 847 inputElement.selectionEnd = newValue.length; | |
| 848 } | |
| 849 event.consume(true); | |
| 850 } | |
| 851 | |
| 852 const cf = WebInspector.Color.Format; | |
| 853 var colorString; | |
| 854 if (this._colorFormat === cf.HEX || this._colorFormat === cf.ShortHEX) { | |
| 855 colorString = this._hexValue.value; | |
| 856 } else { | |
| 857 var format = this._colorFormat === cf.RGB ? "rgba" : "hsla"; | |
| 858 var values = this._textValues.map(elementValue).join(","); | |
| 859 colorString = String.sprintf("%s(%s)", format, values); | |
| 860 } | |
| 861 | |
| 862 var color = WebInspector.Color.parse(colorString); | |
| 863 if (!color) | |
| 864 return; | |
| 865 var hsv = color.hsva(); | |
| 866 if (this._colorFormat === cf.HEX || this._colorFormat === cf.ShortHEX) | |
| 867 this._colorFormat = color.detectHEXFormat(); | |
| 868 this._innerSetColor(hsv, colorString, undefined, WebInspector.Spectrum._
ChangeSource.Input); | |
| 869 }, | |
| 870 | |
| 871 wasShown: function() | |
| 872 { | |
| 873 this._hueAlphaWidth = this._hueElement.offsetWidth; | |
| 874 this.slideHelperWidth = this._hueSlider.offsetWidth / 2; | |
| 875 this.dragWidth = this._colorElement.offsetWidth; | |
| 876 this.dragHeight = this._colorElement.offsetHeight; | |
| 877 this._colorDragElementHeight = this._colorDragElement.offsetHeight / 2; | |
| 878 this._innerSetColor(undefined, undefined, undefined, WebInspector.Spectr
um._ChangeSource.Model); | |
| 879 this._toggleColorPicker(true); | |
| 880 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeMod
el, WebInspector.ResourceTreeModel.EventTypes.ColorPicked, this._colorPicked, th
is); | |
| 881 }, | |
| 882 | |
| 883 willHide: function() | |
| 884 { | |
| 885 this._toggleColorPicker(false); | |
| 886 WebInspector.targetManager.removeModelListener(WebInspector.ResourceTree
Model, WebInspector.ResourceTreeModel.EventTypes.ColorPicked, this._colorPicked,
this); | |
| 887 }, | |
| 888 | |
| 889 /** | |
| 890 * @param {boolean=} enabled | |
| 891 * @param {!WebInspector.Event=} event | |
| 892 */ | |
| 893 _toggleColorPicker: function(enabled, event) | |
| 894 { | |
| 895 if (enabled === undefined) | |
| 896 enabled = !this._colorPickerButton.toggled(); | |
| 897 this._colorPickerButton.setToggled(enabled); | |
| 898 for (var target of WebInspector.targetManager.targets()) | |
| 899 target.pageAgent().setColorPickerEnabled(enabled); | |
| 900 }, | |
| 901 | |
| 902 /** | |
| 903 * @param {!WebInspector.Event} event | |
| 904 */ | |
| 905 _colorPicked: function(event) | |
| 906 { | |
| 907 var rgbColor = /** @type {!DOMAgent.RGBA} */ (event.data); | |
| 908 var rgba = [rgbColor.r, rgbColor.g, rgbColor.b, (rgbColor.a / 2.55 | 0)
/ 100]; | |
| 909 var color = WebInspector.Color.fromRGBA(rgba); | |
| 910 this._innerSetColor(color.hsva(), "", undefined, WebInspector.Spectrum._
ChangeSource.Other); | |
| 911 InspectorFrontendHost.bringToFront(); | |
| 912 }, | |
| 913 | |
| 914 | |
| 915 __proto__: WebInspector.VBox.prototype | |
| 916 } | |
| 917 | |
| 918 /** @typedef {{ title: string, colors: !Array.<string>, mutable: boolean }} */ | |
| 919 WebInspector.Spectrum.Palette; | |
| 920 WebInspector.Spectrum.GeneratedPaletteTitle = "Page colors"; | |
| 921 | |
| 922 /** | |
| 923 * @constructor | |
| 924 * @param {function(!WebInspector.Spectrum.Palette)} callback | |
| 925 */ | |
| 926 WebInspector.Spectrum.PaletteGenerator = function(callback) | |
| 927 { | |
| 928 this._callback = callback; | |
| 929 /** @type {!Map.<string, number>} */ | |
| 930 this._frequencyMap = new Map(); | |
| 931 var stylesheetPromises = []; | |
| 932 for (var target of WebInspector.targetManager.targets(WebInspector.Target.Ty
pe.Page)) { | |
| 933 var cssModel = WebInspector.CSSModel.fromTarget(target); | |
| 934 for (var stylesheet of cssModel.allStyleSheets()) | |
| 935 stylesheetPromises.push(new Promise(this._processStylesheet.bind(thi
s, stylesheet))); | |
| 936 } | |
| 937 Promise.all(stylesheetPromises) | |
| 938 .catchException(null) | |
| 939 .then(this._finish.bind(this)); | |
| 940 } | |
| 941 | |
| 942 WebInspector.Spectrum.PaletteGenerator.prototype = { | |
| 943 /** | |
| 944 * @param {string} a | |
| 945 * @param {string} b | |
| 946 * @return {number} | |
| 947 */ | |
| 948 _frequencyComparator: function(a, b) | |
| 949 { | |
| 950 return this._frequencyMap.get(b) - this._frequencyMap.get(a); | |
| 951 }, | |
| 952 | |
| 953 _finish: function() | |
| 954 { | |
| 955 /** | |
| 956 * @param {string} a | |
| 957 * @param {string} b | |
| 958 * @return {number} | |
| 959 */ | |
| 960 function hueComparator(a, b) | |
| 961 { | |
| 962 var hsva = paletteColors.get(a).hsva(); | |
| 963 var hsvb = paletteColors.get(b).hsva(); | |
| 964 | |
| 965 // First trim the shades of gray | |
| 966 if (hsvb[1] < 0.12 && hsva[1] < 0.12) | |
| 967 return hsvb[2] * hsvb[3] - hsva[2] * hsva[3]; | |
| 968 if (hsvb[1] < 0.12) | |
| 969 return -1; | |
| 970 if (hsva[1] < 0.12) | |
| 971 return 1; | |
| 972 | |
| 973 // Equal hue -> sort by sat | |
| 974 if (hsvb[0] === hsva[0]) | |
| 975 return hsvb[1] * hsvb[3] - hsva[1] * hsva[3]; | |
| 976 | |
| 977 return (hsvb[0] + 0.94) % 1 - (hsva[0] + 0.94) % 1; | |
| 978 } | |
| 979 | |
| 980 var colors = this._frequencyMap.keysArray(); | |
| 981 colors = colors.sort(this._frequencyComparator.bind(this)); | |
| 982 /** @type {!Map.<string, !WebInspector.Color>} */ | |
| 983 var paletteColors = new Map(); | |
| 984 var colorsPerRow = 24; | |
| 985 while (paletteColors.size < colorsPerRow && colors.length) { | |
| 986 var colorText = colors.shift(); | |
| 987 var color = WebInspector.Color.parse(colorText); | |
| 988 if (!color || color.nickname() === "white" || color.nickname() === "
black") | |
| 989 continue; | |
| 990 paletteColors.set(colorText, color); | |
| 991 } | |
| 992 | |
| 993 this._callback({ title: WebInspector.Spectrum.GeneratedPaletteTitle, col
ors: paletteColors.keysArray().sort(hueComparator), mutable: false }); | |
| 994 }, | |
| 995 | |
| 996 /** | |
| 997 * @param {!WebInspector.CSSStyleSheetHeader} stylesheet | |
| 998 * @param {function(?)} resolve | |
| 999 * @this {WebInspector.Spectrum.PaletteGenerator} | |
| 1000 */ | |
| 1001 _processStylesheet: function(stylesheet, resolve) | |
| 1002 { | |
| 1003 /** | |
| 1004 * @param {?string} text | |
| 1005 * @this {WebInspector.Spectrum.PaletteGenerator} | |
| 1006 */ | |
| 1007 function parseContent(text) | |
| 1008 { | |
| 1009 text = text.toLowerCase(); | |
| 1010 var regexResult = text.match(/((?:rgb|hsl)a?\([^)]+\)|#[0-9a-f]{6}|#
[0-9a-f]{3})/g) || []; | |
| 1011 for (var c of regexResult) { | |
| 1012 var frequency = this._frequencyMap.get(c) || 0; | |
| 1013 this._frequencyMap.set(c, ++frequency); | |
| 1014 } | |
| 1015 resolve(null); | |
| 1016 } | |
| 1017 | |
| 1018 stylesheet.requestContent().then(parseContent.bind(this)); | |
| 1019 } | |
| 1020 } | |
| 1021 | |
| 1022 WebInspector.Spectrum.MaterialPaletteShades = { | |
| 1023 "#F44336": ["#FFEBEE", "#FFCDD2", "#EF9A9A", "#E57373", "#EF5350", "#F44336"
, "#E53935", "#D32F2F", "#C62828", "#B71C1C"], | |
| 1024 "#E91E63": ["#FCE4EC", "#F8BBD0", "#F48FB1", "#F06292", "#EC407A", "#E91E63"
, "#D81B60", "#C2185B", "#AD1457", "#880E4F"], | |
| 1025 "#9C27B0": ["#F3E5F5", "#E1BEE7", "#CE93D8", "#BA68C8", "#AB47BC", "#9C27B0"
, "#8E24AA", "#7B1FA2", "#6A1B9A", "#4A148C"], | |
| 1026 "#673AB7": ["#EDE7F6", "#D1C4E9", "#B39DDB", "#9575CD", "#7E57C2", "#673AB7"
, "#5E35B1", "#512DA8", "#4527A0", "#311B92"], | |
| 1027 "#3F51B5": ["#E8EAF6", "#C5CAE9", "#9FA8DA", "#7986CB", "#5C6BC0", "#3F51B5"
, "#3949AB", "#303F9F", "#283593", "#1A237E"], | |
| 1028 "#2196F3": ["#E3F2FD", "#BBDEFB", "#90CAF9", "#64B5F6", "#42A5F5", "#2196F3"
, "#1E88E5", "#1976D2", "#1565C0", "#0D47A1"], | |
| 1029 "#03A9F4": ["#E1F5FE", "#B3E5FC", "#81D4FA", "#4FC3F7", "#29B6F6", "#03A9F4"
, "#039BE5", "#0288D1", "#0277BD", "#01579B"], | |
| 1030 "#00BCD4": ["#E0F7FA", "#B2EBF2", "#80DEEA", "#4DD0E1", "#26C6DA", "#00BCD4"
, "#00ACC1", "#0097A7", "#00838F", "#006064"], | |
| 1031 "#009688": ["#E0F2F1", "#B2DFDB", "#80CBC4", "#4DB6AC", "#26A69A", "#009688"
, "#00897B", "#00796B", "#00695C", "#004D40"], | |
| 1032 "#4CAF50": ["#E8F5E9", "#C8E6C9", "#A5D6A7", "#81C784", "#66BB6A", "#4CAF50"
, "#43A047", "#388E3C", "#2E7D32", "#1B5E20"], | |
| 1033 "#8BC34A": ["#F1F8E9", "#DCEDC8", "#C5E1A5", "#AED581", "#9CCC65", "#8BC34A"
, "#7CB342", "#689F38", "#558B2F", "#33691E"], | |
| 1034 "#CDDC39": ["#F9FBE7", "#F0F4C3", "#E6EE9C", "#DCE775", "#D4E157", "#CDDC39"
, "#C0CA33", "#AFB42B", "#9E9D24", "#827717"], | |
| 1035 "#FFEB3B": ["#FFFDE7", "#FFF9C4", "#FFF59D", "#FFF176", "#FFEE58", "#FFEB3B"
, "#FDD835", "#FBC02D", "#F9A825", "#F57F17"], | |
| 1036 "#FFC107": ["#FFF8E1", "#FFECB3", "#FFE082", "#FFD54F", "#FFCA28", "#FFC107"
, "#FFB300", "#FFA000", "#FF8F00", "#FF6F00"], | |
| 1037 "#FF9800": ["#FFF3E0", "#FFE0B2", "#FFCC80", "#FFB74D", "#FFA726", "#FF9800"
, "#FB8C00", "#F57C00", "#EF6C00", "#E65100"], | |
| 1038 "#FF5722": ["#FBE9E7", "#FFCCBC", "#FFAB91", "#FF8A65", "#FF7043", "#FF5722"
, "#F4511E", "#E64A19", "#D84315", "#BF360C"], | |
| 1039 "#795548": ["#EFEBE9", "#D7CCC8", "#BCAAA4", "#A1887F", "#8D6E63", "#795548"
, "#6D4C41", "#5D4037", "#4E342E", "#3E2723"], | |
| 1040 "#9E9E9E": ["#FAFAFA", "#F5F5F5", "#EEEEEE", "#E0E0E0", "#BDBDBD", "#9E9E9E"
, "#757575", "#616161", "#424242", "#212121"], | |
| 1041 "#607D8B": ["#ECEFF1", "#CFD8DC", "#B0BEC5", "#90A4AE", "#78909C", "#607D8B"
, "#546E7A", "#455A64", "#37474F", "#263238"] | |
| 1042 }; | |
| 1043 | |
| 1044 WebInspector.Spectrum.MaterialPalette = { title: "Material", mutable: false, mat
chUserFormat: true, colors: Object.keys(WebInspector.Spectrum.MaterialPaletteSha
des) }; | |
| OLD | NEW |