diff --git a/manage.html b/manage.html index 15b63bb1..aed0a3a5 100644 --- a/manage.html +++ b/manage.html @@ -7,6 +7,7 @@ + @@ -149,7 +150,7 @@ - + diff --git a/manage/config-dialog.js b/manage/config-dialog.js index e8d8730c..02c5e540 100644 --- a/manage/config-dialog.js +++ b/manage/config-dialog.js @@ -1,8 +1,9 @@ -/* global colorParser messageBox makeLink */ +/* global messageBox makeLink */ 'use strict'; function configDialog(style) { const form = buildConfigForm(); + const colorpicker = window.colorpicker(); return messageBox({ title: `${style.name} v${style.usercssData.version}`, @@ -34,7 +35,7 @@ function configDialog(style) { colorpicker.hide(); } if (button === 0 || enter) { - return form.getVars(); + return form.getVars(); } }); @@ -46,25 +47,14 @@ function configDialog(style) { let appendChild; switch (va.type) { case 'color': - va.inputColor = $element({tag: 'input', type: 'color'}); - va.inputAlpha = $element({ - tag: 'input', - type: 'range', - min: 0, - max: 1, - title: chrome.i18n.getMessage('alphaChannel'), - step: 'any' - }); - va.inputColor.onchange = va.inputAlpha.oninput = () => { - va.dirty = true; - const color = colorParser.parse(va.inputColor.value); - color.a = Number(va.inputAlpha.value); - va.value = colorParser.format(color); - va.inputColor.style.opacity = color.a; - }; - appendChild = [ - $element({appendChild: [va.inputColor, va.inputAlpha]}) - ]; + appendChild = [$element({ + className: 'cm-colorview', + appendChild: va.inputColor = $element({ + va, + className: 'color-swatch', + onclick: onColorClicked, + }) + })]; break; case 'checkbox': @@ -119,15 +109,10 @@ function configDialog(style) { function drawValues() { for (const key of Object.keys(vars)) { const va = vars[key]; - const value = va.value === null || va.value === undefined ? - va.default : va.value; - + const useDefault = va.value === null || va.value === undefined; + const value = useDefault ? va.default : va.value; if (va.type === 'color') { - const color = colorParser.parse(value); - va.inputAlpha.value = color.a; - va.inputColor.style.opacity = color.a; - delete color.a; - va.inputColor.value = colorParser.formatHex(color); + va.inputColor.style.backgroundColor = value; } else if (va.type === 'checkbox') { va.input.checked = Number(value); } else { @@ -149,6 +134,30 @@ function configDialog(style) { return vars; } + function onColorClicked() { + window.removeEventListener('keydown', messageBox.listeners.key, true); + const box = $('#message-box-contents'); + colorpicker.show({ + color: this.va.value || this.va.default, + top: this.getBoundingClientRect().bottom - 5, + left: box.getBoundingClientRect().left - 360, + hideDelay: 1e6, + guessBrightness: box, + callback: newColor => { + if (newColor) { + this.va.dirty = true; + this.va.value = newColor; + this.style.backgroundColor = newColor; + } + setTimeout(() => { + if (!$('.colorpicker-popup')) { + window.addEventListener('keydown', messageBox.listeners.key, true); + } + }); + }, + }); + } + return { elements: labels, useDefault, diff --git a/manage/manage.css b/manage/manage.css index 724d9cc3..b64f2a8c 100644 --- a/manage/manage.css +++ b/manage/manage.css @@ -766,6 +766,29 @@ fieldset select { margin-right: 4px; } +.cm-colorview::before, +.color-swatch { + width: 60px !important; + height: 20px !important; +} + +.cm-colorview::before { + margin: 1px !important; +} + +.color-swatch { + position: absolute; + border: 1px solid gray; + margin-top: -22px; + cursor: pointer; +} + +.colorpicker-popup { + z-index: 2147483647 !important; + border: none !important; + box-shadow: 3px 3px 50px rgba(0,0,0,.5) !important; +} + @keyframes fadein { from { opacity: 0; diff --git a/vendor-overwrites/colorpicker/colorpicker.js b/vendor-overwrites/colorpicker/colorpicker.js index b1a7b264..2253906e 100644 --- a/vendor-overwrites/colorpicker/colorpicker.js +++ b/vendor-overwrites/colorpicker/colorpicker.js @@ -1,7 +1,7 @@ /* global CodeMirror */ 'use strict'; -CodeMirror.defineExtension('colorpicker', function () { +(window.CodeMirror ? window.CodeMirror.prototype : window).colorpicker = function () { const cm = this; const CSS_PREFIX = 'colorpicker-'; const HUE_COLORS = [ @@ -188,18 +188,6 @@ CodeMirror.defineExtension('colorpicker', function () { if (!initialized) { init(); } - $root.style = ` - display: block; - position: fixed; - left: -10000px; - top: -10000px; - `.replace(/;/g, '!important;'); - $root.classList.add(CSS_PREFIX + 'theme-' + - (opt.theme === 'dark' || opt.theme === 'light' ? opt.theme : guessTheme())); - document.body.appendChild($root); - - shown = true; - HSV = {}; currentFormat = ''; options = PUBLIC_API.options = opt; @@ -209,8 +197,23 @@ CodeMirror.defineExtension('colorpicker', function () { $formatChangeButton.title = opt.tooltipForSwitcher || ''; opt.hideDelay = Math.max(0, opt.hideDelay) || 2000; + if (!isNaN(options.left) && !isNaN(options.top)) { + $root.style = ` + display: block; + position: fixed; + `.replace(/;/g, '!important;'); + reposition(); + } + + $root.classList.add(CSS_PREFIX + 'theme-' + + (opt.theme === 'dark' || opt.theme === 'light' ? + opt.theme : + guessTheme())); + document.body.appendChild($root); + + shown = true; + registerEvents(); - reposition(); setFromColor(opt.color); setFromHexLettercaseElement(); } @@ -601,9 +604,9 @@ CodeMirror.defineExtension('colorpicker', function () { switch (e.which) { case 13: setFromInputs({}); - colorpickerCallback(); // fallthrough to 27 case 27: + colorpickerCallback(e.which === 27 ? '' : undefined); e.preventDefault(); e.stopPropagation(); hide(); @@ -622,6 +625,10 @@ CodeMirror.defineExtension('colorpicker', function () { //region Event utilities function colorpickerCallback(colorString = currentColorToString()) { + // Esc pressed? + if (!colorString) { + options.callback(''); + } if ( userActivity && $inputs[currentFormat].every(el => el.checkValidity()) && @@ -914,7 +921,8 @@ CodeMirror.defineExtension('colorpicker', function () { function guessTheme() { const realColor = {r: 255, g: 255, b: 255, a: 1}; - const start = ((cm.display.renderedView || [])[0] || {}).text || cm.display.lineDiv; + const start = options.guessBrightness || + ((cm.display.renderedView || [])[0] || {}).text || cm.display.lineDiv; for (let el = start; el; el = el.parentElement) { const bgColor = getComputedStyle(el).backgroundColor; const [r, g, b, a = 255] = bgColor.match(/\d+/g).map(Number); @@ -953,4 +961,4 @@ CodeMirror.defineExtension('colorpicker', function () { } //endregion -}); +}; diff --git a/vendor-overwrites/colorpicker/colorview.js b/vendor-overwrites/colorpicker/colorview.js index 11cb1bb6..ee2529f6 100644 --- a/vendor-overwrites/colorpicker/colorview.js +++ b/vendor-overwrites/colorpicker/colorview.js @@ -478,6 +478,9 @@ } static popupOnChange(newColor) { + if (!newColor) { + return; + } const {cm, line, ch, embedderCallback} = this; const to = {line, ch: ch + this.prevColor.length}; if (cm.getRange(this, to) !== newColor) {