]>
git.wh0rd.org - chrome-ext/tabs-backup.git/blob - background.js
2 // Set default values if needed
3 if (!localStorage
.prefsMaxBackupItems
) {
4 localStorage
.prefsMaxBackupItems
= "10";
7 if (!localStorage
.prefsBackupTimer
) {
8 localStorage
.prefsBackupTimer
= "30";
11 // Create a backup on first install (or if storage is wiped for some reason).
12 chrome
.storage
.local
.get("backups_list", function(items
) {
13 if (items
.backups_list
) {
17 // Create a backup now
19 var formattedDate
= date_format (d
);
21 backupNow(true, formattedDate
, function(success
, backupName
, backupObj
) {
26 function initAlarm () {
27 //console.log("initAlarm");
29 var BACKUP_ALARM_NAME
= "backup_alarm";
31 // Clear any previous alarm
32 chrome
.alarms
.clearAll();
34 var timerMinutes
= parseInt(localStorage
.prefsBackupTimer
);
35 chrome
.alarms
.create(BACKUP_ALARM_NAME
, {periodInMinutes
: timerMinutes
});
40 function onAlarm (alarm
) {
42 var formattedDate
= date_format (d
);
44 console
.log("Alarm {" + alarm
+ "} fired up: " + formattedDate
);
46 // if last backup time != lastTabsEdit
47 // perform automatic backup
48 backupNow(true, formattedDate
, function(success
, backupName
, backupObj
) {
49 // automatic backup completed
50 var popupViews
= chrome
.extension
.getViews({type
: "popup"});
51 if (popupViews
.length
> 0) {
52 for (var i
= 0; i
< popupViews
.length
; i
++) {
53 var popupView
= popupViews
[i
];
54 if (!popupView
.insertBackupItem
) {
58 popupView
.insertBackupItem(backupName
, backupObj
, true /*insertAtBeginning*/, true /*doAnimation*/);
59 popupView
.updateStorageInfo();
65 chrome
.alarms
.onAlarm
.addListener(onAlarm
);
67 function date_prependZero (val
) {
68 return val
< 10 ? "0" + val
: "" + val
;
72 function date_format (d
) {
73 var monthOneOffset
= d
.getMonth() + 1; // convert from 0-11 to 1-12
75 var formattedDate
= d
.getFullYear() + "-" + date_prependZero(monthOneOffset
) + "-" + date_prependZero(d
.getDate())
76 + " " + date_prependZero(d
.getHours()) + ":" + date_prependZero(d
.getMinutes()) + ":" + date_prependZero(d
.getSeconds());
82 function backupNowManual (callbackDone
) {
84 var formattedDate
= date_format (d
);
86 backupNow(false, formattedDate
, callbackDone
);
91 function deleteOldestBackup () {
92 chrome
.storage
.local
.get("backups_list", function(items
) {
93 if(!items
.backups_list
) {
97 var backupsList
= items
.backups_list
;
98 var numItemsToDelete
= backupsList
.length
- parseInt(localStorage
.prefsMaxBackupItems
);
99 if (numItemsToDelete
> 0) {
101 var loopFunc = function () {
104 var deletedBackupName
= backupsList
[i
-1];
105 var popupViews
= chrome
.extension
.getViews({type
: "popup"});
106 if (popupViews
.length
> 0) {
107 for (var j
= 0; j
< popupViews
.length
; j
++) {
108 var popupView
= popupViews
[j
];
109 if (!popupView
.removeBackupItemDiv
) {
113 popupView
.removeBackupItemDiv(deletedBackupName
);
114 popupView
.updateStorageInfo();
120 if (i
>= numItemsToDelete
) {
124 deleteBackup (backupsList
[i
], loopFunc
);
131 //for (var i = 0; i < numItemsToDelete; i++) {
132 // TODO WARNING: I'm calling deleteBackup rapidly, while deleting is async...(I should wait for each delete to complete before deleting the next)
133 //deleteBackup (backupsList[i], function() {
141 //var isCreatingBackup = false;
143 function backupNow(isAutomatic
, backupName
, callbackDone
) {
144 console
.log("backupNow - isAutomatic: " + isAutomatic
+ " name: " + backupName
);
145 /*if (isCreatingBackup === true) {
146 console.log("backupNow - already running..skipping..");
150 //isCreatingBackup = true;
152 /*if (!confirm("Perform a full backup? All windows and their tabs will be saved!")) {
158 isAutomatic
: isAutomatic
,
162 chrome
.windows
.getAll({populate
: true}, function (window_list
) {
165 for(var i
=0;i
<window_list
.length
;i
++) {
166 var window
= window_list
[i
];
168 //console.log ("Window " + i);
175 height
: window
.height
,
179 var windowTabs
= window
.tabs
;
181 // If it's a single window sittig at the new tab page, don't bother
182 // saving it. This is a nice shortcut when things crash as it will
183 // only show a single window.
184 if (windowTabs
.length
== 1) {
185 const tab
= windowTabs
[0];
186 if (tab
.url
== 'chrome://newtab/')
190 for (var j
= 0; j
< windowTabs
.length
; j
++) {
191 var tab
= windowTabs
[j
];
193 //console.log("==> Tab " + j + " (" + tab.index + "): " + tabUrl);
198 highlighted
: tab
.highlighted
,
202 // Add tab to tabs arrays
203 bkpWindow
.tabs
.push(bkpTab
);
206 totNumTabs
+= windowTabs
.length
;
208 fullBackup
.windows
.push(bkpWindow
);
214 fullBackup
.totNumTabs
= totNumTabs
;
216 var storageSetValues
= {};
217 storageSetValues
[backupName
] = fullBackup
;
220 chrome
.storage
.local
.set(storageSetValues
, function () {
221 if (chrome
.runtime
.lastError
) {
222 //isCreatingBackup = false;
223 // TODO change icon to error..
224 //alert ("Error: " + chrome.runtime.lastError.message);
225 updateBrowserActionIcon (1);
229 console
.log("backup saved");
230 //alert("Backup saved successfully!");
232 chrome
.storage
.local
.get("backups_list", function(items
) {
233 var backupsList
= [];
234 if(items
.backups_list
) {
235 backupsList
= items
.backups_list
;
238 console
.log("Updating 'backups_list' - cur. size: " + backupsList
.length
);
240 backupsList
.push(backupName
);
242 chrome
.storage
.local
.set({"backups_list": backupsList
}, function () {
243 //isCreatingBackup = false;
245 if (chrome
.runtime
.lastError
) {
246 console
.log ("Error saving backups_list: " + chrome
.runtime
.lastError
.message
);
247 updateBrowserActionIcon (1);
250 console
.log("Backups list saved successfully");
252 updateBrowserActionIcon (0);
253 callbackDone(true, backupName
, fullBackup
);
255 if (backupsList
.length
> parseInt(localStorage
.prefsMaxBackupItems
)) {
256 deleteOldestBackup();
270 function updateBrowserActionIcon (status
) {
274 icon
= "icon_ok.png";
277 icon
= "icon_error.png";
281 chrome
.browserAction
.setIcon({path
: icon
});
284 function deleteBackup (backupName
, callback
) {
285 console
.log("Deleting backup " + backupName
);
287 chrome
.storage
.local
.remove(backupName
, function() {
288 //console.log ("=> Deleted backup " + backupName);
290 chrome
.storage
.local
.get("backups_list", function(items
) {
291 //console.log ("==> got backups_list " + backupName);
293 if(!items
.backups_list
) {
298 var backupsList
= items
.backups_list
;
300 var index
= backupsList
.indexOf(backupName
);
302 backupsList
.splice(index
, 1);
305 //console.log ("===> Updating backups_list (removing " + backupName + ")");
307 chrome
.storage
.local
.set({"backups_list": backupsList
}, function() {
308 //console.log ("===> Updated backups_list (removed " + backupName + ")");
313 //console.log ("==> EXIT got backups_list " + backupName);
316 //console.log ("=> EXIT Deleted backup " + backupName);
319 //console.log("EXIT Deleting backup " + backupName);
324 function restoreNow(backupName
) {
325 console
.log("restoreNow");
327 chrome
.storage
.local
.get(backupName
, function(items
) {
328 if(!items
[backupName
]) {
329 alert("No Backup found");
333 /*if (!confirm("Restore full backup?")) {
337 if (confirm("Would you like to close all existing windows first?")) {
338 chrome.windows.getAll({populate : false}, function (window_list) {
339 for(var i=0;i<window_list.length;i++) {
340 var window = window_list[i];
341 chrome.windows.remove(window.id);
347 var fullBackup
= items
[backupName
];
349 for(var i
=0;i
<fullBackup
.windows
.length
;i
++) {
350 const window
= fullBackup
.windows
[i
];
352 //console.log ("Window " + i);
356 const windowTabs
= window
.tabs
;
357 for (let j
= 0; j
< windowTabs
.length
; j
++) {
358 const tab
= windowTabs
[j
];
359 const tabUrl
= tab
.url
;
360 urlsToOpen
.push(tabUrl
);
363 const windowProperties
= {
369 height
: window
.height
,
372 // Create a new Window
373 chrome
.windows
.create(windowProperties
, function(createdWindow
) {
374 // Chrome errors if the dimensions are set on non-normal windows.
375 // So we create the window first with the right settings, then
376 // update the window state.
377 if (window
.state
!= 'normal') {
378 chrome
.windows
.update(createdWindow
.id
, {state
: window
.state
});
381 chrome
.windows
.get(createdWindow
.id
, {populate
: true}, ({tabs
}) => {
382 for (let tabi
= 0; tabi
< windowTabs
.length
; ++tabi
) {
383 const oldtab
= windowTabs
[tabi
];
384 const newtab
= tabs
[tabi
];
385 chrome
.tabs
.update(newtab
.id
, {
386 highlighted
: oldtab
.highlighted
,
387 pinned
: oldtab
.pinned
,
389 if (!oldtab
.highlighted
) {
390 // If we discard a tab too fast, Chrome will completely
391 // throw it away. Wait until it's in a stable enough
392 // state for us to discard it.
394 const checktab
= (id
) => {
395 if (retryCount
-- < 0)
397 chrome
.tabs
.get(id
, (tab
) => {
399 setTimeout(() => checktab(id
), 500);
401 chrome
.tabs
.discard(id
);