issue 5 updates for styles with settings

This commit is contained in:
Jason Barnabe 2014-02-06 15:05:31 -06:00
parent 6489de0861
commit 6bf6cff755
4 changed files with 143 additions and 50 deletions

View File

@ -89,7 +89,7 @@ function getStyles(options, callback) {
} }
var metaValue = values.metaValue; var metaValue = values.metaValue;
if (currentStyle == null || currentStyle.id != values.id) { if (currentStyle == null || currentStyle.id != values.id) {
currentStyle = {id: values.id, url: values.url, updateUrl: values.updateUrl, md5Url: values.md5Url, name: values.name, enabled: values.enabled, sections: []}; currentStyle = {id: values.id, url: values.url, updateUrl: values.updateUrl, md5Url: values.md5Url, name: values.name, enabled: values.enabled, originalMd5: values.originalMd5, sections: []};
cachedStyles.push(currentStyle); cachedStyles.push(currentStyle);
} }
if (currentSection == null || currentSection.id != values.section_id) { if (currentSection == null || currentSection.id != values.section_id) {
@ -199,15 +199,18 @@ function saveStyle(o, callback) {
if ("md5Url" in o) { if ("md5Url" in o) {
t.executeSql('UPDATE styles SET md5Url = ? WHERE id = ?;', [o.md5Url, o.id]); t.executeSql('UPDATE styles SET md5Url = ? WHERE id = ?;', [o.md5Url, o.id]);
} }
if ("originalMd5" in o) {
t.executeSql('UPDATE styles SET originalMd5 = ? WHERE id = ?;', [o.originalMd5, o.id]);
}
} else { } else {
// create a new record // create a new record
// set optional things to null if they're undefined // set optional things to null if they're undefined
["updateUrl", "md5Url", "url"].filter(function(att) { ["updateUrl", "md5Url", "url", "originalMd5"].filter(function(att) {
return !(att in o); return !(att in o);
}).forEach(function(att) { }).forEach(function(att) {
o[att] = null; o[att] = null;
}); });
t.executeSql('INSERT INTO styles (name, enabled, url, updateUrl, md5Url) VALUES (?, ?, ?, ?, ?);', [o.name, true, o.url, o.updateUrl, o.md5Url]); t.executeSql('INSERT INTO styles (name, enabled, url, updateUrl, md5Url, originalMd5) VALUES (?, ?, ?, ?, ?, ?);', [o.name, true, o.url, o.updateUrl, o.md5Url, o.originalMd5]);
} }
if ("sections" in o) { if ("sections" in o) {

View File

@ -4,25 +4,37 @@ chrome.extension.sendMessage({method: "getStyles", url: getMeta("stylish-id-url"
} else { } else {
var installedStyle = response[0]; var installedStyle = response[0];
// maybe an update is needed // maybe an update is needed
getResource(getMeta("stylish-code-chrome"), function(code) { // use the md5 if available
// this would indicate a failure (a style with settings?). var md5Url = getMeta("stylish-md5-url");
if (code == null) { if (md5Url && installedStyle.md5Url && installedStyle.originalMd5) {
sendEvent("styleCanBeUpdatedChrome"); getResource(md5Url, function(md5) {
} if (md5 == installedStyle.originalMd5) {
var json = JSON.parse(code); sendEvent("styleAlreadyInstalledChrome", {updateUrl: installedStyle.updateUrl});
if (json.sections.length == installedStyle.sections.length) { } else {
if (json.sections.every(function(section) { sendEvent("styleCanBeUpdatedChrome", {updateUrl: installedStyle.updateUrl});
return installedStyle.sections.some(function(installedSection) { }
return sectionsAreEqual(section, installedSection); });
}); } else {
})) { getResource(getMeta("stylish-code-chrome"), function(code) {
// everything's the same // this would indicate a failure (a style with settings?).
sendEvent("styleAlreadyInstalledChrome"); if (code == null) {
return; sendEvent("styleCanBeUpdatedChrome", {updateUrl: installedStyle.updateUrl});
}; }
} var json = JSON.parse(code);
sendEvent("styleCanBeUpdatedChrome"); if (json.sections.length == installedStyle.sections.length) {
}); if (json.sections.every(function(section) {
return installedStyle.sections.some(function(installedSection) {
return sectionsAreEqual(section, installedSection);
});
})) {
// everything's the same
sendEvent("styleAlreadyInstalledChrome", {updateUrl: installedStyle.updateUrl});
return;
};
}
sendEvent("styleCanBeUpdatedChrome", {updateUrl: installedStyle.updateUrl});
});
}
} }
}); });
@ -49,9 +61,11 @@ function arraysAreEqual(a, b) {
}); });
} }
function sendEvent(type) { function sendEvent(type, data) {
var stylishEvent = document.createEvent("Events"); if (typeof data == "undefined") {
stylishEvent.initEvent(type, false, false, document.defaultView, null); data = null;
}
var stylishEvent = new CustomEvent(type, {detail: data});
document.dispatchEvent(stylishEvent); document.dispatchEvent(stylishEvent);
} }
@ -77,7 +91,9 @@ document.addEventListener("stylishUpdateChrome", function() {
if (confirm(chrome.i18n.getMessage('styleUpdate', [style.name]))) { if (confirm(chrome.i18n.getMessage('styleUpdate', [style.name]))) {
getResource(getMeta("stylish-code-chrome"), function(code) { getResource(getMeta("stylish-code-chrome"), function(code) {
var json = JSON.parse(code); var json = JSON.parse(code);
chrome.extension.sendMessage({method: "saveStyle", id: style.id, sections: json.sections}, function() { json.method = "saveStyle";
json.id = style.id;
chrome.extension.sendMessage(json, function() {
sendEvent("styleInstalledChrome"); sendEvent("styleInstalledChrome");
}); });
}); });

114
manage.js
View File

@ -1,6 +1,8 @@
var styleTemplate = document.createElement("div"); var styleTemplate = document.createElement("div");
styleTemplate.innerHTML = "<h2 class='style-name'></h2><p class='applies-to'></p><p class='actions'><a class='style-edit-link' href='edit.html?id='><button>" + t('editStyleLabel') + "</button></a><button class='enable'>" + t('enableStyleLabel') + "</button><button class='disable'>" + t('disableStyleLabel') + "</button><button class='delete'>" + t('deleteStyleLabel') + "</button><button class='check-update'>" + t('checkForUpdate') + "</button><button class='update'>" + t('installUpdate') + "</button><span class='update-note'></span></p>"; styleTemplate.innerHTML = "<h2 class='style-name'></h2><p class='applies-to'></p><p class='actions'><a class='style-edit-link' href='edit.html?id='><button>" + t('editStyleLabel') + "</button></a><button class='enable'>" + t('enableStyleLabel') + "</button><button class='disable'>" + t('disableStyleLabel') + "</button><button class='delete'>" + t('deleteStyleLabel') + "</button><button class='check-update'>" + t('checkForUpdate') + "</button><button class='update'>" + t('installUpdate') + "</button><span class='update-note'></span></p>";
var lastUpdatedStyleId = null;
var appliesToExtraTemplate = document.createElement("span"); var appliesToExtraTemplate = document.createElement("span");
appliesToExtraTemplate.className = "applies-to-extra"; appliesToExtraTemplate.className = "applies-to-extra";
appliesToExtraTemplate.innerHTML = " " + t('appliesDisplayTruncatedSuffix'); appliesToExtraTemplate.innerHTML = " " + t('appliesDisplayTruncatedSuffix');
@ -21,6 +23,12 @@ function createStyleElement(style) {
if (style.updateUrl) { if (style.updateUrl) {
e.setAttribute("style-update-url", style.updateUrl); e.setAttribute("style-update-url", style.updateUrl);
} }
if (style.md5Url) {
e.setAttribute("style-md5-url", style.md5Url);
}
if (style.originalMd5) {
e.setAttribute("style-original-md5", style.originalMd5);
}
var styleName = e.querySelector(".style-name"); var styleName = e.querySelector(".style-name");
styleName.appendChild(document.createTextNode(style.name)); styleName.appendChild(document.createTextNode(style.name));
@ -131,7 +139,13 @@ chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
function handleUpdate(style) { function handleUpdate(style) {
var installed = document.getElementById("installed"); var installed = document.getElementById("installed");
installed.replaceChild(createStyleElement(style), installed.querySelector("[style-id='" + style.id + "']")); var element = createStyleElement(style);
installed.replaceChild(element, installed.querySelector("[style-id='" + style.id + "']"));
if (style.id == lastUpdatedStyleId) {
lastUpdatedStyleId = null;
element.className = element.className += " update-done";
element.querySelector(".update-note").innerHTML = t('updateCompleted');
};
} }
function handleDelete(id) { function handleDelete(id) {
@ -152,31 +166,78 @@ function checkUpdate(element) {
element.className = element.className.replace("checking-update", "").replace("no-update", "").replace("can-update", "") + " checking-update"; element.className = element.className.replace("checking-update", "").replace("no-update", "").replace("can-update", "") + " checking-update";
var id = element.getAttribute("style-id"); var id = element.getAttribute("style-id");
var url = element.getAttribute("style-update-url"); var url = element.getAttribute("style-update-url");
var md5Url = element.getAttribute("style-md5-url");
var originalMd5 = element.getAttribute("style-original-md5");
function handleSuccess(forceUpdate, serverJson) {
chrome.extension.sendMessage({method: "getStyles", id: id}, function(styles) {
var style = styles[0];
if (!forceUpdate && codeIsEqual(style.sections, serverJson.sections)) {
handleNeedsUpdate("no", id, serverJson);
} else {
handleNeedsUpdate("yes", id, serverJson);
}
});
}
function handleFailure(status) {
if (status == 0) {
handleNeedsUpdate(t('updateCheckFailServerUnreachable'), id, null);
} else {
handleNeedsUpdate(t('updateCheckFailBadResponseCode', [status]), id, null);
}
}
if (!md5Url || !originalMd5) {
checkUpdateFullCode(url, false, handleSuccess, handleFailure)
} else {
checkUpdateMd5(originalMd5, md5Url, function(needsUpdate) {
if (needsUpdate) {
// If the md5 shows a change we will update regardless of whether the code looks different
checkUpdateFullCode(url, true, handleSuccess, handleFailure);
} else {
handleNeedsUpdate("no", id, null);
}
}, handleFailure);
}
}
function checkUpdateFullCode(url, forceUpdate, successCallback, failureCallback) {
download(url, function(responseText) {
successCallback(forceUpdate, JSON.parse(responseText));
}, failureCallback);
}
function checkUpdateMd5(originalMd5, md5Url, successCallback, failureCallback) {
download(md5Url, function(responseText) {
if (responseText.length != 32) {
failureCallback(-1);
return;
}
successCallback(responseText != originalMd5);
}, failureCallback);
}
function download(url, successCallback, failureCallback) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function (aEvt) { xhr.onreadystatechange = function (aEvt) {
if (xhr.readyState == 4) { if (xhr.readyState == 4) {
if (xhr.status == 200) { if (xhr.status == 200) {
checkNeedsUpdate(id, JSON.parse(xhr.responseText)); successCallback(xhr.responseText)
} else if (xhr.status == 0) {
handleNeedsUpdate(t('updateCheckFailServerUnreachable'), id, null);
} else { } else {
handleNeedsUpdate(t('updateCheckFailBadResponseCode', [xhr.status]), id, null); failureCallback(xhr.status);
} }
} }
}; }
xhr.send(null); if (url.length > 2000) {
} var parts = url.split("?");
xhr.open("POST", parts[0], true);
function checkNeedsUpdate(id, serverJson) { xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
chrome.extension.sendMessage({method: "getStyles", id: id}, function(styles) { xhr.send(parts[1]);
var style = styles[0]; } else {
if (codeIsEqual(style.sections, serverJson.sections)) { xhr.open("GET", url, true);
handleNeedsUpdate("no", id, serverJson); xhr.send();
} else { }
handleNeedsUpdate("yes", id, serverJson);
}
});
} }
function handleNeedsUpdate(needsUpdate, id, serverJson) { function handleNeedsUpdate(needsUpdate, id, serverJson) {
@ -200,11 +261,16 @@ function handleNeedsUpdate(needsUpdate, id, serverJson) {
function doUpdate(event) { function doUpdate(event) {
var element = getStyleElement(event); var element = getStyleElement(event);
chrome.extension.sendMessage({method: "saveStyle", id: element.getAttribute('style-id'), sections: element.updatedCode.sections}, function() {
element.updatedCode = ""; var updatedCode = element.updatedCode;
element.className = element.className.replace("can-update", "update-done"); // update everything but name
element.querySelector(".update-note").innerHTML = t('updateCompleted'); delete updatedCode.name;
}); updatedCode.id = element.getAttribute('style-id');
updatedCode.method = "saveStyle";
// updating the UI will be handled by the general update listener
lastUpdatedStyleId = updatedCode.id;
chrome.extension.sendMessage(updatedCode);
} }
function codeIsEqual(a, b) { function codeIsEqual(a, b) {

View File

@ -18,6 +18,8 @@ function getDatabase(ready, error) {
dbV13(stylishDb, error, ready); dbV13(stylishDb, error, ready);
} else if (stylishDb.version == "1.3") { } else if (stylishDb.version == "1.3") {
dbV14(stylishDb, error, ready); dbV14(stylishDb, error, ready);
} else if (stylishDb.version == "1.4") {
dbV15(stylishDb, error, ready);
} else { } else {
ready(stylishDb); ready(stylishDb);
} }
@ -64,6 +66,12 @@ function dbV14(d, error, done) {
}, error, function() { done(d)}); }, error, function() { done(d)});
} }
function dbV15(d, error, done) {
d.changeVersion(d.version, '1.5', function (t) {
t.executeSql('ALTER TABLE styles ADD COLUMN originalMd5 TEXT NULL;');
}, error, function() { done(d)});
}
function enableStyle(id, enabled) { function enableStyle(id, enabled) {
getDatabase(function(db) { getDatabase(function(db) {
db.transaction(function (t) { db.transaction(function (t) {