]> git.wh0rd.org - chrome-ext/tabs-backup.git/blob - background.js
initial import 0.2.1
[chrome-ext/tabs-backup.git] / background.js
1
2 // Set default values if needed
3 if (!localStorage.prefsMaxBackupItems) {
4 localStorage.prefsMaxBackupItems = "30";
5 }
6
7 if (!localStorage.prefsBackupTimer) {
8 localStorage.prefsBackupTimer = "5";
9 }
10
11 if (!localStorage.lastTimerIntervalId) {
12 localStorage.lastTimerIntervalId = 0;
13 }
14
15 if (!localStorage.lastTabsEdit) {
16 localStorage.lastTabsEdit = 0;
17 }
18
19 if (!localStorage.lastBackupTime) {
20 localStorage.lastBackupTime = -1;
21
22 // Create a backup now
23 var d = new Date();
24 var formattedDate = date_format (d);
25
26 backupNow(true, formattedDate, function(success, backupName, backupObj) {
27 // backup completed
28 });
29
30 localStorage.lastBackupTime = localStorage.lastTabsEdit;
31 }
32
33
34
35 // Works only for Event Pages
36 /*
37 chrome.runtime.onInstalled.addListener(function() {
38 console.log("Extension installed/updates");
39
40 if (localStorage.lastBackupTime != localStorage.lastTabsEdit) {
41 // Create a backup now
42 var d = new Date();
43 var formattedDate = date_format (d);
44
45 backupNow(true, formattedDate, function(success, backupName, backupObj) {
46 // backup completed
47 });
48
49 localStorage.lastBackupTime = localStorage.lastTabsEdit;
50 }
51 });*/
52
53 chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
54 //console.log('tabs.onRemoved');
55
56 tabsEdited(true);
57 });
58
59 chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
60 //console.log('tabs.onUpdated');
61
62 tabsEdited(true);
63 });
64
65 chrome.tabs.onAttached.addListener(function(tabId, attachInfo) {
66 //console.log('tabs.onAttached');
67
68 tabsEdited(false);
69 });
70
71 chrome.tabs.onMoved.addListener(function(tabId, moveInfo) {
72 //console.log('tabs.onMoved');
73
74 tabsEdited(false);
75 });
76
77 chrome.tabs.onDetached.addListener(function(tabId, detachInfo) {
78 //console.log('tabs.onDetached');
79
80 tabsEdited(false);
81 });
82
83 chrome.tabs.onCreated.addListener(function(tab) {
84 //console.log('tabs.onCreated');
85
86 tabsEdited(true);
87 });
88
89 function tabsEdited (isImportant) {
90 var d = new Date();
91 var millis = d.getTime();
92
93 console.log('tabsEdited - lastTabsEdit: ' + localStorage.lastTabsEdit);
94 console.log('tabsEdited - new lastTabsEdit: ' + millis);
95
96 localStorage.lastTabsEdit = millis;
97
98
99 }
100
101 function initAlarm () {
102 console.log("initAlarm");
103
104 var BACKUP_ALARM_NAME = "backup_alarm";
105
106 // Clear any previous alarm
107 chrome.alarms.clearAll();
108 clearInterval(parseInt(localStorage.lastTimerIntervalId));
109
110 var timerMinutes = parseInt(localStorage.prefsBackupTimer);
111
112 // Apparantely once the app is on the Chrome Store it's not possible
113 // to create alarms that have period less than 5 minutes..
114 if (timerMinutes < 5) {
115 var timerMillis = timerMinutes * 60 * 1000;
116 localStorage.lastTimerIntervalId = setInterval (onAlarm, timerMillis);
117 console.log("Created interval alarm - id: " + localStorage.lastTimerIntervalId + " time: " + timerMinutes + " minutes");
118 } else {
119 console.log("Creating chrome.alarm 'backup_alarm' - time: " + timerMinutes + " minutes");
120 chrome.alarms.create(BACKUP_ALARM_NAME, {periodInMinutes: timerMinutes});
121 }
122 }
123
124 initAlarm();
125
126 function onAlarm (alarm) {
127 var d = new Date();
128 var formattedDate = date_format (d);
129
130 console.log("Alarm {" + alarm + "} fired up: " + formattedDate + " last tabs edit: " + localStorage.lastTabsEdit + " last backup time: " + localStorage.lastBackupTime);
131
132 // localStorage.lastBackupTime
133 // if last backup time != lastTabsEdit
134 // perform automatic backup
135 if (localStorage.lastBackupTime != localStorage.lastTabsEdit) {
136 backupNow(true, formattedDate, function(success, backupName, backupObj) {
137 // automatic backup completed
138 var popupViews = chrome.extension.getViews({type: "popup"});
139 if (popupViews.length > 0) {
140 for (var i = 0; i < popupViews.length; i++) {
141 var popupView = popupViews[i];
142 if (!popupView.insertBackupItem) {
143 continue;
144 }
145
146 popupView.insertBackupItem(backupName, backupObj, true /*insertAtBeginning*/, true /*doAnimation*/);
147 popupView.updateStorageInfo();
148 }
149 }
150 });
151
152 localStorage.lastBackupTime = localStorage.lastTabsEdit;
153 }
154 }
155
156 chrome.alarms.onAlarm.addListener(onAlarm);
157
158 function date_prependZero (val) {
159 return val < 10 ? "0" + val : "" + val;
160 }
161
162 // yyyy-m-d h:i:s
163 function date_format (d) {
164 var monthOneOffset = d.getMonth() + 1; // convert from 0-11 to 1-12
165
166 var formattedDate = d.getFullYear() + "-" + date_prependZero(monthOneOffset) + "-" + date_prependZero(d.getDate())
167 + " " + date_prependZero(d.getHours()) + ":" + date_prependZero(d.getMinutes()) + ":" + date_prependZero(d.getSeconds());
168
169 return formattedDate;
170 }
171
172
173 function backupNowManual (callbackDone) {
174 var d = new Date();
175 var formattedDate = date_format (d);
176
177 backupNow(false, formattedDate, callbackDone);
178
179
180 }
181
182 function deleteOldestBackup () {
183 chrome.storage.local.get("backups_list", function(items) {
184 if(!items.backups_list) {
185 return;
186 }
187
188 var backupsList = items.backups_list;
189 var numItemsToDelete = backupsList.length - parseInt(localStorage.prefsMaxBackupItems);
190 if (numItemsToDelete > 0) {
191 var i = 0;
192 var loopFunc = function () {
193 //
194 if (i > 0) {
195 var deletedBackupName = backupsList[i-1];
196 var popupViews = chrome.extension.getViews({type: "popup"});
197 if (popupViews.length > 0) {
198 for (var j = 0; j < popupViews.length; j++) {
199 var popupView = popupViews[j];
200 if (!popupView.removeBackupItemDiv) {
201 continue;
202 }
203
204 popupView.removeBackupItemDiv(deletedBackupName);
205 popupView.updateStorageInfo();
206 }
207 }
208 }
209 //
210
211 if (i >= numItemsToDelete) {
212 return;
213 }
214
215 deleteBackup (backupsList[i], loopFunc);
216 i++;
217 };
218
219 loopFunc ();
220 }
221
222 //for (var i = 0; i < numItemsToDelete; i++) {
223 // TODO WARNING: I'm calling deleteBackup rapidly, while deleting is async...(I should wait for each delete to complete before deleting the next)
224 //deleteBackup (backupsList[i], function() {
225
226 //});
227 //}
228
229 });
230 }
231
232 //var isCreatingBackup = false;
233
234 function backupNow(isAutomatic, backupName, callbackDone) {
235 console.log("backupNow - isAutomatic: " + isAutomatic + " name: " + backupName);
236 /*if (isCreatingBackup === true) {
237 console.log("backupNow - already running..skipping..");
238 return;
239 }*/
240
241 //isCreatingBackup = true;
242
243 /*if (!confirm("Perform a full backup? All windows and their tabs will be saved!")) {
244 return;
245 }*/
246
247 var fullBackup = {
248 windows: [],
249 isAutomatic: isAutomatic,
250 totNumTabs: 0
251 };
252
253 chrome.windows.getAll({populate : true}, function (window_list) {
254 var totNumTabs = 0;
255
256 for(var i=0;i<window_list.length;i++) {
257 var window = window_list[i];
258
259 //console.log ("Window " + i);
260
261 var bkpWindow = {
262 tabs: []
263 };
264
265 var windowTabs = window.tabs;
266 for (var j = 0; j < windowTabs.length; j++) {
267 var tab = windowTabs[j];
268
269 //console.log("==> Tab " + j + " (" + tab.index + "): " + tabUrl);
270
271 var bkpTab = {
272 url: tab.url,
273 title: tab.title
274 };
275
276 // Add tab to tabs arrays
277 bkpWindow.tabs.push(bkpTab);
278 }
279
280 totNumTabs += windowTabs.length;
281
282 fullBackup.windows.push(bkpWindow);
283 }
284
285 fullBackup.totNumTabs = totNumTabs;
286
287 var storageSetValues = {};
288 storageSetValues[backupName] = fullBackup;
289
290 // Store backup
291 chrome.storage.local.set(storageSetValues, function () {
292 if (chrome.runtime.lastError) {
293 //isCreatingBackup = false;
294 // TODO change icon to error..
295 //alert ("Error: " + chrome.runtime.lastError.message);
296 updateBrowserActionIcon (1);
297
298 callbackDone(false);
299 } else {
300 console.log("backup saved");
301 //alert("Backup saved successfully!");
302
303 chrome.storage.local.get("backups_list", function(items) {
304 var backupsList = [];
305 if(items.backups_list) {
306 backupsList = items.backups_list;
307 }
308
309 console.log("Updating 'backups_list' - cur. size: " + backupsList.length);
310
311 backupsList.push(backupName);
312
313 chrome.storage.local.set({"backups_list": backupsList}, function () {
314 //isCreatingBackup = false;
315
316 if (chrome.runtime.lastError) {
317 console.log ("Error saving backups_list: " + chrome.runtime.lastError.message);
318 updateBrowserActionIcon (1);
319 callbackDone(false);
320 } else {
321 console.log("Backups list saved successfully");
322
323 updateBrowserActionIcon (0);
324 callbackDone(true, backupName, fullBackup);
325
326 if (backupsList.length > parseInt(localStorage.prefsMaxBackupItems)) {
327 deleteOldestBackup();
328 }
329 }
330 });
331 });
332 }
333 });
334 });
335 }
336
337 /**
338 * 0 ==> OK
339 * 1 ==> ERROR
340 */
341 function updateBrowserActionIcon (status) {
342 var icon;
343 switch(status) {
344 case 0:
345 icon = "icon_ok.png";
346 break;
347 default:
348 icon = "icon_error.png";
349 break;
350 }
351
352 chrome.browserAction.setIcon({path: icon});
353 }
354
355 function deleteBackup (backupName, callback) {
356 console.log("Deleting backup " + backupName);
357
358 chrome.storage.local.remove(backupName, function() {
359 //console.log ("=> Deleted backup " + backupName);
360
361 chrome.storage.local.get("backups_list", function(items) {
362 //console.log ("==> got backups_list " + backupName);
363
364 if(!items.backups_list) {
365 callback();
366 return;
367 }
368
369 var backupsList = items.backups_list;
370
371 var index = backupsList.indexOf(backupName);
372 if (index >= 0) {
373 backupsList.splice(index, 1);
374 }
375
376 //console.log ("===> Updating backups_list (removing " + backupName + ")");
377
378 chrome.storage.local.set({"backups_list": backupsList}, function() {
379 //console.log ("===> Updated backups_list (removed " + backupName + ")");
380
381 callback();
382 });
383
384 //console.log ("==> EXIT got backups_list " + backupName);
385 });
386
387 //console.log ("=> EXIT Deleted backup " + backupName);
388 });
389
390 //console.log("EXIT Deleting backup " + backupName);
391
392
393 }
394
395 function restoreNow(backupName) {
396 console.log("restoreNow");
397
398 chrome.storage.local.get(backupName, function(items) {
399 if(!items[backupName]) {
400 alert("No Backup found");
401 return;
402 }
403
404 /*if (!confirm("Restore full backup?")) {
405 return;
406 }*/
407 /*
408 if (confirm("Would you like to close all existing windows first?")) {
409 chrome.windows.getAll({populate : false}, function (window_list) {
410 for(var i=0;i<window_list.length;i++) {
411 var window = window_list[i];
412 chrome.windows.remove(window.id);
413 }
414 });
415 }*/
416
417
418 var fullBackup = items[backupName];
419
420 for(var i=0;i<fullBackup.windows.length;i++) {
421 var window = fullBackup.windows[i];
422
423 //console.log ("Window " + i);
424
425 urlsToOpen = [];
426
427 var windowTabs = window.tabs;
428 for (var j = 0; j < windowTabs.length; j++) {
429 var tab = windowTabs[j];
430 var tabUrl = tab.url;
431 urlsToOpen.push(tabUrl);
432 }
433
434 var windowProperties = {
435 url: urlsToOpen
436 };
437
438 // Create a new Window
439 chrome.windows.create(windowProperties, function(createdWindow) {
440 //console.log("Created window id: " + createdWindow.id);
441
442 //chrome.tabs.remove(createdWindow.tabs[0].id);
443
444 // Create new tabs
445 /*var windowTabs = window.tabs;
446 for (var j = 0; j < windowTabs.length; j++) {
447 var tab = windowTabs[j];
448 var tabUrl = tab.url;
449
450 console.log("==> Tab " + j + ": " + tabUrl);
451
452 var tabProperties = {
453 url: tabUrl,
454 windowId: createdWindow.id
455 };
456
457 chrome.tabs.create(tabProperties, function(createdTab) {
458 // do nothing..
459 });
460 }*/
461 });
462
463
464
465 }
466 });
467 }