throttle mozImport after 100ms, display progress after 500ms
* Ctrl-Enter = append button * Shift-Ctrl-Enter = replace button * instantaneous readiness of import dialog on non-blank input * code dedup: addSections() * trimNewLines() -> trim()
This commit is contained in:
parent
102b5e03d4
commit
8517e392fe
170
edit/edit.js
170
edit/edit.js
|
@ -1360,45 +1360,56 @@ function isUsercss(style) {
|
||||||
|
|
||||||
function initWithSectionStyle({style, codeIsUpdated}) {
|
function initWithSectionStyle({style, codeIsUpdated}) {
|
||||||
setStyleMeta(style);
|
setStyleMeta(style);
|
||||||
|
if (codeIsUpdated !== false) {
|
||||||
if (codeIsUpdated === false) {
|
|
||||||
setCleanGlobal();
|
|
||||||
updateTitle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// if this was done in response to an update, we need to clear existing sections
|
|
||||||
editors.length = 0;
|
editors.length = 0;
|
||||||
getSections().forEach(div => div.remove());
|
getSections().forEach(div => div.remove());
|
||||||
const queue = style.sections.length ? style.sections.slice() : [{code: ''}];
|
addSections(style.sections.length ? style.sections : [{code: ''}]);
|
||||||
const t0 = performance.now();
|
|
||||||
maximizeCodeHeight.stats = null;
|
|
||||||
// after 100ms the sections will be added asynchronously
|
|
||||||
while (performance.now() - t0 <= 100 && queue.length) {
|
|
||||||
add();
|
|
||||||
}
|
|
||||||
(function processQueue() {
|
|
||||||
if (queue.length) {
|
|
||||||
add();
|
|
||||||
setTimeout(processQueue);
|
|
||||||
if (performance.now() - t0 > 500) {
|
|
||||||
setGlobalProgress(editors.length, style.sections.length);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setGlobalProgress();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
editors[0].focus();
|
|
||||||
initHooks();
|
initHooks();
|
||||||
|
}
|
||||||
setCleanGlobal();
|
setCleanGlobal();
|
||||||
updateTitle();
|
updateTitle();
|
||||||
|
}
|
||||||
|
|
||||||
function add() {
|
function addSections(sections, onAdded = () => {}) {
|
||||||
const sectionDiv = addSection(null, queue.shift());
|
if (addSections.running) {
|
||||||
maximizeCodeHeight(sectionDiv, !queue.length);
|
console.error('addSections cannot be re-entered: please report to the developers');
|
||||||
if (!queue.length) {
|
// TODO: handle this properly e.g. on update/import
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addSections.running = true;
|
||||||
|
maximizeCodeHeight.stats = null;
|
||||||
|
// make a shallow copy since we might run asynchronously
|
||||||
|
// and the original array might get modified
|
||||||
|
sections = sections.slice();
|
||||||
|
const t0 = performance.now();
|
||||||
|
const divs = [];
|
||||||
|
let index = 0;
|
||||||
|
return new Promise(function run(resolve) {
|
||||||
|
while (index < sections.length) {
|
||||||
|
const div = addSection(null, sections[index]);
|
||||||
|
maximizeCodeHeight(div, index === sections.length - 1);
|
||||||
|
onAdded(div, index);
|
||||||
|
divs.push(div);
|
||||||
|
index++;
|
||||||
|
const elapsed = performance.now() - t0;
|
||||||
|
if (elapsed > 500) {
|
||||||
|
setGlobalProgress(index, sections.length);
|
||||||
|
}
|
||||||
|
if (elapsed > 100) {
|
||||||
|
// after 100ms the sections are added asynchronously
|
||||||
|
setTimeout(run, 0, resolve);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (divs[0]) {
|
||||||
|
makeSectionVisible(divs[0].CodeMirror);
|
||||||
|
divs[0].CodeMirror.focus();
|
||||||
|
}
|
||||||
editors.last.state.renderLintReportNow = true;
|
editors.last.state.renderLintReportNow = true;
|
||||||
}
|
addSections.running = false;
|
||||||
}
|
setGlobalProgress();
|
||||||
|
resolve(divs);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupOptionsExpand() {
|
function setupOptionsExpand() {
|
||||||
|
@ -1657,75 +1668,62 @@ function fromMozillaFormat() {
|
||||||
name: 'import-replace',
|
name: 'import-replace',
|
||||||
textContent: t('importReplaceLabel'),
|
textContent: t('importReplaceLabel'),
|
||||||
title: t('importReplaceTooltip'),
|
title: t('importReplaceTooltip'),
|
||||||
onclick: doImport,
|
onclick: () => doImport({replaceOldStyle: true}),
|
||||||
}),
|
}),
|
||||||
]}));
|
]}));
|
||||||
|
|
||||||
const contents = $('.contents', popup);
|
const contents = $('.contents', popup);
|
||||||
contents.insertBefore(popup.codebox.display.wrapper, contents.firstElementChild);
|
contents.insertBefore(popup.codebox.display.wrapper, contents.firstElementChild);
|
||||||
popup.codebox.focus();
|
popup.codebox.focus();
|
||||||
popup.codebox.on('change', () => {
|
popup.codebox.on('changes', cm => {
|
||||||
clearTimeout(popup.mozillaTimeout);
|
popup.classList.toggle('ready', !cm.isBlank());
|
||||||
popup.mozillaTimeout = setTimeout(() => {
|
|
||||||
popup.classList.toggle('ready', trimNewLines(popup.codebox.getValue()));
|
|
||||||
}, 100);
|
|
||||||
});
|
});
|
||||||
|
// overwrite default extraKeys as those are inapplicable in popup context
|
||||||
|
popup.codebox.options.extraKeys = {
|
||||||
|
'Ctrl-Enter': doImport,
|
||||||
|
'Shift-Ctrl-Enter': () => doImport({replaceOldStyle: true}),
|
||||||
|
};
|
||||||
|
|
||||||
function doImport(event) {
|
function doImport({replaceOldStyle = false}) {
|
||||||
const replaceOldStyle = event.target.name === 'import-replace';
|
lockPageUI(true);
|
||||||
const mozStyle = trimNewLines(popup.codebox.getValue());
|
new Promise(setTimeout)
|
||||||
|
.then(() => mozParser.parse(popup.codebox.getValue().trim()))
|
||||||
mozParser.parse(mozStyle)
|
.then(sections => {
|
||||||
.then(updateSection)
|
removeOldSections(replaceOldStyle);
|
||||||
.then(() => {
|
return addSections(sections, div => setCleanItem(div, false));
|
||||||
editors.forEach(cm => updateLintReportIfEnabled(cm, 1));
|
})
|
||||||
editors.last.state.renderLintReportNow = true;
|
.then(sectionDivs => {
|
||||||
|
sectionDivs.forEach(div => updateLintReportIfEnabled(div.CodeMirror, 1));
|
||||||
$('.dismiss', popup).onclick();
|
$('.dismiss', popup).onclick();
|
||||||
})
|
})
|
||||||
.catch(showError);
|
.catch(showError)
|
||||||
|
.then(() => lockPageUI(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeOldSections(removeAll) {
|
||||||
|
let toRemove;
|
||||||
|
if (removeAll) {
|
||||||
|
toRemove = editors.slice().reverse();
|
||||||
|
} else if (editors.last.isBlank() && $('.applies-to-everything', editors.last.getSection())) {
|
||||||
|
toRemove = [editors.last];
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toRemove.forEach(cm => removeSection({target: cm.getSection()}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function lockPageUI(locked) {
|
||||||
|
document.documentElement.style.pointerEvents = locked ? 'none' : '';
|
||||||
|
popup.classList.toggle('ready', locked ? false : !popup.codebox.isBlank());
|
||||||
|
popup.codebox.options.readOnly = locked;
|
||||||
|
popup.codebox.display.wrapper.style.opacity = locked ? '.5' : '';
|
||||||
|
}
|
||||||
|
|
||||||
function showError(errors) {
|
function showError(errors) {
|
||||||
if (!Array.isArray(errors)) {
|
|
||||||
errors = [errors];
|
|
||||||
}
|
|
||||||
showHelp(t('styleFromMozillaFormatError'), $element({
|
showHelp(t('styleFromMozillaFormatError'), $element({
|
||||||
tag: 'pre',
|
tag: 'pre',
|
||||||
textContent: errors.join('\n'),
|
textContent: Array.isArray(errors) ? errors.join('\n') : errors,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSection(sections) {
|
|
||||||
if (replaceOldStyle) {
|
|
||||||
editors.slice(0).reverse().forEach(cm => {
|
|
||||||
removeSection({target: cm.getSection().firstElementChild});
|
|
||||||
});
|
|
||||||
} else if (!editors.last.getValue()) {
|
|
||||||
// nuke the last blank section
|
|
||||||
if ($('.applies-to-everything', editors.last.getSection())) {
|
|
||||||
removeSection({target: editors.last.getSection()});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstSection = sections[0];
|
|
||||||
setCleanItem(addSection(null, firstSection), false);
|
|
||||||
const firstAddedCM = editors.last;
|
|
||||||
for (const section of sections.slice(1)) {
|
|
||||||
setCleanItem(addSection(null, section), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete maximizeCodeHeight.stats;
|
|
||||||
editors.forEach(cm => {
|
|
||||||
maximizeCodeHeight(cm.getSection(), cm === editors.last);
|
|
||||||
});
|
|
||||||
|
|
||||||
makeSectionVisible(firstAddedCM);
|
|
||||||
firstAddedCM.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function trimNewLines(s) {
|
|
||||||
return s.replace(/^[\s\n]+/, '').replace(/[\s\n]+$/, '');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSectionHelp() {
|
function showSectionHelp() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user