From 05677d93b3146addef2d556208e67093120857df Mon Sep 17 00:00:00 2001 From: tophf Date: Mon, 27 Nov 2017 00:45:21 +0300 Subject: [PATCH] usercss: use cm.changeGeneration() to detect dirtiness --- edit/codemirror-default.js | 11 ++++- edit/edit.js | 44 ++++------------- edit/source-editor.js | 99 +++++++++++++++++--------------------- 3 files changed, 63 insertions(+), 91 deletions(-) diff --git a/edit/codemirror-default.js b/edit/codemirror-default.js index 1c532e5a..78627713 100644 --- a/edit/codemirror-default.js +++ b/edit/codemirror-default.js @@ -113,9 +113,16 @@ uso: 'css' }; - CodeMirror.defineExtension('setPreprocessor', function (preprocessor) { + CodeMirror.defineExtension('setPreprocessor', function (preprocessor, force = false) { 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); }); }); diff --git a/edit/edit.js b/edit/edit.js index 75ae8855..ac1e8a98 100644 --- a/edit/edit.js +++ b/edit/edit.js @@ -1939,46 +1939,20 @@ function showCodeMirrorPopup(title, html, options) { 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) { switch (request.method) { 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) { - // the code-less style came from notifyAllTabs - onBackgroundReady().then(() => { - request.style = BG.cachedStyles.byId.get(request.style.id); - replaceStyle(request); - }); + request.style = BG.cachedStyles.byId.get(request.style.id); + } + if (isUsercss(request.style)) { + editor.replaceStyle(request.style, request.codeIsUpdated); } else { - replaceStyle(request); + initWithSectionStyle(request); } } break; diff --git a/edit/source-editor.js b/edit/source-editor.js index b6ef422e..47438e07 100644 --- a/edit/source-editor.js +++ b/edit/source-editor.js @@ -8,6 +8,7 @@ function createSourceEditor(style) { // a flag for isTouched() let hadBeenSaved = false; + let savedGeneration = 0; $('#name').disabled = true; $('#mozilla-format-container').remove(); @@ -18,9 +19,8 @@ function createSourceEditor(style) { const dirty = dirtyReporter(); dirty.onChange(() => { - const DIRTY = dirty.isDirty(); - document.body.classList.toggle('dirty', DIRTY); - $('#save-button').disabled = !DIRTY; + document.body.classList.toggle('dirty', dirty.isDirty()); + $('#save-button').disabled = !dirty.isDirty(); updateTitle(); }); @@ -41,6 +41,7 @@ function createSourceEditor(style) { cm.setValue(style.sourceCode); cm.clearHistory(); cm.markClean(); + savedGeneration = cm.changeGeneration(); initHooks(); initAppliesToLineWidget(); @@ -101,7 +102,7 @@ function createSourceEditor(style) { ${section} `.replace(/^\s+/gm, ''); - dirty.clear('source'); + dirty.clear('sourceGeneration'); style.sourceCode = ''; BG.chromeSync.getLZValue('usercssTemplate').then(code => { style.sourceCode = code || DEFAULT_CODE; @@ -110,45 +111,35 @@ function createSourceEditor(style) { cm.clearHistory(); cm.markClean(); cm.endOperation(); + dirty.clear('sourceGeneration'); + savedGeneration = cm.changeGeneration(); }); } function initHooks() { - // sidebar commands $('#save-button').onclick = save; $('#beautify').onclick = beautify; $('#keyMap-help').onclick = showKeyMapHelp; $('#toggle-style-help').onclick = showToggleStyleHelp; $('#cancel-button').onclick = goBackToManage; - // enable - $('#enabled').onchange = e => { - const value = e.target.checked; + $('#enabled').onchange = function () { + const value = this.checked; dirty.modify('enabled', style.enabled, value); style.enabled = value; }; - // source - cm.on('change', () => { - const value = cm.getValue(); - dirty.modify('source', style.sourceCode, value); - style.sourceCode = value; - + cm.on('changes', () => { + dirty.modify('sourceGeneration', savedGeneration, cm.changeGeneration()); updateLintReportIfEnabled(cm); }); - // hotkeyRerouter - cm.on('focus', () => { - hotkeyRerouter.setState(false); - }); - cm.on('blur', () => { - hotkeyRerouter.setState(true); - }); + cm.on('focus', () => hotkeyRerouter.setState(false)); + cm.on('blur', () => hotkeyRerouter.setState(true)); - // autocomplete - if (prefs.get('editor.autocompleteOnTyping')) { - setupAutocomplete(cm); - } + //if (prefs.get('editor.autocompleteOnTyping')) { + // setupAutocomplete(cm); + //} } function updateMeta() { @@ -170,25 +161,36 @@ function createSourceEditor(style) { } } - function replaceStyle(newStyle) { - if (!style.id && newStyle.id) { - history.replaceState({}, '', `?id=${newStyle.id}`); + function replaceStyle(newStyle, codeIsUpdated) { + const sameCode = newStyle.sourceCode === cm.getValue(); + hadBeenSaved = sameCode; + if (sameCode) { + savedGeneration = cm.changeGeneration(); + dirty.clear('sourceGeneration'); } - style = deepCopy(newStyle); - updateMeta(); - if (style.sourceCode !== cm.getValue()) { - const cursor = cm.getCursor(); - cm.setValue(style.sourceCode); - cm.setCursor(cursor); + if (codeIsUpdated === false || sameCode) { + style.enabled = newStyle.enabled; + dirty.clear('enabled'); + updateMeta(); + return; } - dirty.clear(); - hadBeenSaved = false; - } - - function setStyleDirty(newStyle) { - dirty.clear(); - dirty.modify('source', newStyle.sourceCode, style.sourceCode); - dirty.modify('enabled', newStyle.enabled, style.enabled); + Promise.resolve(messageBox.confirm(t('styleUpdateDiscardChanges'))).then(ok => { + if (!ok) { + return; + } + if (!style.id && newStyle.id) { + history.replaceState({}, '', `?id=${newStyle.id}`); + } + style = deepCopy(newStyle); + updateMeta(); + if (!sameCode) { + const cursor = cm.getCursor(); + cm.setValue(style.sourceCode); + cm.setCursor(cursor); + savedGeneration = cm.changeGeneration(); + } + dirty.clear(); + }); } function toggleStyle() { @@ -209,12 +211,9 @@ function createSourceEditor(style) { reason: 'editSave', id: style.id, enabled: style.enabled, - sourceCode: style.sourceCode + sourceCode: cm.getValue(), })) .then(replaceStyle) - .then(() => { - hadBeenSaved = true; - }) .catch(err => { if (err.message === t('styleMissingMeta', 'name')) { messageBox.confirm(t('usercssReplaceTemplateConfirmation')).then(ok => ok && @@ -257,16 +256,8 @@ function createSourceEditor(style) { return dirty.isDirty() || hadBeenSaved; } - function replaceMeta(newStyle) { - style.enabled = newStyle.enabled; - dirty.clear('enabled'); - updateMeta(); - } - return { replaceStyle, - replaceMeta, - setStyleDirty, save, toggleStyle, isDirty: dirty.isDirty,