embed digest in DB as style.originalDigest

This commit is contained in:
tophf 2017-05-03 18:37:47 +03:00
parent f3c42fc27b
commit 5f0b57bebf
4 changed files with 71 additions and 71 deletions

View File

@ -67,6 +67,24 @@ if ('commands' in chrome) {
browserUIlanguage: UIlang, browserUIlanguage: UIlang,
}); });
} }
// TODO: remove in the future
// embed style digests
chrome.storage.local.get(null, data => {
const digestKeys = Object.keys(data).filter(key => key.startsWith('originalDigest'));
if (!digestKeys.length) {
return;
}
chrome.storage.local.remove(digestKeys);
getStyles().then(styles => {
for (const style of styles) {
const digest = data['originalDigest' + style.id];
if (!style.originalDigest && digest) {
style.originalDigest = digest;
dbExec('put', style);
}
}
});
});
}; };
// bind for 60 seconds max and auto-unbind if it's a normal run // bind for 60 seconds max and auto-unbind if it's a normal run
chrome.runtime.onInstalled.addListener(onInstall); chrome.runtime.onInstalled.addListener(onInstall);

View File

@ -60,9 +60,6 @@ function importFromString(jsonString) {
const oldStylesByName = json.length && new Map( const oldStylesByName = json.length && new Map(
oldStyles.map(style => [style.name.trim(), style])); oldStyles.map(style => [style.name.trim(), style]));
let oldDigests;
chrome.storage.local.get(null, data => (oldDigests = data));
const stats = { const stats = {
added: {names: [], ids: [], legend: 'importReportLegendAdded'}, added: {names: [], ids: [], legend: 'importReportLegendAdded'},
unchanged: {names: [], ids: [], legend: 'importReportLegendIdentical'}, unchanged: {names: [], ids: [], legend: 'importReportLegendIdentical'},
@ -220,7 +217,6 @@ function importFromString(jsonString) {
deleteStyleSafe({id, notify: false}).then(id => { deleteStyleSafe({id, notify: false}).then(id => {
const oldStyle = oldStylesById.get(id); const oldStyle = oldStylesById.get(id);
if (oldStyle) { if (oldStyle) {
oldStyle.styleDigest = oldDigests[BG.DIGEST_KEY_PREFIX + id];
saveStyleSafe(Object.assign(oldStyle, SAVE_OPTIONS)) saveStyleSafe(Object.assign(oldStyle, SAVE_OPTIONS))
.then(undoNextId); .then(undoNextId);
} else { } else {
@ -282,14 +278,7 @@ function importFromString(jsonString) {
$('#file-all-styles').onclick = () => { $('#file-all-styles').onclick = () => {
Promise.all([ getStylesSafe().then(styles => {
BG.chromeLocal.get(null),
getStylesSafe(),
]).then(([data, styles]) => {
styles = styles.map(style => {
const styleDigest = data[BG.DIGEST_KEY_PREFIX + style.id];
return styleDigest ? Object.assign({styleDigest}, style) : style;
});
const text = JSON.stringify(styles, null, '\t'); const text = JSON.stringify(styles, null, '\t');
const url = 'data:text/plain;charset=utf-8,' + encodeURIComponent(text); const url = 'data:text/plain;charset=utf-8,' + encodeURIComponent(text);
return url; return url;

View File

@ -6,9 +6,6 @@ const RX_NAMESPACE = new RegExp([/[\s\r\n]*/,
const RX_CSS_COMMENTS = /\/\*[\s\S]*?\*\//g; const RX_CSS_COMMENTS = /\/\*[\s\S]*?\*\//g;
const SLOPPY_REGEXP_PREFIX = '\0'; const SLOPPY_REGEXP_PREFIX = '\0';
// eslint-disable-next-line no-var
var DIGEST_KEY_PREFIX = 'originalDigest';
// Note, only 'var'-declared variables are visible from another extension page // Note, only 'var'-declared variables are visible from another extension page
// eslint-disable-next-line no-var // eslint-disable-next-line no-var
var cachedStyles = { var cachedStyles = {
@ -232,37 +229,55 @@ function saveStyle(style) {
const id = Number(style.id) || null; const id = Number(style.id) || null;
const reason = style.reason; const reason = style.reason;
const notify = style.notify !== false; const notify = style.notify !== false;
const styleDigest = style.styleDigest;
delete style.method; delete style.method;
delete style.reason; delete style.reason;
delete style.notify; delete style.notify;
delete style.styleDigest;
if (!style.name) { if (!style.name) {
delete style.name; delete style.name;
} }
let existed, codeIsUpdated; let existed, codeIsUpdated;
if (id !== null) { if (reason == 'update' || reason == 'update-digest') {
// Update or create return calcStyleDigest(style).then(digest => {
style.id = id; style.originalDigest = digest;
return dbExec('get', id).then((event, store) => { decide();
const oldStyle = event.target.result;
existed = Boolean(oldStyle);
codeIsUpdated = !existed || style.sections && !styleSectionsEqual(style, oldStyle);
style = Object.assign({}, oldStyle, style);
return write(style, store);
}); });
} else { }
// Create if (reason == 'import') {
delete style.id; style.originalDigest = style.originalDigest || style.styleDigest; // TODO: remove in the future
style = Object.assign({ delete style.styleDigest; // TODO: remove in the future
// Set optional things if they're undefined if (typeof style.originalDigest != 'string' || style.originalDigest.length != 40) {
enabled: true, delete style.originalDigest;
updateUrl: null, }
md5Url: null, }
url: null, return decide();
originalMd5: null,
}, style); function decide() {
return write(style); if (id !== null) {
// Update or create
style.id = id;
return dbExec('get', id).then((event, store) => {
const oldStyle = event.target.result;
existed = Boolean(oldStyle);
if (reason == 'update-digest' && oldStyle.originalDigest == style.originalDigest) {
return style;
}
codeIsUpdated = !existed || style.sections && !styleSectionsEqual(style, oldStyle);
style = Object.assign({}, oldStyle, style);
return write(style, store);
});
} else {
// Create
delete style.id;
style = Object.assign({
// Set optional things if they're undefined
enabled: true,
updateUrl: null,
md5Url: null,
url: null,
originalMd5: null,
}, style);
return write(style);
}
} }
function write(style, store) { function write(style, store) {
@ -277,6 +292,9 @@ function saveStyle(style) {
} }
function done(event) { function done(event) {
if (reason == 'update-digest') {
return style;
}
style.id = style.id || event.target.result; style.id = style.id || event.target.result;
invalidateCache(existed ? {updated: style} : {added: style}); invalidateCache(existed ? {updated: style} : {added: style});
compileStyleRegExps({style}); compileStyleRegExps({style});
@ -286,15 +304,6 @@ function saveStyle(style) {
style, codeIsUpdated, reason, style, codeIsUpdated, reason,
}); });
} }
if (reason == 'update') {
updateStyleDigest(style);
} else if (reason == 'import') {
if (typeof styleDigest == 'string' && styleDigest.length == 40) {
chromeLocal.setValue(DIGEST_KEY_PREFIX + style.id, styleDigest);
} else {
chrome.storage.local.remove(DIGEST_KEY_PREFIX + style.id);
}
}
return style; return style;
} }
} }
@ -302,7 +311,7 @@ function saveStyle(style) {
function deleteStyle({id, notify = true}) { function deleteStyle({id, notify = true}) {
id = Number(id); id = Number(id);
chrome.storage.local.remove(DIGEST_KEY_PREFIX + id, ignoreChromeError); chrome.storage.local.remove('originalDigest' + id, ignoreChromeError); // TODO: remove in the future
return dbExec('delete', id).then(() => { return dbExec('delete', id).then(() => {
invalidateCache({deletedId: id}); invalidateCache({deletedId: id});
if (notify) { if (notify) {
@ -567,20 +576,6 @@ function normalizeStyleSections({sections}) {
} }
function getStyleDigests(style) {
return Promise.all([
chromeLocal.getValue(DIGEST_KEY_PREFIX + style.id),
calcStyleDigest(style),
]);
}
function updateStyleDigest(style) {
calcStyleDigest(style).then(digest =>
chromeLocal.setValue(DIGEST_KEY_PREFIX + style.id, digest));
}
function calcStyleDigest(style) { function calcStyleDigest(style) {
const jsonString = JSON.stringify(normalizeStyleSections(style)); const jsonString = JSON.stringify(normalizeStyleSections(style));
const text = new TextEncoder('utf-8').encode(jsonString); const text = new TextEncoder('utf-8').encode(jsonString);

View File

@ -1,5 +1,5 @@
/* global getStyles, saveStyle, styleSectionsEqual, chromeLocal */ /* global getStyles, saveStyle, styleSectionsEqual, chromeLocal */
/* global getStyleDigests, updateStyleDigest */ /* global calcStyleDigest */
'use strict'; 'use strict';
// eslint-disable-next-line no-var // eslint-disable-next-line no-var
@ -39,7 +39,6 @@ var updater = {
}, },
checkStyle({style, observer = () => {}, save = true, ignoreDigest}) { checkStyle({style, observer = () => {}, save = true, ignoreDigest}) {
let hasDigest;
/* /*
Original style digests are calculated in these cases: Original style digests are calculated in these cases:
* style is installed or updated from server * style is installed or updated from server
@ -54,7 +53,7 @@ var updater = {
'ignoreDigest' option is set on the second manual individual update check on the manage page. 'ignoreDigest' option is set on the second manual individual update check on the manage page.
*/ */
return getStyleDigests(style) return (ignoreDigest ? Promise.resolve() : calcStyleDigest(style))
.then(maybeFetchMd5) .then(maybeFetchMd5)
.then(maybeFetchCode) .then(maybeFetchCode)
.then(maybeSave) .then(maybeSave)
@ -68,9 +67,8 @@ var updater = {
updater.log(updater.SKIPPED + ` (${err}) #${style.id} ${style.name}`); updater.log(updater.SKIPPED + ` (${err}) #${style.id} ${style.name}`);
}); });
function maybeFetchMd5([originalDigest, current]) { function maybeFetchMd5(digest) {
hasDigest = Boolean(originalDigest); if (!ignoreDigest && style.originalDigest && style.originalDigest != digest) {
if (hasDigest && !ignoreDigest && originalDigest != current) {
return Promise.reject(updater.EDITED); return Promise.reject(updater.EDITED);
} }
return download(style.md5Url); return download(style.md5Url);
@ -80,7 +78,7 @@ var updater = {
if (!md5 || md5.length != 32) { if (!md5 || md5.length != 32) {
return Promise.reject(updater.ERROR_MD5); return Promise.reject(updater.ERROR_MD5);
} }
if (md5 == style.originalMd5 && hasDigest && !ignoreDigest) { if (md5 == style.originalMd5 && style.originalDigest && !ignoreDigest) {
return Promise.reject(updater.SAME_MD5); return Promise.reject(updater.SAME_MD5);
} }
return download(style.updateUrl); return download(style.updateUrl);
@ -95,9 +93,9 @@ var updater = {
if (styleSectionsEqual(json, style)) { if (styleSectionsEqual(json, style)) {
// JSONs may have different order of items even if sections are effectively equal // JSONs may have different order of items even if sections are effectively equal
// so we'll update the digest anyway // so we'll update the digest anyway
updateStyleDigest(json); saveStyle(Object.assign(json, {reason: 'update-digest'}));
return Promise.reject(updater.SAME_CODE); return Promise.reject(updater.SAME_CODE);
} else if (!hasDigest && !ignoreDigest) { } else if (!style.originalDigest && !ignoreDigest) {
return Promise.reject(updater.MAYBE_EDITED); return Promise.reject(updater.MAYBE_EDITED);
} }
return !save ? json : return !save ? json :