From 022e588c9709017dc8232ea01bd6bba467eaadf2 Mon Sep 17 00:00:00 2001 From: tophf Date: Sun, 7 Jan 2018 16:36:30 +0300 Subject: [PATCH] allow errors in usercss when saving in editor and live-reloading --- background/usercss-helper.js | 61 ++++++++++++++---------------- edit/source-editor.js | 9 +++-- install-usercss/install-usercss.js | 9 +++-- js/usercss.js | 17 +++++++-- 4 files changed, 53 insertions(+), 43 deletions(-) diff --git a/background/usercss-helper.js b/background/usercss-helper.js index 274ff37c..33275e3e 100644 --- a/background/usercss-helper.js +++ b/background/usercss-helper.js @@ -4,6 +4,7 @@ (() => { API_METHODS.saveUsercss = save; + API_METHODS.saveUsercssUnsafe = style => save(style, true); API_METHODS.buildUsercss = build; API_METHODS.installUsercss = install; @@ -47,60 +48,56 @@ } } - function buildCode(style) { - return usercss.buildCode(style); - } - // Parse the source and find the duplication function build({sourceCode, checkDup = false}) { return buildMeta({sourceCode}) - .then(style => Promise.all([ - buildCode(style), - checkDup && findDup(style) - ])) - .then(([style, dup]) => ({style, dup})); + .then(usercss.buildCode) + .then(style => ({ + style, + dup: checkDup && findDup(style), + })); } - function save(style) { + function save(style, allowErrors = false) { // restore if stripped by getStyleWithNoCode if (typeof style.sourceCode !== 'string') { style.sourceCode = cachedStyles.byId.get(style.id).sourceCode; } return buildMeta(style) .then(assignVars) - .then(buildCode) - .then(saveStyle); + .then(style => usercss.buildCode(style, allowErrors)) + .then(result => + allowErrors ? + saveStyle(result.style).then(style => ({style, errors: result.errors})) : + saveStyle(result)); function assignVars(style) { if (style.reason === 'config' && style.id) { return style; } - return findDup(style).then(dup => { - if (dup) { - style.id = dup.id; - if (style.reason !== 'config') { - // preserve style.vars during update - usercss.assignVars(style, dup); - } + const dup = findDup(style); + if (dup) { + style.id = dup.id; + if (style.reason !== 'config') { + // preserve style.vars during update + usercss.assignVars(style, dup); } - return style; - }); + } + return style; } } function findDup(style) { - if (style.id) { - return getStyles({id: style.id}).then(s => s[0]); + if (style.id) return cachedStyles.byId.get(style.id); + const {name, namespace} = style.usercssData; + for (const dup of cachedStyles.list) { + const data = dup.usercssData; + if (!data) continue; + if (data.name === name && + data.namespace === namespace) { + return dup; + } } - return getStyles().then(styles => - styles.find(target => { - if (!target.usercssData) { - return false; - } - return target.usercssData.name === style.usercssData.name && - target.usercssData.namespace === style.usercssData.namespace; - }) - ); } function install({url, direct, downloaded, tab}, sender) { diff --git a/edit/source-editor.js b/edit/source-editor.js index b3e22a68..568fb4e0 100644 --- a/edit/source-editor.js +++ b/edit/source-editor.js @@ -192,13 +192,16 @@ function createSourceEditor(style) { if (!dirty.isDirty()) return; const code = cm.getValue(); return ( - API.saveUsercss({ - reason: 'editSave', + API.saveUsercssUnsafe({ id: style.id, + reason: 'editSave', enabled: style.enabled, sourceCode: code, })) - .then(replaceStyle) + .then(({style, errors}) => { + replaceStyle(style); + if (errors) return Promise.reject(errors); + }) .catch(err => { if (err.message === t('styleMissingMeta', 'name')) { messageBox.confirm(t('usercssReplaceTemplateConfirmation')).then(ok => ok && diff --git a/install-usercss/install-usercss.js b/install-usercss/install-usercss.js index 072db856..bf1e2d3c 100644 --- a/install-usercss/install-usercss.js +++ b/install-usercss/install-usercss.js @@ -68,13 +68,14 @@ cm.setCursor(cursor); cm.scrollTo(scrollInfo.left, scrollInfo.top); - return sendMessage({ + API.saveUsercssUnsafe({ id: (installed || installedDup).id, - method: 'saveUsercss', reason: 'update', sourceCode - }).then(updateMeta) - .catch(showError); + }).then(({style, errors}) => { + updateMeta(style); + if (errors) return Promise.reject(errors); + }).catch(showError); }); } diff --git a/js/usercss.js b/js/usercss.js index 59233dcc..cffa2204 100644 --- a/js/usercss.js +++ b/js/usercss.js @@ -471,7 +471,13 @@ var usercss = (() => { return version; } - function buildCode(style) { + /** + * @param {Object} style + * @param {Boolean} [allowErrors=false] + * @returns {(Style | {style: Style, errors: (false|String[])})} - style object + * when allowErrors is falsy or {style, errors} object when allowErrors is truthy + */ + function buildCode(style, allowErrors) { const {usercssData: {preprocessor, vars}, sourceCode} = style; let builder; if (preprocessor) { @@ -494,11 +500,14 @@ var usercss = (() => { styleId: style.id, code: mozStyle, })) - .then(({sections, errors}) => sections.length && sections || Promise.reject(errors)) - .then(sections => { + .then(({sections, errors}) => { + if (!errors.length) errors = false; + if (!sections.length || errors && !allowErrors) { + return Promise.reject(errors); + } style.sections = sections; if (builder.postprocess) builder.postprocess(style.sections, sVars); - return style; + return allowErrors ? {style, errors} : style; })); }