usercss: use cm.changeGeneration() to detect dirtiness

This commit is contained in:
tophf 2017-11-27 00:45:21 +03:00
parent 76b49af81f
commit 05677d93b3
3 changed files with 63 additions and 91 deletions

View File

@ -113,9 +113,16 @@
uso: 'css' uso: 'css'
}; };
CodeMirror.defineExtension('setPreprocessor', function (preprocessor) { CodeMirror.defineExtension('setPreprocessor', function (preprocessor, force = false) {
const mode = MODE[preprocessor] || 'css'; const mode = MODE[preprocessor] || 'css';
return loadScript(mode !== 'css' && `/vendor/codemirror/mode/${mode}/${mode}.js`).then(() => { if ((this.doc.mode || {}).name === mode && !force) {
return Promise.resolve();
}
if (mode === 'css') {
this.setOption('mode', mode);
return Promise.resolve();
}
return loadScript(`/vendor/codemirror/mode/${mode}/${mode}.js`).then(() => {
this.setOption('mode', mode); this.setOption('mode', mode);
}); });
}); });

View File

@ -1939,46 +1939,20 @@ function showCodeMirrorPopup(title, html, options) {
chrome.runtime.onMessage.addListener(onRuntimeMessage); chrome.runtime.onMessage.addListener(onRuntimeMessage);
function replaceStyle(request) {
const codeIsUpdated = request.codeIsUpdated !== false;
if (!isUsercss(request.style)) {
initWithSectionStyle(request);
return;
}
if (!codeIsUpdated) {
editor.replaceMeta(request.style);
return;
}
askDiscardChanges()
.then(result => {
if (result) {
editor.replaceStyle(request.style);
} else {
editor.setStyleDirty(request.style);
}
});
function askDiscardChanges() {
if (!editor.isTouched()) {
return Promise.resolve(true);
}
return messageBox.confirm(t('styleUpdateDiscardChanges'));
}
}
function onRuntimeMessage(request) { function onRuntimeMessage(request) {
switch (request.method) { switch (request.method) {
case 'styleUpdated': case 'styleUpdated':
if (styleId && styleId === request.style.id && request.reason !== 'editSave' && request.reason !== 'config') { if (styleId && styleId === request.style.id &&
request.reason !== 'editSave' &&
request.reason !== 'config') {
// code-less style from notifyAllTabs
if ((request.style.sections[0] || {}).code === null) { if ((request.style.sections[0] || {}).code === null) {
// the code-less style came from notifyAllTabs
onBackgroundReady().then(() => {
request.style = BG.cachedStyles.byId.get(request.style.id); request.style = BG.cachedStyles.byId.get(request.style.id);
replaceStyle(request); }
}); if (isUsercss(request.style)) {
editor.replaceStyle(request.style, request.codeIsUpdated);
} else { } else {
replaceStyle(request); initWithSectionStyle(request);
} }
} }
break; break;

View File

@ -8,6 +8,7 @@
function createSourceEditor(style) { function createSourceEditor(style) {
// a flag for isTouched() // a flag for isTouched()
let hadBeenSaved = false; let hadBeenSaved = false;
let savedGeneration = 0;
$('#name').disabled = true; $('#name').disabled = true;
$('#mozilla-format-container').remove(); $('#mozilla-format-container').remove();
@ -18,9 +19,8 @@ function createSourceEditor(style) {
const dirty = dirtyReporter(); const dirty = dirtyReporter();
dirty.onChange(() => { dirty.onChange(() => {
const DIRTY = dirty.isDirty(); document.body.classList.toggle('dirty', dirty.isDirty());
document.body.classList.toggle('dirty', DIRTY); $('#save-button').disabled = !dirty.isDirty();
$('#save-button').disabled = !DIRTY;
updateTitle(); updateTitle();
}); });
@ -41,6 +41,7 @@ function createSourceEditor(style) {
cm.setValue(style.sourceCode); cm.setValue(style.sourceCode);
cm.clearHistory(); cm.clearHistory();
cm.markClean(); cm.markClean();
savedGeneration = cm.changeGeneration();
initHooks(); initHooks();
initAppliesToLineWidget(); initAppliesToLineWidget();
@ -101,7 +102,7 @@ function createSourceEditor(style) {
${section} ${section}
`.replace(/^\s+/gm, ''); `.replace(/^\s+/gm, '');
dirty.clear('source'); dirty.clear('sourceGeneration');
style.sourceCode = ''; style.sourceCode = '';
BG.chromeSync.getLZValue('usercssTemplate').then(code => { BG.chromeSync.getLZValue('usercssTemplate').then(code => {
style.sourceCode = code || DEFAULT_CODE; style.sourceCode = code || DEFAULT_CODE;
@ -110,45 +111,35 @@ function createSourceEditor(style) {
cm.clearHistory(); cm.clearHistory();
cm.markClean(); cm.markClean();
cm.endOperation(); cm.endOperation();
dirty.clear('sourceGeneration');
savedGeneration = cm.changeGeneration();
}); });
} }
function initHooks() { function initHooks() {
// sidebar commands
$('#save-button').onclick = save; $('#save-button').onclick = save;
$('#beautify').onclick = beautify; $('#beautify').onclick = beautify;
$('#keyMap-help').onclick = showKeyMapHelp; $('#keyMap-help').onclick = showKeyMapHelp;
$('#toggle-style-help').onclick = showToggleStyleHelp; $('#toggle-style-help').onclick = showToggleStyleHelp;
$('#cancel-button').onclick = goBackToManage; $('#cancel-button').onclick = goBackToManage;
// enable $('#enabled').onchange = function () {
$('#enabled').onchange = e => { const value = this.checked;
const value = e.target.checked;
dirty.modify('enabled', style.enabled, value); dirty.modify('enabled', style.enabled, value);
style.enabled = value; style.enabled = value;
}; };
// source cm.on('changes', () => {
cm.on('change', () => { dirty.modify('sourceGeneration', savedGeneration, cm.changeGeneration());
const value = cm.getValue();
dirty.modify('source', style.sourceCode, value);
style.sourceCode = value;
updateLintReportIfEnabled(cm); updateLintReportIfEnabled(cm);
}); });
// hotkeyRerouter cm.on('focus', () => hotkeyRerouter.setState(false));
cm.on('focus', () => { cm.on('blur', () => hotkeyRerouter.setState(true));
hotkeyRerouter.setState(false);
});
cm.on('blur', () => {
hotkeyRerouter.setState(true);
});
// autocomplete //if (prefs.get('editor.autocompleteOnTyping')) {
if (prefs.get('editor.autocompleteOnTyping')) { // setupAutocomplete(cm);
setupAutocomplete(cm); //}
}
} }
function updateMeta() { function updateMeta() {
@ -170,25 +161,36 @@ function createSourceEditor(style) {
} }
} }
function replaceStyle(newStyle) { function replaceStyle(newStyle, codeIsUpdated) {
const sameCode = newStyle.sourceCode === cm.getValue();
hadBeenSaved = sameCode;
if (sameCode) {
savedGeneration = cm.changeGeneration();
dirty.clear('sourceGeneration');
}
if (codeIsUpdated === false || sameCode) {
style.enabled = newStyle.enabled;
dirty.clear('enabled');
updateMeta();
return;
}
Promise.resolve(messageBox.confirm(t('styleUpdateDiscardChanges'))).then(ok => {
if (!ok) {
return;
}
if (!style.id && newStyle.id) { if (!style.id && newStyle.id) {
history.replaceState({}, '', `?id=${newStyle.id}`); history.replaceState({}, '', `?id=${newStyle.id}`);
} }
style = deepCopy(newStyle); style = deepCopy(newStyle);
updateMeta(); updateMeta();
if (style.sourceCode !== cm.getValue()) { if (!sameCode) {
const cursor = cm.getCursor(); const cursor = cm.getCursor();
cm.setValue(style.sourceCode); cm.setValue(style.sourceCode);
cm.setCursor(cursor); cm.setCursor(cursor);
savedGeneration = cm.changeGeneration();
} }
dirty.clear(); dirty.clear();
hadBeenSaved = false; });
}
function setStyleDirty(newStyle) {
dirty.clear();
dirty.modify('source', newStyle.sourceCode, style.sourceCode);
dirty.modify('enabled', newStyle.enabled, style.enabled);
} }
function toggleStyle() { function toggleStyle() {
@ -209,12 +211,9 @@ function createSourceEditor(style) {
reason: 'editSave', reason: 'editSave',
id: style.id, id: style.id,
enabled: style.enabled, enabled: style.enabled,
sourceCode: style.sourceCode sourceCode: cm.getValue(),
})) }))
.then(replaceStyle) .then(replaceStyle)
.then(() => {
hadBeenSaved = true;
})
.catch(err => { .catch(err => {
if (err.message === t('styleMissingMeta', 'name')) { if (err.message === t('styleMissingMeta', 'name')) {
messageBox.confirm(t('usercssReplaceTemplateConfirmation')).then(ok => ok && messageBox.confirm(t('usercssReplaceTemplateConfirmation')).then(ok => ok &&
@ -257,16 +256,8 @@ function createSourceEditor(style) {
return dirty.isDirty() || hadBeenSaved; return dirty.isDirty() || hadBeenSaved;
} }
function replaceMeta(newStyle) {
style.enabled = newStyle.enabled;
dirty.clear('enabled');
updateMeta();
}
return { return {
replaceStyle, replaceStyle,
replaceMeta,
setStyleDirty,
save, save,
toggleStyle, toggleStyle,
isDirty: dirty.isDirty, isDirty: dirty.isDirty,