Merge remote-tracking branch 'upstream/master'
* upstream/master: (45 commits) Alas, poor clamp! I knew it well Update number input on blur Don't re-render input while focused Fix undefined value Update current value in updateRangeCurrentValue Remove onblur, don't save invalid inputs Change stored number value on change Remove isNumber function Fix isNumber function Change clamp function order & only call onblur Remove misleading comment Fix strict equals Fix clamp function Check for null in isNumber Fix clamp function Fix clamp undefined step Fix clamp undefined min/max Switch to isNumber function More suggested changes Remove unnecessary css ...
This commit is contained in:
commit
5a8936e15e
|
@ -1051,6 +1051,15 @@
|
|||
},
|
||||
"description": "Error displayed when the value of @var color is invalid"
|
||||
},
|
||||
"styleMetaErrorRangeOrNumber": {
|
||||
"message": "Invalid @var $type$: value must be an array containing at least one number at index zero",
|
||||
"description": "Error displayed when the value of @var number or @var range is invalid",
|
||||
"placeholders": {
|
||||
"type": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorPreprocessor": {
|
||||
"message": "Unsupported @preprocessor: $preprocessor$",
|
||||
"placeholders": {
|
||||
|
|
|
@ -29,7 +29,7 @@ var usercss = (() => {
|
|||
['version', 0],
|
||||
]);
|
||||
const MANDATORY_META = ['name', 'namespace', 'version'];
|
||||
const META_VARS = ['text', 'color', 'checkbox', 'select', 'dropdown', 'image'];
|
||||
const META_VARS = ['text', 'color', 'checkbox', 'select', 'dropdown', 'image', 'number', 'range'];
|
||||
const META_URLS = [...KNOWN_META.keys()].filter(k => k.endsWith('URL'));
|
||||
|
||||
const BUILDER = {
|
||||
|
@ -194,12 +194,40 @@ var usercss = (() => {
|
|||
state.errorPrefix = 'Invalid JSON: ';
|
||||
parseJSONValue(state);
|
||||
state.errorPrefix = '';
|
||||
const extractDefaultOption = (key, value) => {
|
||||
if (key.endsWith('*')) {
|
||||
const option = createOption(key.slice(0, -1), value);
|
||||
result.default = option.name;
|
||||
return option;
|
||||
}
|
||||
return createOption(key, value);
|
||||
};
|
||||
if (Array.isArray(state.value)) {
|
||||
result.options = state.value.map(text => createOption(text));
|
||||
result.options = state.value.map(k => extractDefaultOption(k));
|
||||
} else {
|
||||
result.options = Object.keys(state.value).map(k => createOption(k, state.value[k]));
|
||||
result.options = Object.keys(state.value).map(k => extractDefaultOption(k, state.value[k]));
|
||||
}
|
||||
if (result.default === null) {
|
||||
result.default = (result.options[0] || {}).name || '';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'number':
|
||||
case 'range': {
|
||||
state.errorPrefix = 'Invalid JSON: ';
|
||||
parseJSONValue(state);
|
||||
state.errorPrefix = '';
|
||||
// [default, start, end, step, units] (start, end, step & units are optional)
|
||||
if (Array.isArray(state.value) && state.value.length) {
|
||||
// label may be placed anywhere
|
||||
result.units = (state.value.find(i => typeof i === 'string') || '').replace(/[\d.+-]/g, '');
|
||||
const range = state.value.filter(i => typeof i === 'number' || i === null);
|
||||
result.default = range[0];
|
||||
result.min = range[1];
|
||||
result.max = range[2];
|
||||
result.step = range[3] === 0 ? 1 : range[3];
|
||||
}
|
||||
result.default = (result.options[0] || {}).name || '';
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -541,6 +569,9 @@ var usercss = (() => {
|
|||
// TODO: handle customized image
|
||||
return va.options.find(o => o.name === va[prop]).value;
|
||||
}
|
||||
if ((va.type === 'number' || va.type === 'range') && va.units) {
|
||||
return va[prop] + va.units;
|
||||
}
|
||||
return va[prop];
|
||||
}
|
||||
|
||||
|
@ -578,6 +609,8 @@ var usercss = (() => {
|
|||
throw new Error(chrome.i18n.getMessage('styleMetaErrorCheckbox'));
|
||||
} else if (va.type === 'color') {
|
||||
va[value] = colorConverter.format(colorConverter.parse(va[value]), 'rgb');
|
||||
} else if ((va.type === 'number' || va.type === 'range') && typeof va[value] !== 'number') {
|
||||
throw new Error(chrome.i18n.getMessage('styleMetaErrorRangeOrNumber', va.type));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,15 @@
|
|||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.current-value {
|
||||
padding: 2px 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.config-number span, .config-range span {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.config-body label:not(.nondefault) .config-reset-icon {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
|
|
@ -258,16 +258,44 @@ function configDialog(style) {
|
|||
];
|
||||
break;
|
||||
|
||||
case 'range':
|
||||
case 'number': {
|
||||
const options = {
|
||||
va,
|
||||
type: va.type,
|
||||
onfocus: va.type === 'number' ? selectAllOnFocus : null,
|
||||
onblur: va.type === 'number' ? updateVarOnBlur : null,
|
||||
onchange: updateVarOnChange,
|
||||
oninput: updateVarOnInput,
|
||||
required: true
|
||||
};
|
||||
if (typeof va.min === 'number') {
|
||||
options.min = va.min;
|
||||
}
|
||||
if (typeof va.max === 'number') {
|
||||
options.max = va.max;
|
||||
}
|
||||
if (typeof va.step === 'number' && isFinite(va.step)) {
|
||||
options.step = va.step;
|
||||
}
|
||||
children = [
|
||||
va.type === 'range' && $create('span.current-value'),
|
||||
va.input = $create('input.config-value', options)
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
children = [
|
||||
va.input = $create('input.config-value', {
|
||||
va,
|
||||
type: 'text',
|
||||
type: va.type,
|
||||
onchange: updateVarOnChange,
|
||||
oninput: updateVarOnInput,
|
||||
onfocus: selectAllOnFocus,
|
||||
}),
|
||||
];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
resetter = resetter.cloneNode(true);
|
||||
|
@ -285,8 +313,28 @@ function configDialog(style) {
|
|||
}
|
||||
}
|
||||
|
||||
function updateVarOnBlur() {
|
||||
this.value = isDefault(this.va) ? this.va.default : this.va.value;
|
||||
}
|
||||
|
||||
function updateVarOnChange() {
|
||||
this.va.value = this.type !== 'checkbox' ? this.value : this.checked ? '1' : '0';
|
||||
if (this.type === 'range') {
|
||||
this.va.value = Number(this.value);
|
||||
updateRangeCurrentValue(this.va, this.va.value);
|
||||
} else if (this.type === 'number') {
|
||||
if (this.reportValidity()) {
|
||||
this.va.value = Number(this.value);
|
||||
}
|
||||
} else {
|
||||
this.va.value = this.type !== 'checkbox' ? this.value : this.checked ? '1' : '0';
|
||||
}
|
||||
}
|
||||
|
||||
function updateRangeCurrentValue(va, value) {
|
||||
const span = $('.current-value', va.input.closest('.config-range'));
|
||||
if (span) {
|
||||
span.textContent = value + (va.units || '');
|
||||
}
|
||||
}
|
||||
|
||||
function updateVarOnInput(event, debounced = false) {
|
||||
|
@ -297,8 +345,15 @@ function configDialog(style) {
|
|||
}
|
||||
}
|
||||
|
||||
function selectAllOnFocus(event) {
|
||||
event.target.select();
|
||||
}
|
||||
|
||||
function renderValues(varsToRender = vars) {
|
||||
for (const va of varsToRender) {
|
||||
if (va.input === document.activeElement) {
|
||||
continue;
|
||||
}
|
||||
const value = isDefault(va) ? va.default : va.value;
|
||||
if (va.type === 'color') {
|
||||
va.input.style.backgroundColor = value;
|
||||
|
@ -307,6 +362,9 @@ function configDialog(style) {
|
|||
}
|
||||
} else if (va.type === 'checkbox') {
|
||||
va.input.checked = Number(value);
|
||||
} else if (va.type === 'range') {
|
||||
va.input.value = value;
|
||||
updateRangeCurrentValue(va, va.input.value);
|
||||
} else {
|
||||
va.input.value = value;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user