Don't apply styles until import is finished
This commit is contained in:
parent
e2e64113fe
commit
38006847f7
|
@ -62,10 +62,10 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
|||
&& sender.tab.url == request.matchUrl) {
|
||||
updateIcon(sender.tab, styles);
|
||||
}
|
||||
return true;
|
||||
return KEEP_CHANNEL_OPEN;
|
||||
case "saveStyle":
|
||||
saveStyle(request, sendResponse);
|
||||
return true;
|
||||
saveStyle(request).then(sendResponse);
|
||||
return KEEP_CHANNEL_OPEN;
|
||||
case "invalidateCache":
|
||||
if (typeof invalidateCache != "undefined") {
|
||||
invalidateCache(false);
|
||||
|
@ -73,7 +73,7 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
|||
break;
|
||||
case "healthCheck":
|
||||
getDatabase(function() { sendResponse(true); }, function() { sendResponse(false); });
|
||||
return true;
|
||||
return KEEP_CHANNEL_OPEN;
|
||||
case "openURL":
|
||||
openURL(request);
|
||||
break;
|
||||
|
@ -88,6 +88,9 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
|||
chrome.contextMenus.update("disableAll", {checked: request.value});
|
||||
}
|
||||
break;
|
||||
case "refreshAllTabs":
|
||||
refreshAllTabs().then(sendResponse);
|
||||
return KEEP_CHANNEL_OPEN;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* globals getStyles, saveStyle */
|
||||
/* globals getStyles, saveStyle, invalidateCache, refreshAllTabs, handleUpdate */
|
||||
'use strict';
|
||||
|
||||
var STYLISH_DUMP_FILE_EXT = '.txt';
|
||||
|
@ -71,27 +71,26 @@ document.getElementById('file-all-styles').addEventListener('click', function ()
|
|||
});
|
||||
});
|
||||
|
||||
document.getElementById('unfile-all-styles').addEventListener('click', function () {
|
||||
loadFromFile(STYLISH_DUMPFILE_EXTENSION).then(function (rawText) {
|
||||
var json = JSON.parse(rawText);
|
||||
var i = 0, nextStyle;
|
||||
document.getElementById('unfile-all-styles').addEventListener('click', () => {
|
||||
loadFromFile(STYLISH_DUMPFILE_EXTENSION).then(rawText => {
|
||||
const json = JSON.parse(rawText);
|
||||
const numStyles = json.length;
|
||||
|
||||
function done() {
|
||||
window.alert(i + ' styles installed/updated');
|
||||
location.reload();
|
||||
}
|
||||
invalidateCache(true);
|
||||
proceed();
|
||||
|
||||
function proceed() {
|
||||
nextStyle = json[i++];
|
||||
const nextStyle = json.shift();
|
||||
if (nextStyle) {
|
||||
saveStyle(nextStyle, proceed);
|
||||
}
|
||||
else {
|
||||
i--;
|
||||
done();
|
||||
saveStyle(nextStyle, {notify: false}).then(style => {
|
||||
handleUpdate(style);
|
||||
setTimeout(proceed, 0);
|
||||
});
|
||||
} else {
|
||||
refreshAllTabs().then(() => {
|
||||
setTimeout(alert, 100, numStyles + ' styles installed/updated');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
proceed();
|
||||
});
|
||||
});
|
||||
|
|
57
manage.js
57
manage.js
|
@ -19,9 +19,7 @@ function showStyles(styles) {
|
|||
return;
|
||||
}
|
||||
styles.sort(function(a, b) { return a.name.localeCompare(b.name)});
|
||||
styles.map(createStyleElement).forEach(function(e) {
|
||||
installed.appendChild(e);
|
||||
});
|
||||
styles.forEach(handleUpdate);
|
||||
if (history.state) {
|
||||
window.scrollTo(0, history.state.scrollY);
|
||||
}
|
||||
|
@ -163,10 +161,8 @@ function getStyleElement(event) {
|
|||
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
||||
switch (request.method) {
|
||||
case "styleUpdated":
|
||||
handleUpdate(request.style);
|
||||
break;
|
||||
case "styleAdded":
|
||||
installed.appendChild(createStyleElement(request.style));
|
||||
handleUpdate(request.style);
|
||||
break;
|
||||
case "styleDeleted":
|
||||
handleDelete(request.id);
|
||||
|
@ -176,12 +172,17 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
|||
|
||||
function handleUpdate(style) {
|
||||
var element = createStyleElement(style);
|
||||
installed.replaceChild(element, installed.querySelector("[style-id='" + style.id + "']"));
|
||||
var oldElement = installed.querySelector(`[style-id="${style.id}"]`);
|
||||
if (!oldElement) {
|
||||
installed.appendChild(element);
|
||||
return;
|
||||
}
|
||||
installed.replaceChild(element, oldElement);
|
||||
if (style.id == lastUpdatedStyleId) {
|
||||
lastUpdatedStyleId = null;
|
||||
element.className = element.className += " update-done";
|
||||
element.querySelector(".update-note").innerHTML = t('updateCompleted');
|
||||
};
|
||||
element.className = element.className += ' update-done';
|
||||
element.querySelector('.update-note').innerHTML = t('updateCompleted');
|
||||
}
|
||||
}
|
||||
|
||||
function handleDelete(id) {
|
||||
|
@ -465,41 +466,6 @@ function initFilter(className, node) {
|
|||
onFilterChange(className, {target: node});
|
||||
}
|
||||
|
||||
function importStyles (e) {
|
||||
var file = e.target.files[0];
|
||||
var reader = new FileReader();
|
||||
var styles = [];
|
||||
|
||||
function save () {
|
||||
var style = styles.shift();
|
||||
if (style) {
|
||||
delete style.id;
|
||||
saveStyle(style, save);
|
||||
}
|
||||
else {
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
|
||||
reader.onloadend = function (evt) {
|
||||
try {
|
||||
styles = JSON.parse(evt.target.result);
|
||||
save();
|
||||
}
|
||||
catch (e) {
|
||||
window.alert(e.message);
|
||||
}
|
||||
};
|
||||
reader.onerror = function (e) {
|
||||
window.alert(e.message);
|
||||
}
|
||||
reader.readAsText(file)
|
||||
}
|
||||
|
||||
function selectAll () {
|
||||
document.execCommand('selectAll');
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
installed = document.getElementById("installed");
|
||||
if (document.stylishStyles) {
|
||||
|
@ -520,5 +486,4 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
]);
|
||||
initFilter("enabled-only", document.getElementById("manage.onlyEnabled"));
|
||||
initFilter("edited-only", document.getElementById("manage.onlyEdited"));
|
||||
|
||||
});
|
||||
|
|
26
messaging.js
26
messaging.js
|
@ -1,3 +1,6 @@
|
|||
// keep message channel open for sendResponse in chrome.runtime.onMessage listener
|
||||
const KEEP_CHANNEL_OPEN = true;
|
||||
|
||||
function notifyAllTabs(request) {
|
||||
chrome.windows.getAll({populate: true}, function(windows) {
|
||||
windows.forEach(function(win) {
|
||||
|
@ -16,6 +19,29 @@ function notifyAllTabs(request) {
|
|||
}
|
||||
}
|
||||
|
||||
function refreshAllTabs() {
|
||||
return new Promise(resolve => {
|
||||
chrome.windows.getAll({populate: true}, windows => {
|
||||
windows.forEach((win, winIndex) => {
|
||||
win.tabs.forEach((tab, tabIndex) => {
|
||||
getStyles({matchUrl: tab.url, enabled: true, asHash: true}, styles => {
|
||||
const message = {method: 'styleReplaceAll', styles};
|
||||
if (tab.url == location.href && typeof applyOnMessage !== 'undefined') {
|
||||
applyOnMessage(message);
|
||||
} else {
|
||||
chrome.tabs.sendMessage(tab.id, message);
|
||||
}
|
||||
updateIcon(tab, styles);
|
||||
if (winIndex == windows.length - 1 && tabIndex == win.tabs.length - 1) {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function updateIcon(tab, styles) {
|
||||
// while NTP is still loading only process the request for its main frame with a real url
|
||||
// (but when it's loaded we should process style toggle requests from popups, for example)
|
||||
|
|
109
storage.js
109
storage.js
|
@ -95,72 +95,65 @@ function filterStyles(styles, options) {
|
|||
return styles;
|
||||
}
|
||||
|
||||
function saveStyle(o, callback) {
|
||||
getDatabase(function(db) {
|
||||
var tx = db.transaction(["styles"], "readwrite");
|
||||
var os = tx.objectStore("styles");
|
||||
function saveStyle(style, {notify = true} = {}) {
|
||||
return new Promise(resolve => {
|
||||
getDatabase(db => {
|
||||
const tx = db.transaction(['styles'], 'readwrite');
|
||||
const os = tx.objectStore('styles');
|
||||
|
||||
// Update
|
||||
if (o.id) {
|
||||
var request = os.get(Number(o.id));
|
||||
request.onsuccess = function(event) {
|
||||
var style = request.result || {};
|
||||
for (var prop in o) {
|
||||
if (prop == "id") {
|
||||
continue;
|
||||
}
|
||||
style[prop] = o[prop];
|
||||
}
|
||||
request = os.put(style);
|
||||
request.onsuccess = function(event) {
|
||||
notifyAllTabs({method: "styleUpdated", style: style});
|
||||
invalidateCache(true);
|
||||
if (callback) {
|
||||
callback(style);
|
||||
}
|
||||
// Update
|
||||
if (style.id) {
|
||||
style.id = Number(style.id);
|
||||
os.get(style.id).onsuccess = eventGet => {
|
||||
style = Object.assign({}, eventGet.target.result, style);
|
||||
os.put(style).onsuccess = eventPut => {
|
||||
style.id = style.id || eventPut.target.result;
|
||||
if (notify) {
|
||||
notifyAllTabs({method: 'styleUpdated', style});
|
||||
}
|
||||
invalidateCache(notify);
|
||||
resolve(style);
|
||||
};
|
||||
};
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
// Create
|
||||
// Set optional things to null if they're undefined
|
||||
["updateUrl", "md5Url", "url", "originalMd5"].filter(function(att) {
|
||||
return !(att in o);
|
||||
}).forEach(function(att) {
|
||||
o[att] = null;
|
||||
});
|
||||
// Set other optional things to empty array if they're undefined
|
||||
o.sections.forEach(function(section) {
|
||||
["urls", "urlPrefixes", "domains", "regexps"].forEach(function(property) {
|
||||
if (!section[property]) {
|
||||
section[property] = [];
|
||||
}
|
||||
});
|
||||
});
|
||||
// Set to enabled if not set
|
||||
if (!("enabled" in o)) {
|
||||
o.enabled = true;
|
||||
}
|
||||
// Make sure it's not null - that makes indexeddb sad
|
||||
delete o["id"];
|
||||
var request = os.add(o);
|
||||
request.onsuccess = function(event) {
|
||||
invalidateCache(true);
|
||||
// Give it the ID that was generated
|
||||
o.id = event.target.result;
|
||||
notifyAllTabs({method: "styleAdded", style: o});
|
||||
if (callback) {
|
||||
callback(o);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Create
|
||||
style = Object.assign({
|
||||
// Set optional things if they're undefined
|
||||
enabled: true,
|
||||
updateUrl: null,
|
||||
md5Url: null,
|
||||
url: null,
|
||||
originalMd5: null,
|
||||
}, style, {
|
||||
// Set other optional things to empty array if they're undefined
|
||||
sections: style.sections.map(section =>
|
||||
Object.assign({
|
||||
urls: [],
|
||||
urlPrefixes: [],
|
||||
domains: [],
|
||||
regexps: [],
|
||||
}, section)
|
||||
),
|
||||
})
|
||||
// Make sure it's not null - that makes indexeddb sad
|
||||
delete style.id;
|
||||
os.add(style).onsuccess = event => {
|
||||
invalidateCache(true);
|
||||
// Give it the ID that was generated
|
||||
style.id = event.target.result;
|
||||
notifyAllTabs({method: 'styleAdded', style});
|
||||
resolve(style);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function enableStyle(id, enabled) {
|
||||
saveStyle({id: id, enabled: enabled}, function(style) {
|
||||
saveStyle({id: id, enabled: enabled}).then(style => {
|
||||
handleUpdate(style);
|
||||
notifyAllTabs({method: "styleUpdated", style: style});
|
||||
notifyAllTabs({method: "styleUpdated", style});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user