From 7966ce5bd3207680d77be2dd9f8e3b01ccca7461 Mon Sep 17 00:00:00 2001 From: tophf Date: Fri, 16 Oct 2020 22:56:56 +0300 Subject: [PATCH] show a palette for current editor in color picker --- vendor-overwrites/colorpicker/colorpicker.css | 12 +++++ vendor-overwrites/colorpicker/colorpicker.js | 23 ++++++++++ vendor-overwrites/colorpicker/colorview.js | 45 +++++++++++++++++++ 3 files changed, 80 insertions(+) diff --git a/vendor-overwrites/colorpicker/colorpicker.css b/vendor-overwrites/colorpicker/colorpicker.css index e02b0d14..6ddfb97f 100644 --- a/vendor-overwrites/colorpicker/colorpicker.css +++ b/vendor-overwrites/colorpicker/colorpicker.css @@ -357,3 +357,15 @@ .colorpicker-format-change-button:hover { color: var(--label-color-hover); } + +.colorpicker-palette:not(:empty) { + padding: 0 8px 8px; + min-height: 14px; /* same as padding-left in .colorview-swatch */ + max-height: 10vw; + overflow: auto; + box-sizing: content-box; +} + +.colorpicker-palette .colorview-swatch { + padding-bottom: 14px; /* same as padding-left in .colorview-swatch */ +} diff --git a/vendor-overwrites/colorpicker/colorpicker.js b/vendor-overwrites/colorpicker/colorpicker.js index c3381495..df312aaf 100644 --- a/vendor-overwrites/colorpicker/colorpicker.js +++ b/vendor-overwrites/colorpicker/colorpicker.js @@ -30,6 +30,7 @@ let $swatch; let $formatChangeButton; let $hexCode; + let $palette; const $inputGroups = {}; const $inputs = {}; const $rgb = {}; @@ -164,6 +165,7 @@ $formatChangeButton = $('format-change-button', {textContent: '↔'}), ]}), ]}), + $palette = $('palette'), ]}); $inputs.hex = [$hexCode]; @@ -221,6 +223,11 @@ if (!isNaN(options.left) && !isNaN(options.top)) { reposition(); } + if (Array.isArray(options.palette)) { + // Might need to clear a lot of elements so this is known to be faster than textContent = '' + while ($palette.firstChild) $palette.firstChild.remove(); + $palette.append(...(options.palette)); + } } function hide() { @@ -574,6 +581,18 @@ } } + /** @param {MouseEvent} e */ + function onPaletteClicked(e) { + if (e.target !== e.currentTarget) { + e.preventDefault(); + if (!e.button) { + setColor(e.target.__color); + } else if (e.button === 2 && options.paletteCallback) { + options.paletteCallback(e.target); + } + } + } + function onMouseUp(event) { releaseMouse(event, ['saturation', 'hue', 'opacity']); if (onMouseDown.outsideClick) { @@ -710,6 +729,8 @@ $opacity.addEventListener('mousedown', onOpacityMouseDown); $hexLettercase.true.addEventListener('click', onHexLettercaseClicked); $hexLettercase.false.addEventListener('click', onHexLettercaseClicked); + $palette.addEventListener('click', onPaletteClicked); + $palette.addEventListener('contextmenu', onPaletteClicked); stopSnoozing(); if (!options.isShortCut) { @@ -735,6 +756,8 @@ $opacity.removeEventListener('mousedown', onOpacityMouseDown); $hexLettercase.true.removeEventListener('click', onHexLettercaseClicked); $hexLettercase.false.removeEventListener('click', onHexLettercaseClicked); + $palette.removeEventListener('click', onPaletteClicked); + $palette.removeEventListener('contextmenu', onPaletteClicked); releaseMouse(); stopSnoozing(); } diff --git a/vendor-overwrites/colorpicker/colorview.js b/vendor-overwrites/colorpicker/colorview.js index f88fe07b..6b0f4933 100644 --- a/vendor-overwrites/colorpicker/colorview.js +++ b/vendor-overwrites/colorpicker/colorview.js @@ -532,6 +532,8 @@ color: data.color, prevColor: data.color || '', callback: popupOnChange, + palette: makePalette(state), + paletteCallback: el => paletteCallback(state, el), })); } @@ -551,6 +553,49 @@ } } + function makePalette({cm, options}) { + const palette = new Map(); + let i = 0; + let nums; + cm.doc.eachLine(({markedSpans}) => { + ++i; + if (!markedSpans) return; + for (const {from, marker: m} of markedSpans) { + if (from == null || m.className !== COLORVIEW_CLASS) continue; + nums = palette.get(m.color); + if (!nums) palette.set(m.color, (nums = [])); + nums.push(i); + } + }); + const res = []; + if (palette.size > 1 || nums && nums.length > 1) { + const old = new Map((options.popup.palette || []).map(el => [el.__color, el])); + for (const [color, data] of palette) { + res.push(old.get(color) || makePaletteSwatch(color, data)); + } + } + return res; + } + + function makePaletteSwatch(color, nums) { + const s = nums.join(', '); + const el = document.createElement('div'); + el.className = COLORVIEW_SWATCH_CLASS; + el.style.cssText = COLORVIEW_SWATCH_CSS + color; + el.title = color + (!s ? '' : `\nLine: ${s.length > 50 ? s.replace(/([^,]+,\s){10}/g, '$&\n') : s}`); + el.__color = color; + return el; + } + + function paletteCallback({cm}, el) { + const lines = el.title.split('\n')[1].match(/\d+/g).map(Number); + const curLine = cm.getCursor().line + 1; + const i = lines.indexOf(curLine) + 1; + const pos = {line: (lines[i] || curLine) - 1, ch: 0}; + cm.scrollIntoView(pos, cm.defaultTextHeight()); + cm.setCursor(pos); + } + //endregion //region Utility