edit: throttle setOption for 'theme' and 'lineWrapping'
when the style has more than 4 sections, these options are propagated to CM instances in 100 ms chunks, and a progress overlay is shown over the corresponding option element after 100 ms
This commit is contained in:
parent
a8796b0bd2
commit
3d0b811b27
|
@ -134,6 +134,12 @@ h2 .svg-icon, label .svg-icon {
|
|||
#options .option > * {
|
||||
padding-right: 0.25rem;
|
||||
}
|
||||
.set-option-progress {
|
||||
position: absolute;
|
||||
background-color: currentColor;
|
||||
content: "";
|
||||
opacity: .15;
|
||||
}
|
||||
/************ content ***********/
|
||||
#sections > div {
|
||||
margin: 0.7rem;
|
||||
|
|
81
edit/edit.js
81
edit/edit.js
|
@ -269,6 +269,10 @@ function initCodeMirror() {
|
|||
CM.getOption = o => CodeMirror.defaults[o];
|
||||
CM.setOption = (o, v) => {
|
||||
CodeMirror.defaults[o] = v;
|
||||
if (editors.length > 4 && (o === 'theme' || o === 'lineWrapping')) {
|
||||
throttleSetOption({key: o, value: v, index: 0});
|
||||
return;
|
||||
}
|
||||
editors.forEach(editor => {
|
||||
editor.setOption(o, v);
|
||||
});
|
||||
|
@ -306,6 +310,83 @@ function initCodeMirror() {
|
|||
setupLivePrefs();
|
||||
|
||||
hotkeyRerouter.setState(true);
|
||||
|
||||
const THROTTLE_AFTER_MS = 100;
|
||||
const THROTTLE_SHOW_PROGRESS_AFTER_MS = 100;
|
||||
|
||||
function throttleSetOption({
|
||||
key,
|
||||
value,
|
||||
index,
|
||||
timeStart = performance.now(),
|
||||
cmStart = editors.lastActive || editors[0],
|
||||
editorsCopy = editors.slice(),
|
||||
progress,
|
||||
}) {
|
||||
if (index === 0) {
|
||||
if (!cmStart) {
|
||||
return;
|
||||
}
|
||||
cmStart.setOption(key, value);
|
||||
}
|
||||
const t0 = performance.now();
|
||||
const total = editorsCopy.length;
|
||||
while (index < total) {
|
||||
const cm = editorsCopy[index++];
|
||||
if (cm === cmStart ||
|
||||
cm !== editors[index] && !editors.includes(cm)) {
|
||||
continue;
|
||||
}
|
||||
cm.setOption(key, value);
|
||||
if (performance.now() - t0 > THROTTLE_AFTER_MS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index >= total) {
|
||||
if (progress) {
|
||||
progress.remove();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!progress &&
|
||||
index < total / 2 &&
|
||||
t0 - timeStart > THROTTLE_SHOW_PROGRESS_AFTER_MS) {
|
||||
let option = $('#editor.' + key);
|
||||
if (option) {
|
||||
if (option.type === 'checkbox') {
|
||||
option = (option.labels || [])[0] || option.nextElementSibling || option;
|
||||
}
|
||||
progress = document.body.appendChild($element({
|
||||
className: 'set-option-progress',
|
||||
targetElement: option,
|
||||
}));
|
||||
}
|
||||
}
|
||||
if (progress) {
|
||||
const optionBounds = progress.targetElement.getBoundingClientRect();
|
||||
const bounds = {
|
||||
top: optionBounds.top + window.scrollY + 1,
|
||||
left: optionBounds.left + window.scrollX + 1,
|
||||
width: (optionBounds.width - 2) * index / total | 0,
|
||||
height: optionBounds.height - 2,
|
||||
};
|
||||
const style = progress.style;
|
||||
for (const prop in bounds) {
|
||||
if (bounds[prop] !== parseFloat(style[prop])) {
|
||||
style[prop] = bounds[prop] + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
setTimeout(throttleSetOption, 0, {
|
||||
key,
|
||||
value,
|
||||
index,
|
||||
timeStart,
|
||||
cmStart,
|
||||
editorsCopy,
|
||||
progress,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function acmeEventListener(event) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user