Add: use cache template
This commit is contained in:
parent
3fd4343cfd
commit
5dbd2249dd
|
@ -1,6 +1,16 @@
|
||||||
/* global regExpTester debounce messageBox CodeMirror */
|
/* global regExpTester debounce messageBox CodeMirror */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
function templateCache(cache) {
|
||||||
|
function clone(id) {
|
||||||
|
if (typeof cache[id] === 'function') {
|
||||||
|
cache[id] = cache[id]();
|
||||||
|
}
|
||||||
|
return cache[id].cloneNode(true);
|
||||||
|
}
|
||||||
|
return {clone};
|
||||||
|
}
|
||||||
|
|
||||||
function createAppliesToLineWidget(cm) {
|
function createAppliesToLineWidget(cm) {
|
||||||
const APPLIES_TYPE = [
|
const APPLIES_TYPE = [
|
||||||
[t('appliesUrlOption'), 'url'],
|
[t('appliesUrlOption'), 'url'],
|
||||||
|
@ -13,6 +23,57 @@ function createAppliesToLineWidget(cm) {
|
||||||
let fromLine, toLine, styleVariables;
|
let fromLine, toLine, styleVariables;
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
|
|
||||||
|
const template = templateCache({
|
||||||
|
container: () =>
|
||||||
|
$element({className: 'applies-to', appendChild: [
|
||||||
|
$element({tag: 'label', appendChild: t('appliesLabel')}),
|
||||||
|
$element({
|
||||||
|
tag: 'ul',
|
||||||
|
className: 'applies-to-list'
|
||||||
|
})
|
||||||
|
]}),
|
||||||
|
listItem: () =>
|
||||||
|
$element({tag: 'li', appendChild: [
|
||||||
|
$element({
|
||||||
|
tag: 'select',
|
||||||
|
className: 'applies-type',
|
||||||
|
appendChild: APPLIES_TYPE.map(([label, value]) => $element({
|
||||||
|
tag: 'option',
|
||||||
|
value: value,
|
||||||
|
textContent: label
|
||||||
|
}))
|
||||||
|
}),
|
||||||
|
$element({
|
||||||
|
tag: 'input',
|
||||||
|
className: 'applies-value'
|
||||||
|
}),
|
||||||
|
$element({
|
||||||
|
tag: 'button',
|
||||||
|
type: 'button',
|
||||||
|
className: 'applies-to-regexp-test',
|
||||||
|
textContent: t('styleRegexpTestButton')
|
||||||
|
}),
|
||||||
|
$element({
|
||||||
|
tag: 'button',
|
||||||
|
type: 'button',
|
||||||
|
className: 'applies-to-remove',
|
||||||
|
textContent: t('appliesRemove')
|
||||||
|
}),
|
||||||
|
$element({
|
||||||
|
tag: 'button',
|
||||||
|
type: 'button',
|
||||||
|
className: 'applies-to-add',
|
||||||
|
textContent: t('appliesAdd')
|
||||||
|
})
|
||||||
|
]}),
|
||||||
|
appliesToEverything: () =>
|
||||||
|
$element({
|
||||||
|
tag: 'li',
|
||||||
|
className: 'applies-to-everything',
|
||||||
|
textContent: t('appliesToEverything')
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
return {toggle};
|
return {toggle};
|
||||||
|
|
||||||
function toggle(newState = !initialized) {
|
function toggle(newState = !initialized) {
|
||||||
|
@ -240,128 +301,93 @@ function createAppliesToLineWidget(cm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildElement({applies}) {
|
function buildElement({applies}) {
|
||||||
const el = $element({className: 'applies-to', appendChild: [
|
const el = template.clone('container');
|
||||||
$element({tag: 'label', appendChild: [
|
const appliesToList = $('.applies-to-list', el);
|
||||||
t('appliesLabel'),
|
applies.map(makeLi)
|
||||||
// $element({tag: 'svg'})
|
.forEach(item => appliesToList.appendChild(item));
|
||||||
]}),
|
if (!appliesToList.childNodes.length) {
|
||||||
$element({
|
appliesToList.appendChild(template.clone('appliesToEverything'));
|
||||||
tag: 'ul',
|
|
||||||
className: 'applies-to-list',
|
|
||||||
appendChild: applies.map(makeLi)
|
|
||||||
})
|
|
||||||
]});
|
|
||||||
if (!$('li', el)) {
|
|
||||||
$('ul', el).appendChild($element({
|
|
||||||
tag: 'li',
|
|
||||||
className: 'applies-to-everything',
|
|
||||||
textContent: t('appliesToEverything')
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
return el;
|
return el;
|
||||||
|
|
||||||
function makeLi(apply) {
|
function makeLi(apply) {
|
||||||
const el = $element({tag: 'li', appendChild: makeInput(apply)});
|
const el = template.clone('listItem');
|
||||||
el.dataset.type = apply.type.text;
|
el.dataset.type = apply.type.text;
|
||||||
el.addEventListener('change', e => {
|
el.addEventListener('change', e => {
|
||||||
if (e.target.classList.contains('applies-type')) {
|
if (e.target.classList.contains('applies-type')) {
|
||||||
el.dataset.type = apply.type.text;
|
el.dataset.type = apply.type.text;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return el;
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeInput(apply) {
|
const typeInput = $('.applies-type', el);
|
||||||
const typeInput = $element({
|
|
||||||
tag: 'select',
|
|
||||||
className: 'applies-type',
|
|
||||||
appendChild: APPLIES_TYPE.map(([label, value]) => $element({
|
|
||||||
tag: 'option',
|
|
||||||
value: value,
|
|
||||||
textContent: label
|
|
||||||
})),
|
|
||||||
onchange() {
|
|
||||||
applyChange(apply.type, this.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
typeInput.value = apply.type.text;
|
typeInput.value = apply.type.text;
|
||||||
const valueInput = $element({
|
typeInput.onchange = function () {
|
||||||
tag: 'input',
|
applyChange(apply.type, this.value);
|
||||||
className: 'applies-value',
|
};
|
||||||
value: apply.value.text,
|
|
||||||
oninput() {
|
const valueInput = $('.applies-value', el);
|
||||||
debounce(applyChange, THROTTLE_DELAY, apply.value, this.value);
|
valueInput.value = apply.value.text;
|
||||||
},
|
valueInput.oninput = function () {
|
||||||
onfocus: updateRegexpTest
|
debounce(applyChange, THROTTLE_DELAY, apply.value, this.value);
|
||||||
});
|
};
|
||||||
const regexpTestButton = $element({
|
valueInput.onfocus = updateRegexpTest;
|
||||||
tag: 'button',
|
|
||||||
type: 'button',
|
const regexpTestButton = $('.applies-to-regexp-test', el);
|
||||||
className: 'applies-to-regexp-test',
|
regexpTestButton.onclick = () => {
|
||||||
textContent: t('styleRegexpTestButton'),
|
regExpTester.toggle();
|
||||||
onclick() {
|
regExpTester.update([apply.value.text]);
|
||||||
regExpTester.toggle();
|
};
|
||||||
regExpTester.update([apply.value.text]);
|
|
||||||
|
const removeButton = $('.applies-to-remove', el);
|
||||||
|
removeButton.onclick = function () {
|
||||||
|
const i = applies.indexOf(apply);
|
||||||
|
let repl;
|
||||||
|
let from;
|
||||||
|
let to;
|
||||||
|
if (applies.length < 2) {
|
||||||
|
messageBox({
|
||||||
|
contents: chrome.i18n.getMessage('appliesRemoveError'),
|
||||||
|
buttons: [t('confirmClose')]
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
if (i === 0) {
|
||||||
const removeButton = $element({
|
from = apply.mark.find().from;
|
||||||
tag: 'button',
|
to = applies[i + 1].mark.find().from;
|
||||||
type: 'button',
|
repl = '';
|
||||||
className: 'applies-to-remove',
|
} else if (i === applies.length - 1) {
|
||||||
textContent: t('appliesRemove'),
|
from = applies[i - 1].mark.find().to;
|
||||||
onclick() {
|
to = apply.mark.find().to;
|
||||||
const i = applies.indexOf(apply);
|
repl = '';
|
||||||
let repl;
|
} else {
|
||||||
let from;
|
from = applies[i - 1].mark.find().to;
|
||||||
let to;
|
to = applies[i + 1].mark.find().from;
|
||||||
if (applies.length < 2) {
|
repl = ', ';
|
||||||
messageBox({
|
|
||||||
contents: chrome.i18n.getMessage('appliesRemoveError'),
|
|
||||||
buttons: [t('confirmClose')]
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (i === 0) {
|
|
||||||
from = apply.mark.find().from;
|
|
||||||
to = applies[i + 1].mark.find().from;
|
|
||||||
repl = '';
|
|
||||||
} else if (i === applies.length - 1) {
|
|
||||||
from = applies[i - 1].mark.find().to;
|
|
||||||
to = apply.mark.find().to;
|
|
||||||
repl = '';
|
|
||||||
} else {
|
|
||||||
from = applies[i - 1].mark.find().to;
|
|
||||||
to = applies[i + 1].mark.find().from;
|
|
||||||
repl = ', ';
|
|
||||||
}
|
|
||||||
cm.replaceRange(repl, from, to, 'appliesTo');
|
|
||||||
clearApply(apply);
|
|
||||||
this.closest('li').remove();
|
|
||||||
applies.splice(i, 1);
|
|
||||||
}
|
}
|
||||||
});
|
cm.replaceRange(repl, from, to, 'appliesTo');
|
||||||
const addButton = $element({
|
clearApply(apply);
|
||||||
tag: 'button',
|
this.closest('li').remove();
|
||||||
type: 'button',
|
applies.splice(i, 1);
|
||||||
className: 'applies-to-add',
|
};
|
||||||
textContent: t('appliesAdd'),
|
|
||||||
onclick() {
|
const addButton = $('.applies-to-add', el);
|
||||||
const i = applies.indexOf(apply);
|
addButton.onclick = function () {
|
||||||
const pos = apply.mark.find().to;
|
const i = applies.indexOf(apply);
|
||||||
const text = `, ${apply.type.text}("")`;
|
const pos = apply.mark.find().to;
|
||||||
cm.replaceRange(text, pos, pos, 'appliesTo');
|
const text = `, ${apply.type.text}("")`;
|
||||||
const newApply = createApply(
|
cm.replaceRange(text, pos, pos, 'appliesTo');
|
||||||
cm.indexFromPos(pos) + 2,
|
const newApply = createApply(
|
||||||
apply.type.text,
|
cm.indexFromPos(pos) + 2,
|
||||||
'',
|
apply.type.text,
|
||||||
true
|
'',
|
||||||
);
|
true
|
||||||
setupApplyMarkers(newApply);
|
);
|
||||||
applies.splice(i + 1, 0, newApply);
|
setupApplyMarkers(newApply);
|
||||||
this.closest('li').insertAdjacentElement('afterend', makeLi(newApply));
|
applies.splice(i + 1, 0, newApply);
|
||||||
}
|
this.closest('li').insertAdjacentElement('afterend', makeLi(newApply));
|
||||||
});
|
};
|
||||||
return [typeInput, valueInput, regexpTestButton, removeButton, addButton];
|
|
||||||
|
return el;
|
||||||
|
|
||||||
function updateRegexpTest() {
|
function updateRegexpTest() {
|
||||||
if (apply.type.text === 'regexp') {
|
if (apply.type.text === 'regexp') {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user