+// Create a backup on first install (or if storage is wiped for some reason.
+chrome.storage.local.get(function(items) {
+ // Setup defaults.
+ if (items.prefs_max_backup_items === undefined) {
+ chrome.storage.local.set({prefs_max_backup_items: 10});
+ }
+ if (items.prefs_backup_timer === undefined) {
+ chrome.storage.local.set({prefs_backup_timer: 30});
+ }
-// Set default values if needed
-if (!localStorage.prefsMaxBackupItems) {
- localStorage.prefsMaxBackupItems = "10";
-}
-
-if (!localStorage.prefsBackupTimer) {
- localStorage.prefsBackupTimer = "30";
-}
-
-// Create a backup on first install (or if storage is wiped for some reason).
-chrome.storage.local.get("backups_list", function(items) {
+ // If a backup exists already, nothing to do.
if (items.backups_list) {
return;
}
var d = new Date();
var formattedDate = date_format (d);
- backupNow(true, formattedDate, function(success, backupName, backupObj) {
+ backupNow(true, formattedDate, function({success, backupName, backupObj}) {
// backup completed
});
});
// Clear any previous alarm
chrome.alarms.clearAll();
- var timerMinutes = parseInt(localStorage.prefsBackupTimer);
- chrome.alarms.create(BACKUP_ALARM_NAME, {periodInMinutes: timerMinutes});
+ chrome.storage.local.get(function(items) {
+ const timerMinutes = items.prefs_backup_timer;
+ chrome.alarms.create(BACKUP_ALARM_NAME, {periodInMinutes: timerMinutes});
+ });
}
initAlarm();
// if last backup time != lastTabsEdit
// perform automatic backup
- backupNow(true, formattedDate, function(success, backupName, backupObj) {
+ backupNow(true, formattedDate, function({success, backupName, backupObj}) {
// automatic backup completed
- var popupViews = chrome.extension.getViews({type: "popup"});
- if (popupViews.length > 0) {
- for (var i = 0; i < popupViews.length; i++) {
- var popupView = popupViews[i];
- if (!popupView.insertBackupItem) {
- continue;
- }
-
- popupView.insertBackupItem(backupName, backupObj, true /*insertAtBeginning*/, true /*doAnimation*/);
- popupView.updateStorageInfo();
- }
- }
+ chrome.runtime.sendMessage({
+ action: 'insertBackupItem',
+ args: [backupName, backupObj, true /*insertAtBeginning*/, true /*doAnimation*/],
+ });
});
}
chrome.alarms.onAlarm.addListener(onAlarm);
-function date_prependZero (val) {
- return val < 10 ? "0" + val : "" + val;
-}
-
-// yyyy-m-d h:i:s
-function date_format (d) {
- var monthOneOffset = d.getMonth() + 1; // convert from 0-11 to 1-12
-
- var formattedDate = d.getFullYear() + "-" + date_prependZero(monthOneOffset) + "-" + date_prependZero(d.getDate())
- + " " + date_prependZero(d.getHours()) + ":" + date_prependZero(d.getMinutes()) + ":" + date_prependZero(d.getSeconds());
-
- return formattedDate;
+// yyyy-mm-dd hh:mm:ss
+function date_format(d) {
+ const prependZero = (val) => val.toString().padStart(2, '0');
+ return d.getFullYear() + "-" +
+ prependZero(d.getMonth() + 1) + "-" +
+ prependZero(d.getDate()) + " " +
+ prependZero(d.getHours()) + ":" +
+ prependZero(d.getMinutes()) + ":" +
+ prependZero(d.getSeconds());
}
}
-function deleteOldestBackup () {
- chrome.storage.local.get("backups_list", function(items) {
- if(!items.backups_list) {
- return;
- }
-
- var backupsList = items.backups_list;
- var numItemsToDelete = backupsList.length - parseInt(localStorage.prefsMaxBackupItems);
- if (numItemsToDelete > 0) {
- var i = 0;
- var loopFunc = function () {
- //
- if (i > 0) {
- var deletedBackupName = backupsList[i-1];
- var popupViews = chrome.extension.getViews({type: "popup"});
- if (popupViews.length > 0) {
- for (var j = 0; j < popupViews.length; j++) {
- var popupView = popupViews[j];
- if (!popupView.removeBackupItemDiv) {
- continue;
- }
-
- popupView.removeBackupItemDiv(deletedBackupName);
- popupView.updateStorageInfo();
- }
- }
- }
- //
-
- if (i >= numItemsToDelete) {
- return;
- }
-
- deleteBackup (backupsList[i], loopFunc);
- i++;
- };
-
- loopFunc ();
- }
-
- //for (var i = 0; i < numItemsToDelete; i++) {
- // TODO WARNING: I'm calling deleteBackup rapidly, while deleting is async...(I should wait for each delete to complete before deleting the next)
- //deleteBackup (backupsList[i], function() {
+async function deleteOldestBackup() {
+ const items = await chrome.storage.local.get();
+ if (!items.backups_list) {
+ return;
+ }
- //});
- //}
+ const backupsList = items.backups_list;
+ const numItemsToDelete = backupsList.length - items.prefs_max_backup_items;
+ for (let i = 0; i < numItemsToDelete; ++i) {
+ const deletedBackupName = backupsList[i];
+ await deleteBackup(deletedBackupName);
- });
+ chrome.runtime.sendMessage({
+ action: 'removeBackupItemDiv',
+ args: [deletedBackupName],
+ });
+ }
}
//var isCreatingBackup = false;
//console.log("==> Tab " + j + " (" + tab.index + "): " + tabUrl);
+ // Ignore windows that we can't/shouldn't backup.
+ if (tab.url.startsWith('chrome-untrusted://')) {
+ continue;
+ }
+
var bkpTab = {
url: tab.url,
title: tab.title,
bkpWindow.tabs.push(bkpTab);
}
- totNumTabs += windowTabs.length;
+ if (bkpWindow.tabs.length) {
+ totNumTabs += bkpWindow.tabs.length;
- fullBackup.windows.push(bkpWindow);
+ fullBackup.windows.push(bkpWindow);
+ }
}
if (totNumTabs == 0)
//alert ("Error: " + chrome.runtime.lastError.message);
updateBrowserActionIcon (1);
- callbackDone(false);
+ callbackDone({success: false});
} else {
console.log("backup saved");
//alert("Backup saved successfully!");
- chrome.storage.local.get("backups_list", function(items) {
+ chrome.storage.local.get(function(items) {
var backupsList = [];
if(items.backups_list) {
backupsList = items.backups_list;
if (chrome.runtime.lastError) {
console.log ("Error saving backups_list: " + chrome.runtime.lastError.message);
updateBrowserActionIcon (1);
- callbackDone(false);
+ callbackDone({success: false});
} else {
console.log("Backups list saved successfully");
updateBrowserActionIcon (0);
- callbackDone(true, backupName, fullBackup);
+ callbackDone({
+ success: true,
+ backupName,
+ backupObj: fullBackup,
+ });
- if (backupsList.length > parseInt(localStorage.prefsMaxBackupItems)) {
+ if (backupsList.length > items.prefs_max_backup_items) {
deleteOldestBackup();
}
}
break;
}
- chrome.browserAction.setIcon({path: icon});
+ chrome.action.setIcon({path: icon});
}
-function deleteBackup (backupName, callback) {
+async function deleteBackup(backupName) {
console.log("Deleting backup " + backupName);
- chrome.storage.local.remove(backupName, function() {
- //console.log ("=> Deleted backup " + backupName);
-
- chrome.storage.local.get("backups_list", function(items) {
- //console.log ("==> got backups_list " + backupName);
-
- if(!items.backups_list) {
- callback();
- return;
- }
+ await chrome.storage.local.remove(backupName);
+ //console.log("=> Deleted backup " + backupName);
- var backupsList = items.backups_list;
+ const items = await chrome.storage.local.get("backups_list");
+ //console.log("==> got backups_list " + backupName);
- var index = backupsList.indexOf(backupName);
- if (index >= 0) {
- backupsList.splice(index, 1);
- }
-
- //console.log ("===> Updating backups_list (removing " + backupName + ")");
-
- chrome.storage.local.set({"backups_list": backupsList}, function() {
- //console.log ("===> Updated backups_list (removed " + backupName + ")");
-
- callback();
- });
-
- //console.log ("==> EXIT got backups_list " + backupName);
- });
+ if (!items.backups_list) {
+ return;
+ }
- //console.log ("=> EXIT Deleted backup " + backupName);
- });
+ var backupsList = items.backups_list;
- //console.log("EXIT Deleting backup " + backupName);
+ var index = backupsList.indexOf(backupName);
+ if (index >= 0) {
+ backupsList.splice(index, 1);
+ }
+ //console.log("===> Updating backups_list (removing " + backupName + ")");
+ await chrome.storage.local.set({"backups_list": backupsList});
+ //console.log("===> Updated backups_list (removed " + backupName + ")");
}
function restoreNow(backupName) {
}
});
}
+
+/**
+ * Callback from other pages (like the popup).
+ */
+chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
+ console.log(`Got message from ${sender.id}: action=${request.action}`, request);
+
+ let asyncResponse = false;
+ switch (request?.action) {
+ case 'initAlarm':
+ initAlarm();
+ break;
+
+ case 'restoreNow':
+ restoreNow(...request.args);
+ break;
+
+ case 'deleteBackup':
+ deleteBackup(...request.args).then(sendResponse);
+ asyncResponse = true;
+ break;
+
+ case 'backupNowManual':
+ backupNowManual(sendResponse);
+ asyncResponse = true;
+ break;
+ }
+ return asyncResponse;
+});