diff --git a/background/update.js b/background/update.js index 3f35283d..8426035e 100644 --- a/background/update.js +++ b/background/update.js @@ -153,9 +153,8 @@ global API_METHODS case 0: // re-install is invalid in a soft upgrade if (!ignoreDigest) { - return Promise.reject(STATES.SAME_VERSION); - } else if (text === style.sourceCode) { - return Promise.reject(STATES.SAME_CODE); + const sameCode = text === style.sourceCode; + return Promise.reject(sameCode ? STATES.SAME_CODE : STATES.SAME_VERSION); } break; case 1: @@ -186,10 +185,14 @@ global API_METHODS json.originalName = json.name; } - if (styleSectionsEqual(json, style)) { + if (styleSectionsEqual(json, style, {checkSource: true})) { // update digest even if save === false as there might be just a space added etc. - saveStyle(Object.assign(json, {reason: 'update-digest'})); - return Promise.reject(STATES.SAME_CODE); + json.reason = 'update-digest'; + return saveStyle(json) + .then(saved => { + style.originalDigest = saved.originalDigest; + return Promise.reject(STATES.SAME_CODE); + }); } if (!style.originalDigest && !ignoreDigest) { diff --git a/js/sections-equal.js b/js/sections-equal.js index 0f05f504..d01c4bfe 100644 --- a/js/sections-equal.js +++ b/js/sections-equal.js @@ -1,7 +1,24 @@ 'use strict'; -// ignoreCode=true is used by invalidateCache to determine if cached filters should be cleared -function styleSectionsEqual({sections: a}, {sections: b}, {ignoreCode = false} = {}) { +/** + * @param {Style} a - first style object + * @param {Style} b - second style object + * @param {Object} options + * @param {Boolean=} options.ignoreCode - + * true used by invalidateCache to determine if cached filters should be cleared + * @param {Boolean=} options.checkSource - + * true used by update check to compare the server response + * instead of sections that depend on @preprocessor + * @returns {Boolean|undefined} + */ +function styleSectionsEqual(a, b, {ignoreCode, checkSource} = {}) { + if (checkSource && + typeof a.sourceCode === 'string' && + typeof b.sourceCode === 'string') { + return a.sourceCode === b.sourceCode; + } + a = a.sections; + b = b.sections; if (!a || !b) { return undefined; } diff --git a/manage/manage.css b/manage/manage.css index a997d781..eb037482 100644 --- a/manage/manage.css +++ b/manage/manage.css @@ -479,7 +479,7 @@ a:hover { cursor: pointer; } -.newUI .entry .style-name::before { +.newUI .entry .style-name:hover::before { content: ""; position: absolute; top: 0; @@ -488,13 +488,6 @@ a:hover { bottom: 0; background: linear-gradient(to right, hsla(180, 50%, 30%, 0.2), hsla(180, 20%, 10%, 0.05) 50%, transparent); pointer-events: none; - opacity: 0; - transition: opacity .1s; - will-change: opacity; -} - -.newUI .entry .style-name:hover::before { - opacity: 1; } .newUI .entry.enabled .style-name:hover .style-name-link { diff --git a/manage/updater-ui.js b/manage/updater-ui.js index 4eaca65d..46a197c9 100644 --- a/manage/updater-ui.js +++ b/manage/updater-ui.js @@ -155,6 +155,16 @@ function reportUpdateState({updated, style, error, STATES}) { $('.update-note', entry).textContent = message; $('.check-update', entry).title = newUI.enabled ? message : ''; $('.update', entry).title = t(edited ? 'updateCheckManualUpdateForce' : 'installUpdate'); + // digest may change silently when forcing an update of a locally edited style + // so we need to update it in entry's styleMeta in all open manager tabs + if (error === STATES.SAME_CODE) { + for (const view of chrome.extension.getViews({type: 'tab'})) { + if (view.location.pathname === location.pathname) { + const entry = view.$(ENTRY_ID_PREFIX + style.id); + if (entry) entry.styleMeta.originalDigest = style.originalDigest; + } + } + } if (!isCheckAll) { renderUpdatesOnlyFilter({show: $('.can-update, .update-problem')}); }