Skip to content

Commit 7a9581c

Browse files
hobinjknightpool
authored andcommitted
Asynchronously migrate extension data (#1385)
* Asynchronously migrate extension data * Add storage migration warning; Default to unlimited storage * Bump version to 7.7.6-less-broken * Skip update if current value is longer * copying -> migrating for clarity * Bump version * Excise misleading comment
1 parent 216a6e9 commit 7a9581c

File tree

5 files changed

+84
-24
lines changed

5 files changed

+84
-24
lines changed

Firefox/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"title": "New XKit",
33
"name": "new-xkit",
44
"fullName": "New XKit",
5-
"version": "7.7.6",
5+
"version": "7.7.7",
66
"description": "Fork of XKit, the Tumblr extension framework",
77
"main": "./main.js",
88
"author": "",

Firefox/sync-data.js

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,44 @@
1-
/* globals require, exports */
1+
/* globals require, exports, Promise */
22
let prefs = require('sdk/preferences/service');
3+
let {setTimeout} = require('sdk/timers');
34
let prefRoot = 'extensions.xkit7.';
45

6+
function migratePreference(port, prefKey) {
7+
let name = prefKey.substring(prefRoot.length);
8+
let value = prefs.get(prefKey, null);
9+
let msg = {};
10+
msg[name] = value;
11+
// postMessage doesn't return a promise even though it could :(
12+
port.postMessage(msg);
13+
return new Promise(function(resolve, reject) {
14+
setTimeout(function() {
15+
if (port.error) {
16+
reject(port.error);
17+
} else {
18+
resolve();
19+
}
20+
}, 10);
21+
});
22+
}
23+
24+
function migratePreferences(port, existingKeys) {
25+
if (existingKeys.length === 0) {
26+
return Promise.resolve();
27+
}
28+
let key = existingKeys.pop();
29+
return migratePreference(port, key).then(function() {
30+
return migratePreferences(port, existingKeys);
31+
});
32+
}
33+
534
exports.setSyncLegacyDataPort = function(port) {
635

7-
// Get all and broadcast to webext
36+
// Get all and broadcast to webext one at a time
837
let existingKeys = prefs.keys(prefRoot);
9-
let xkitStorage = {};
10-
for (let properName of existingKeys) {
11-
let name = properName.substring(prefRoot.length);
12-
let value = prefs.get(properName, null);
13-
xkitStorage[name] = value;
14-
}
15-
port.postMessage(xkitStorage);
38+
39+
migratePreferences(port, existingKeys).then(() => {
40+
return port.postMessage({isProperlyMigrated: true});
41+
}).catch(err => {
42+
console.error('preferences not migrated', err);
43+
});
1644
};

Firefox/webextension/background.js

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,43 @@
1-
/* global browser */
1+
/* global browser, Promise */
22

33
// From the MDN WebExtensions hybrid addon example
44

55
// Ask to the legacy part to dump the needed data and send it back
66
// to the background page...
7-
var port = browser.runtime.connect({name: "sync-legacy-addon-data"});
8-
port.onMessage.addListener((msg) => {
9-
if (msg) {
10-
browser.storage.local.get('isMigrated').then(function(item) {
11-
if (item.isMigrated) {
12-
console.warn('Skipping migration');
13-
return;
7+
browser.storage.local.get('isProperlyMigrated').then(function(item) {
8+
if (item.isProperlyMigrated) {
9+
console.warn('Skipping migration', item);
10+
return;
11+
}
12+
13+
var port = browser.runtime.connect({name: "sync-legacy-addon-data"});
14+
function onMessage(msg) {
15+
if (!msg) {
16+
return;
17+
}
18+
let setPromises = Object.keys(msg).map(function(key) {
19+
return browser.storage.local.get({key: null}).then(function(msgItem) {
20+
if (typeof(msgItem[key]) === 'string') {
21+
if (msgItem[key].length > msg[key].length) {
22+
// Do not update the storage
23+
return Promise.resolve();
24+
}
25+
}
26+
// The corresponding code in XKit is GM_setValue(name, value) -> set({name: value})
27+
return browser.storage.local.set(msg);
28+
});
29+
});
30+
Promise.all(setPromises).catch(function(err) {
31+
let errorMessage = "XKit failed to migrate your preferences to the new storage system. The migration reported the following error messag: " + err + ". Please restart your browser to try again.";
32+
if (typeof(XKit) === 'undefined') {
33+
alert(errorMessage);
34+
} else {
35+
XKit.window.show("Storage migration in progress", errorMessage, "error", "<div class=\"xkit-button default\">OK</div>");
1436
}
15-
// The corresponding code in XKit is GM_setValue(name, value) -> set({name: value})
16-
msg.isMigrated = true;
17-
console.log('Migrating pref storage', msg);
18-
browser.storage.local.set(msg);
37+
browser.storage.local.set({isProperlyMigrated: false});
38+
port.onMessage.removeListener(onMessage);
1939
});
2040
}
41+
42+
port.onMessage.addListener(onMessage);
2143
});

Firefox/webextension/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"manifest_version": 2,
1616
"name": "New XKit",
1717
"permissions": ["*://*/*", "*://*/", "storage", "http://*.tumblr.com/", "https://*.tumblr.com/" ],
18-
"version": "7.7.6",
18+
"version": "7.7.7",
1919
"web_accessible_resources": [ "manifest.json", "editor.js" ],
2020
"background": {
2121
"scripts": ["background.js"]

WebExtension/bridge.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ try {
2626
var storage = browser.storage.local;
2727
var storage_loaded = false;
2828
var framework_version = getVersion();
29-
var storage_used = -1;
29+
var storage_used = 0;
3030
var storage_max = -1;
3131
init_bridge();
3232
} catch (e) {
@@ -90,6 +90,16 @@ function init_bridge() {
9090
});
9191
return;
9292
}
93+
if (typeof(chrome) === 'undefined') {
94+
if (!items.isProperlyMigrated) {
95+
XKit.window.show("Storage migration in progress", "XKit is still busy migrating your preferences from the old storage system to the new one. Please check back in a couple seconds by refreshing the page.", "warning", "<div class=\"xkit-button default\" id=\"xkit-bridge-refresh\">Refresh</div>");
96+
$("#xkit-bridge-refresh").click(function() {
97+
window.location = window.location;
98+
});
99+
return;
100+
}
101+
102+
}
93103
for (var key in items) {
94104
xkit_storage[key] = items[key];
95105
}

0 commit comments

Comments
 (0)