usercss editor: use real theme color for inputs in widgets
This commit is contained in:
parent
69736ef5a1
commit
bd0f460c56
|
@ -74,7 +74,7 @@
|
||||||
<link rel="stylesheet" href="/edit/codemirror-default.css">
|
<link rel="stylesheet" href="/edit/codemirror-default.css">
|
||||||
|
|
||||||
<template data-id="appliesTo">
|
<template data-id="appliesTo">
|
||||||
<li>
|
<li class="applies-to-item">
|
||||||
<div class="select-resizer">
|
<div class="select-resizer">
|
||||||
<select name="applies-type" class="applies-type style-contributor">
|
<select name="applies-type" class="applies-type style-contributor">
|
||||||
<option value="url" i18n-text="appliesUrlOption"></option>
|
<option value="url" i18n-text="appliesUrlOption"></option>
|
||||||
|
|
|
@ -5,7 +5,7 @@ function createAppliesToLineWidget(cm) {
|
||||||
const THROTTLE_DELAY = 400;
|
const THROTTLE_DELAY = 400;
|
||||||
let TPL, EVENTS, CLICK_ROUTE;
|
let TPL, EVENTS, CLICK_ROUTE;
|
||||||
let widgets = [];
|
let widgets = [];
|
||||||
let fromLine, toLine, styleVariables;
|
let fromLine, toLine, actualStyle;
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
return {toggle};
|
return {toggle};
|
||||||
|
|
||||||
|
@ -29,23 +29,14 @@ function createAppliesToLineWidget(cm) {
|
||||||
$create('label', t('appliesLabel')),
|
$create('label', t('appliesLabel')),
|
||||||
$create('ul.applies-to-list'),
|
$create('ul.applies-to-list'),
|
||||||
]),
|
]),
|
||||||
listItem:
|
listItem: template.appliesTo,
|
||||||
$create('li.applies-to-item', [
|
|
||||||
$create('select.applies-type', [
|
|
||||||
$create('option', {value: 'url'}, t('appliesUrlOption')),
|
|
||||||
$create('option', {value: 'url-prefix'}, t('appliesUrlPrefixOption')),
|
|
||||||
$create('option', {value: 'domain'}, t('appliesDomainOption')),
|
|
||||||
$create('option', {value: 'regexp'}, t('appliesRegexpOption')),
|
|
||||||
]),
|
|
||||||
$create('input.applies-value', {spellcheck: false}),
|
|
||||||
$create('button.test-regexp', t('styleRegexpTestButton')),
|
|
||||||
$create('button.remove-applies-to', t('appliesRemove')),
|
|
||||||
$create('button.add-applies-to', t('appliesAdd')),
|
|
||||||
]),
|
|
||||||
appliesToEverything:
|
appliesToEverything:
|
||||||
$create('li.applies-to-everything', t('appliesToEverything')),
|
$create('li.applies-to-everything', t('appliesToEverything')),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$('button', TPL.listItem).insertAdjacentElement('afterend',
|
||||||
|
$create('button.test-regexp', t('styleRegexpTestButton')));
|
||||||
|
|
||||||
CLICK_ROUTE = {
|
CLICK_ROUTE = {
|
||||||
'.test-regexp': (item, apply) => {
|
'.test-regexp': (item, apply) => {
|
||||||
regExpTester.toggle();
|
regExpTester.toggle();
|
||||||
|
@ -136,15 +127,13 @@ function createAppliesToLineWidget(cm) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
styleVariables = $create('style');
|
actualStyle = $create('style');
|
||||||
fromLine = 0;
|
fromLine = 0;
|
||||||
toLine = cm.doc.size;
|
toLine = cm.doc.size;
|
||||||
|
|
||||||
cm.on('change', onChange);
|
cm.on('change', onChange);
|
||||||
cm.on('optionChange', onOptionChange);
|
cm.on('optionChange', onOptionChange);
|
||||||
|
|
||||||
// is it possible to avoid flickering?
|
|
||||||
window.addEventListener('load', updateWidgetStyle);
|
|
||||||
chrome.runtime.onMessage.addListener(onRuntimeMessage);
|
chrome.runtime.onMessage.addListener(onRuntimeMessage);
|
||||||
|
|
||||||
updateWidgetStyle();
|
updateWidgetStyle();
|
||||||
|
@ -158,9 +147,8 @@ function createAppliesToLineWidget(cm) {
|
||||||
widgets.length = 0;
|
widgets.length = 0;
|
||||||
cm.off('change', onChange);
|
cm.off('change', onChange);
|
||||||
cm.off('optionChange', onOptionChange);
|
cm.off('optionChange', onOptionChange);
|
||||||
window.removeEventListener('load', updateWidgetStyle);
|
|
||||||
chrome.runtime.onMessage.removeListener(onRuntimeMessage);
|
chrome.runtime.onMessage.removeListener(onRuntimeMessage);
|
||||||
styleVariables.remove();
|
actualStyle.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChange(cm, event) {
|
function onChange(cm, event) {
|
||||||
|
@ -229,24 +217,112 @@ function createAppliesToLineWidget(cm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateWidgetStyle() {
|
function updateWidgetStyle() {
|
||||||
const gutterStyle = getComputedStyle(cm.getGutterElement());
|
const MIN_LUMA = .05;
|
||||||
const borderStyle = gutterStyle.borderRightWidth !== '0px' ?
|
const MIN_LUMA_DIFF = .4;
|
||||||
`${gutterStyle.borderRightWidth} ${gutterStyle.borderRightStyle} ${gutterStyle.borderRightColor}` :
|
const color = {
|
||||||
`1px solid ${gutterStyle.color}`;
|
wrapper: getRealColors(cm.display.wrapper),
|
||||||
const id = Date.now();
|
gutter: getRealColors(cm.display.gutters, {
|
||||||
styleVariables.textContent = `
|
bg: 'backgroundColor',
|
||||||
.single-editor {
|
border: 'borderRightColor',
|
||||||
--at-background-color-${id}: ${gutterStyle.backgroundColor};
|
}),
|
||||||
--at-border-top-${id}: ${borderStyle};
|
line: getRealColors('.CodeMirror-linenumber'),
|
||||||
--at-border-bottom-${id}: ${borderStyle};
|
comment: getRealColors('span.cm-comment'),
|
||||||
}
|
};
|
||||||
|
const hasBorder =
|
||||||
|
color.gutter.style.borderRightWidth !== '0px' &&
|
||||||
|
!/transparent|\b0\)/g.test(color.gutter.style.borderRightColor);
|
||||||
|
const diff = {
|
||||||
|
wrapper: Math.abs(color.gutter.bgLuma - color.wrapper.foreLuma),
|
||||||
|
border: hasBorder ? Math.abs(color.gutter.bgLuma - color.gutter.borderLuma) : 0,
|
||||||
|
line: Math.abs(color.gutter.bgLuma - color.line.foreLuma),
|
||||||
|
};
|
||||||
|
const preferLine = diff.line > diff.wrapper || diff.line > MIN_LUMA_DIFF;
|
||||||
|
const fore = preferLine ? color.line.fore : color.wrapper.fore;
|
||||||
|
|
||||||
|
const border = fore.replace(/[\d.]+(?=\))/, MIN_LUMA_DIFF / 2);
|
||||||
|
const borderStyleForced = `1px ${hasBorder ? color.gutter.style.borderRightStyle : 'solid'} ${border}`;
|
||||||
|
|
||||||
|
actualStyle.textContent = `
|
||||||
.applies-to {
|
.applies-to {
|
||||||
background-color: var(--at-background-color-${id});
|
background-color: ${color.gutter.bg};
|
||||||
border-top: var(--at-border-top-${id});
|
border-top: ${borderStyleForced};
|
||||||
border-bottom: var(--at-border-bottom-${id});
|
border-bottom: ${borderStyleForced};
|
||||||
|
}
|
||||||
|
.applies-to label {
|
||||||
|
color: ${fore};
|
||||||
|
}
|
||||||
|
.applies-to input,
|
||||||
|
.applies-to select {
|
||||||
|
background-color: rgba(255, 255, 255, ${
|
||||||
|
Math.max(MIN_LUMA, Math.pow(Math.max(0, color.gutter.bgLuma - MIN_LUMA * 2), 2)).toFixed(2)
|
||||||
|
});
|
||||||
|
border: ${borderStyleForced};
|
||||||
|
transition: none;
|
||||||
|
color: ${fore};
|
||||||
|
}
|
||||||
|
.applies-to .svg-icon.select-arrow {
|
||||||
|
fill: ${fore};
|
||||||
|
transition: none;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
document.documentElement.appendChild(styleVariables);
|
document.documentElement.appendChild(actualStyle);
|
||||||
|
|
||||||
|
function getRealColors(el, targets = {}) {
|
||||||
|
targets.fore = 'color';
|
||||||
|
const colors = {};
|
||||||
|
const done = {};
|
||||||
|
let numDone = 0;
|
||||||
|
let numTotal = 0;
|
||||||
|
for (const k in targets) {
|
||||||
|
colors[k] = {r: 255, g: 255, b: 255, a: 1};
|
||||||
|
numTotal++;
|
||||||
|
}
|
||||||
|
const isDummy = typeof el === 'string';
|
||||||
|
el = isDummy ? cm.display.lineDiv.appendChild($create(el, {style: 'display: none'})) : el;
|
||||||
|
for (let current = el; current; current = current && current.parentElement) {
|
||||||
|
const style = getComputedStyle(current);
|
||||||
|
for (const k in targets) {
|
||||||
|
if (!done[k]) {
|
||||||
|
done[k] = blend(colors[k], style[targets[k]]);
|
||||||
|
numDone += done[k] ? 1 : 0;
|
||||||
|
if (numDone === numTotal) {
|
||||||
|
current = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
colors.style = colors.style || style;
|
||||||
|
}
|
||||||
|
if (isDummy) {
|
||||||
|
el.remove();
|
||||||
|
}
|
||||||
|
for (const k in targets) {
|
||||||
|
const {r, g, b, a} = colors[k];
|
||||||
|
colors[k] = `rgba(${r}, ${g}, ${b}, ${a})`;
|
||||||
|
// https://www.w3.org/TR/AERT#color-contrast
|
||||||
|
colors[k + 'Luma'] = (r * .299 + g * .587 + b * .114) / 256;
|
||||||
|
}
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
function blend(base, color) {
|
||||||
|
const [r, g, b, a = 255] = (color.match(/\d+/g) || []).map(Number);
|
||||||
|
if (a === 255) {
|
||||||
|
base.r = r;
|
||||||
|
base.g = g;
|
||||||
|
base.b = b;
|
||||||
|
base.a = 1;
|
||||||
|
} else if (a) {
|
||||||
|
const mixedA = 1 - (1 - a / 255) * (1 - base.a);
|
||||||
|
const q1 = a / 255 / mixedA;
|
||||||
|
const q2 = base.a * (1 - mixedA) / mixedA;
|
||||||
|
base.r = Math.round(r * q1 + base.r * q2);
|
||||||
|
base.g = Math.round(g * q1 + base.g * q2);
|
||||||
|
base.b = Math.round(b * q1 + base.b * q2);
|
||||||
|
base.a = mixedA;
|
||||||
|
}
|
||||||
|
return Math.abs(base.a - 1) < 1e-3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function doUpdate() {
|
function doUpdate() {
|
||||||
|
|
|
@ -56,7 +56,3 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CodeMirror-activeline .applies-to ul {
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user