show "x" to reset non-default values in usercss config individually

also:
* simplified CSS selectors where possible
* .config-name = var name, 1st element in <label>
* .config-value = var value, 2nd element in <label>
* .nondefault class added on <label>
This commit is contained in:
tophf 2017-12-08 03:23:09 +03:00
parent 3318db1999
commit 2deffbc622
2 changed files with 84 additions and 34 deletions

View File

@ -1,16 +1,15 @@
#stylus-popup #message-box-contents { #stylus-manage .config-dialog #message-box-contents {
padding: .25rem .75rem; padding: 2em 16px;
}
#stylus-popup .config-dialog #message-box-contents {
padding: 8px 16px;
} }
#stylus-popup .config-body label { #stylus-popup .config-body label {
padding: .5em 0; padding: .5em 0;
} }
#stylus-popup .config-body label > :first-child {
max-width: 140px;
min-width: 140px;
}
.config-heading { .config-heading {
float: right; float: right;
margin: -1.25rem 0 0 0; margin: -1.25rem 0 0 0;
@ -21,9 +20,10 @@
display: flex; display: flex;
padding: .75em 0; padding: .75em 0;
align-items: center; align-items: center;
margin-right: -16px; /* for .config-reset-icon */
} }
.config-dialog .select-resizer { .config-body .select-resizer {
position: static; position: static;
} }
@ -39,25 +39,16 @@
border-top: 1px dotted #ccc; border-top: 1px dotted #ccc;
} }
.config-body label > :first-child { .config-body .dirty {
margin-right: 8px; font-style: italic;
flex-grow: 1;
} }
.config-body label:not([disabled]) > :first-child { .config-body .dirty:after {
cursor: default;
}
.config-dialog .dirty:after {
content: "*"; content: "*";
position: absolute; position: absolute;
left: 6px; left: 6px;
} }
.config-dialog .dirty {
font-style: italic;
}
.config-body input, .config-body input,
.config-body select, .config-body select,
.config-body .onoffswitch { .config-body .onoffswitch {
@ -81,21 +72,48 @@
.config-body .onoffswitch { .config-body .onoffswitch {
height: auto; height: auto;
margin: calc((2em - 12px) / 2) 0; margin: calc((2em - 12px) / 2) 0;
flex-grow: 0;
} }
.config-body input[type="text"] { .config-body input[type="text"] {
padding-left: 0.25em; padding-left: 0.25em;
} }
.config-body label > :last-child { .config-name {
flex-grow: 1;
margin-right: 1em;
}
.config-value {
box-sizing: border-box; box-sizing: border-box;
flex-shrink: 0; flex-shrink: 0;
} }
.config-body label > :last-child:not(.onoffswitch):not(.select-resizer) > :not(:last-child) { .config-value:not(.onoffswitch):not(.select-resizer) > :not(:last-child) {
margin-right: 4px; margin-right: 4px;
} }
.config-body label:not(.nondefault) .config-reset-icon {
visibility: hidden;
}
.svg-icon.config-reset-icon {
/*position: absolute;*/
pointer-events: all !important;
cursor: pointer;
/*right: -7px;*/
fill: #aaa;
width: 16px;
height: 16px;
padding: 0 1px;
box-sizing: border-box;
flex-shrink: 0;
}
.svg-icon.config-reset-icon:hover {
fill: #666;
}
#config-autosave-wrapper { #config-autosave-wrapper {
position: relative; position: relative;
padding: 0 0 0 16px; padding: 0 0 0 16px;

View File

@ -72,15 +72,17 @@ function configDialog(style) {
colorpicker.hide(); colorpicker.hide();
} }
function onchange({target}) { function onchange({target, justSaved = false}) {
// invoked after element's own onchange so 'va' contains the updated value // invoked after element's own onchange so 'va' contains the updated value
const va = target.va; const va = target.va;
if (va) { if (va) {
va.dirty = varsInitial[va.name] !== (isDefault(va) ? va.default : va.value); va.dirty = varsInitial[va.name] !== (isDefault(va) ? va.default : va.value);
if (prefs.get('config.autosave')) { if (prefs.get('config.autosave') && !justSaved) {
debounce(save, 0, {anyChangeIsDirty: true}); debounce(save, 0, {anyChangeIsDirty: true});
} else { return;
target.closest('label').classList.toggle('dirty', va.dirty); }
renderValueState(va);
if (!justSaved) {
updateButtons(); updateButtons();
} }
} }
@ -148,7 +150,8 @@ function configDialog(style) {
return BG.usercssHelper.save(style) return BG.usercssHelper.save(style)
.then(saved => { .then(saved => {
varsInitial = getInitialValues(deepCopy(saved.usercssData.vars)); varsInitial = getInitialValues(deepCopy(saved.usercssData.vars));
vars.forEach(va => onchange({target: va.input})); vars.forEach(va => onchange({target: va.input, justSaved: true}));
renderValues();
updateButtons(); updateButtons();
$.remove('.config-error'); $.remove('.config-error');
}) })
@ -172,12 +175,19 @@ function configDialog(style) {
} }
function buildConfigForm() { function buildConfigForm() {
let resetter = $create('SVG:svg.svg-icon.config-reset-icon', {viewBox: '0 0 20 20'}, [
$create('SVG:title', t('genericResetLabel')),
$create('SVG:polygon', {
points: '16.2,5.5 14.5,3.8 10,8.3 5.5,3.8 3.8,5.5 8.3,10 3.8,14.5 ' +
'5.5,16.2 10,11.7 14.5,16.2 16.2,14.5 11.7,10',
}),
]);
for (const va of vars) { for (const va of vars) {
let children; let children;
switch (va.type) { switch (va.type) {
case 'color': case 'color':
children = [ children = [
$create('.cm-colorview', [ $create('.cm-colorview.config-value', [
va.input = $create('.color-swatch', { va.input = $create('.color-swatch', {
va, va,
onclick: showColorpicker onclick: showColorpicker
@ -188,7 +198,7 @@ function configDialog(style) {
case 'checkbox': case 'checkbox':
children = [ children = [
$create('span.onoffswitch', [ $create('span.onoffswitch.config-value', [
va.input = $create('input.slider', { va.input = $create('input.slider', {
va, va,
type: 'checkbox', type: 'checkbox',
@ -204,7 +214,7 @@ function configDialog(style) {
case 'image': case 'image':
// TODO: a image picker input? // TODO: a image picker input?
children = [ children = [
$create('.select-resizer', [ $create('.select-resizer.config-value', [
va.input = $create('select', { va.input = $create('select', {
va, va,
onchange: updateVarOnChange, onchange: updateVarOnChange,
@ -219,7 +229,7 @@ function configDialog(style) {
default: default:
children = [ children = [
va.input = $create('input', { va.input = $create('input.config-value', {
va, va,
type: 'text', type: 'text',
onchange: updateVarOnChange, onchange: updateVarOnChange,
@ -228,10 +238,16 @@ function configDialog(style) {
]; ];
break; break;
} }
resetter = resetter.cloneNode(true);
resetter.va = va;
resetter.onclick = resetOnClick;
elements.push( elements.push(
$create(`label.config-${va.type}`, [ $create(`label.config-${va.type}`, [
$create('span', va.label), $create('span.config-name', tWordBreak(va.label)),
...children, ...children,
resetter,
])); ]));
} }
} }
@ -248,8 +264,8 @@ function configDialog(style) {
} }
} }
function renderValues() { function renderValues(varsToRender = vars) {
for (const va of vars) { for (const va of varsToRender) {
const value = isDefault(va) ? va.default : va.value; const value = isDefault(va) ? va.default : va.value;
if (va.type === 'color') { if (va.type === 'color') {
va.input.style.backgroundColor = value; va.input.style.backgroundColor = value;
@ -261,8 +277,24 @@ function configDialog(style) {
} else { } else {
va.input.value = value; va.input.value = value;
} }
if (!prefs.get('config.autosave')) {
renderValueState(va);
} }
} }
}
function renderValueState(va) {
const el = va.input.closest('label');
el.classList.toggle('dirty', Boolean(va.dirty));
el.classList.toggle('nondefault', !isDefault(va));
}
function resetOnClick(event) {
event.preventDefault();
this.va.value = null;
renderValues([this.va]);
onchange({target: this.va.input});
}
function showColorpicker() { function showColorpicker() {
window.removeEventListener('keydown', messageBox.listeners.key, true); window.removeEventListener('keydown', messageBox.listeners.key, true);