]> git.wh0rd.org - chrome-ext/tabs-backup.git/blob - advanced.js
my customizations
[chrome-ext/tabs-backup.git] / advanced.js
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Add event listeners once the DOM has fully loaded by listening for the
6 // `DOMContentLoaded` event on the document, and adding your listeners to
7 // specific elements when it triggers.
8 document.addEventListener('DOMContentLoaded', function () {
9 //document.querySelector('button').addEventListener('click', testf);
10 //document.getElementById("menuItem_restoreNow").addEventListener('click', menu_restoreNow);
11 document.getElementById("menuItem_showOlderBackups").addEventListener('click', menu_ShowOlderBackups);
12 document.getElementById("restoreSelectedDiv").addEventListener('click', menu_RestoreSelected);
13 document.getElementById("restoreSelectedClearSelectionLink").addEventListener('click', menu_ClearSelection);
14
15 document.getElementById("restoreSelectedRadioSingleWindowSpanLabel").addEventListener('click', function() {
16 $('#restoreSelectedRadioSingleWindow').prop('checked', true);
17 });
18
19 document.getElementById("restoreSelectedRadioMultipleWindowsSpanLabel").addEventListener('click', function() {
20 $('#restoreSelectedRadioMultipleWindows').prop('checked', true);
21 });
22
23
24 initBackupsList (false /*showAll*/);
25
26 /*$(function() {
27 $( "#dialog-confirm" ).dialog({
28 resizable: false,
29 height:140,
30 modal: true,
31 buttons: {
32 "Delete all items": function() {
33 $( this ).dialog( "close" );
34 },
35 Cancel: function() {
36 $( this ).dialog( "close" );
37 }
38 }
39 });
40 });*/
41
42
43 });
44
45 function menu_ShowOptions () {
46 chrome.tabs.create({url:chrome.extension.getURL("options.html")});
47 }
48
49 function menu_ShowAdvancedView() {
50 chrome.tabs.create({url:chrome.extension.getURL("advanced.html")});
51 }
52
53 function menu_ClearSelection () {
54 var selectedCheckboxes = $("input:checked");
55 for (var i = 0; i < selectedCheckboxes.length; i++) {
56 var checkbox = selectedCheckboxes[i];
57 if (checkbox.type == 'checkbox') {
58 checkbox.checked = false;
59 }
60 }
61
62 updateRestoreSelectedDiv();
63 }
64
65 function menu_RestoreSelected_Real() {
66 var selectedCheckboxes = $("input:checked");
67
68 var restoreToMultipleWindows = $('#restoreSelectedRadioMultipleWindows').is(':checked');
69
70 var allUrls = [];
71
72 var windows = {};
73 var windowsKeys = [];
74
75 for (var i = 0; i < selectedCheckboxes.length; i++) {
76 var checkbox = selectedCheckboxes[i];
77 //if (!checkbox.hasAttribute('tbrBackupName') || !checkbox.hasAttribute('tbrWindowIndex')) {
78 if (checkbox.tbrBackupName === undefined ||
79 checkbox.tbrWindowIndex === undefined ||
80 checkbox.tbrTabUrl === undefined) {
81 continue;
82 }
83 //checkbox.tbrBackupName
84 //checkbox.tbrWindowIndex
85 console.log("Restoring " + checkbox.tbrBackupName + " --> " + checkbox.tbrWindowIndex);
86
87 var tabUrl = checkbox.tbrTabUrl;
88
89 var windowIdx = checkbox.tbrWindowIndex;
90 var bkpName = checkbox.tbrBackupName;
91 var key = bkpName + "_" + windowIdx;
92
93 if (!(key in windows)) {
94 windows[key] = [];
95 windowsKeys.push(key);
96 }
97
98 windows[key].push(tabUrl);
99
100 allUrls.push(checkbox.tbrTabUrl);
101 }
102
103 if (restoreToMultipleWindows) {
104 for (var i = 0; i < windowsKeys.length; i++) {
105 var key = windowsKeys[i];
106 var urls = windows[key];
107
108 var windowProperties = {
109 url: urls
110 };
111
112 // Create a new Window
113 chrome.windows.create(windowProperties, function(createdWindow) {
114
115 });
116 }
117 } else {
118 var windowProperties = {
119 url: allUrls
120 };
121
122 // Create a new Window
123 chrome.windows.create(windowProperties, function(createdWindow) {
124
125 });
126 }
127 }
128
129 function menu_RestoreSelected() {
130 bootbox.confirm("Restore selection?", function(confirmed) {
131 if (confirmed) {
132 menu_RestoreSelected_Real();
133 }
134 });
135
136
137
138 }
139
140 function updateRestoreSelectedDiv() {
141 var selectedCheckboxes = $("input:checked");
142
143 var numSelectedTabs = 0;
144 var numSelectedWindows = 0;
145 for (var i = 0; i < selectedCheckboxes.length; i++) {
146 var checkbox = selectedCheckboxes[i];
147
148 if (checkbox.tbrIsWindow !== undefined) {
149 if (checkbox.tbrIsWindow) {
150 numSelectedWindows++;
151 }
152 }
153
154 if (checkbox.tbrBackupName === undefined ||
155 checkbox.tbrWindowIndex === undefined ||
156 checkbox.tbrTabUrl === undefined) {
157 continue;
158 }
159
160
161
162 // find the first selected tab checkbox
163 numSelectedTabs++;
164 }
165
166 $('#restoreSelectedInfoNumTabs').html(numSelectedTabs);
167
168 var restoreDiv = $('#floatingRightDiv');
169
170 if (numSelectedTabs > 0) {
171
172
173 if (!restoreDiv.is(':visible')) {
174 restoreDiv.fadeIn(600);
175 }
176
177
178
179 } else {
180 if (restoreDiv.is(':visible')) {
181 restoreDiv.fadeOut(600);
182 }
183 }
184 }
185
186 function menu_ShowOlderBackups () {
187 // save current scrollbar position
188 //var scrollPosition = $(document).scrollTop();
189
190 // Re-initialize backups list
191 //initBackupsList(true /*showAll*/, function () {
192 // Update the scrollbar position to the saved one
193 // $(document).scrollTop(scrollPosition);
194 //});
195
196
197
198 var oldestVisibleBackupItem = $(".backupItem:last");
199 var oldestVisibleBackupItemId = oldestVisibleBackupItem.attr('id');
200 // the id is in the form 'div_' + backupName
201 var oldestVisibleBackupName = oldestVisibleBackupItemId.substring(4);
202
203
204 var backupsDiv = document.getElementById ('backupsDiv');
205
206 chrome.storage.local.get(null, function(items) {
207 var backupsList = [];
208 if(items.backups_list) {
209 backupsList = items.backups_list;
210 }
211
212 var shouldInsert = false;
213
214 for (var i = backupsList.length-1; i >= 0; i--) {
215 var backupName = backupsList[i];
216 var backupObj = items[backupName];
217
218 if (!backupObj) {
219 continue;
220 }
221
222 if (backupObj.isAutomatic === undefined) {
223 backupObj.isAutomatic = true;
224 }
225
226 if (oldestVisibleBackupName == backupName) {
227 // found last visible item, start inserting
228 shouldInsert = true;
229 } else {
230
231 if (shouldInsert) {
232 insertBackupItem(backupName, backupObj, false /*insertAtBeginning*/, false /*doAnimation*/);
233 }
234 }
235 }
236
237 // Hide the "show all" link
238 $("#showOlderBackupsDiv").hide();
239 });
240
241 }
242
243 function insertBackupItem (backupName, backupObj, insertAtBeginning, doAnimation) {
244 var backupsDiv = document.getElementById ('backupsDiv');
245
246 var restoreButtonId = 'restoreSelectedBackup_' + backupName;
247 var deleteButtonId = 'deleteSelectedBackup_' + backupName;
248 var divId = 'div_' + backupName;
249
250 var elem = document.createElement("div");
251 if (doAnimation) {
252 // start with hidden element (only if we are doing the animation later)
253 elem.style.cssText = 'display: none';
254 }
255
256 var backupTitleDivId = 'backup_title_' + backupName;
257 var backupItemClickId = 'backup_click_' + backupName;
258
259 elem.id = divId;
260 elem.className = 'backupItem';
261 elem.innerHTML = '<div class="backupItemWrapper" id="' + backupTitleDivId + '">' +
262 '<div class="backupItemContent" id="' + backupItemClickId + '">' +
263 '<div class="backupItemTitle">' + backupName + "</div>" +
264 '<div class="backupItemDetails">' +
265 'Nr. Windows:<span class="backupItemDetailsNr">' + backupObj.windows.length + '</span><br />' +
266 'Nr. Tabs:<span class="backupItemDetailsNr">' + backupObj.totNumTabs + '</span>' +
267 '</div>' +
268
269 // '<div class="backupItemToolbar">' +
270 // '<a id="' + restoreButtonId + '"><img src="icon_48.png" title="Open Windows & Tabs" style="border: 0; width: 24px; height: 24px" /></a>' +
271 // '<a id="' + deleteButtonId + '"><img src="trash_48.png" title="Delete Backup" style="border: 0; width: 22px; height: 22px" /></a>' +
272 // '</div>' +
273
274 '<div class="backupItemFooter">' +
275 (backupObj.isAutomatic ? '<span class="backupItemFooterAutoBackup">AUTO BACKUP</span>' :
276 '<span class="backupItemFooterManualBackup">MANUAL BACKUP</span>') +
277 '</div>' +
278 '</div>' +
279 '</div>';
280
281 //elem.innerHTML += "# Windows: " +
282 //backupsDiv.appendChild(elem);
283
284 //var restoreFuncHandler = (function(backupName) {
285 // return function(event) {
286 // bootbox.confirm("Open Windows & Tabs of backup '" + backupName + "'?", function(confirmed) {
287 // if (confirmed) {
288 // chrome.extension.getBackgroundPage().restoreNow(backupName);
289 // }
290 // });
291
292 /*if (!confirm("Open Windows & Tabs of backup '" + backupName + "'?")) {
293 return;
294 }*/
295
296
297 // };
298 //})(backupName);
299
300 //var deleteFuncHandler = (function(backupName, elem) {
301 // return function(event) {
302 /*if (!confirm("Delete backup '" + backupName + "'?")) {
303 return;
304 }*/
305
306 // bootbox.confirm("Delete backup '" + backupName + "'?", function(confirmed) {
307 // if (confirmed) {
308 // chrome.extension.getBackgroundPage().deleteBackup(backupName, function() {
309
310 // });
311
312 //if (elem.parentNode) {
313 // elem.parentNode.removeChild(elem);
314 //
315 // removeBackupItemDiv (backupName);
316 // }
317 // });
318
319
320 // };
321 //})(backupName, elem);
322
323 if (insertAtBeginning && backupsDiv.childNodes.length > 0) {
324 // some items already exist
325 var firstNode = backupsDiv.childNodes[0];
326 backupsDiv.insertBefore(elem, firstNode);
327 } else {
328 backupsDiv.appendChild(elem);
329 }
330
331 $(jq(backupItemClickId)).click(function() {
332 var restoreDivId = "restoreDiv_" + backupName;
333 var restoreDiv = $(jq(restoreDivId));
334 if (restoreDiv.length == 0) {
335 // element never created, create it
336 showAdvancedRestoreFor(backupName);
337 } else {
338 if (restoreDiv.is(':visible')) {
339 //restoreDiv.hide();
340 restoreDiv.slideUp();
341 //$('#restoreSelectedDiv').slideUp();
342 } else {
343 restoreDiv.slideDown();
344 //$('#restoreSelectedDiv').slideDown();
345 }
346 //restoreDiv.remove();
347
348 }
349
350
351 });
352
353 //document.getElementById(restoreButtonId).addEventListener('click', restoreFuncHandler);
354 //document.getElementById(deleteButtonId).addEventListener('click', deleteFuncHandler);
355
356 if (doAnimation) {
357 var divIdJQ = jq(divId);
358 $(divIdJQ).slideDown(1000);
359 }
360 /*obj.animate({ height: 1, opacity: 1 }, {
361 duration: 1000,
362 complete: function(){obj.css('display', 'block');}
363 });*/
364
365 //obj.fadeIn(2000);
366 //obj.slideDown();
367
368 //$(divId).display = 'none';
369 //$(divId).slideUp();
370 //$(divId).fadeOut(1000);
371 /*var bkp = $("backupsDiv");
372 bkp.remove();
373 var div = $(divId);
374 var a = 0;*/
375 /*setTimeout( function() {
376 var obj = $("#" + divId);
377 obj.fadeIn();
378
379 }, 1000 );*/
380 }
381
382 function jq(myid) {
383 return '#' + myid.replace(/(:|\.| )/g,'\\$1');
384 }
385
386 function addClickListenerForWindowTitle (windowTitleDiv, tabsDivId) {
387 windowTitleDiv.addEventListener('click', function(e) {
388 var clickedElem = e.target;
389 if (clickedElem) {
390 if (clickedElem.className.indexOf("parentIgnoreClick") != -1) {
391 // ignore click
392 return;
393 }
394 }
395 $(jq(tabsDivId)).slideToggle();
396 });
397 }
398
399 function addClickListenerForWindowCheckbox(checkboxWindowElem, windowTabs, backupName, i) {
400 checkboxWindowElem.addEventListener('click', function(e) {
401 var isChecked = checkboxWindowElem.checked;
402
403 for (var j = 0; j < windowTabs.length; j++) {
404
405 var checkboxId = 'checkbox_tab_' + backupName + '_' + i + '_' + j;
406 $(jq(checkboxId)).prop('checked', isChecked);
407 //var el = document.getElementById(checkboxId);
408 //document.getElementById(checkboxId).change()
409 //document.getElementById(checkboxId).checked = isChecked;
410 }
411
412 updateRestoreSelectedDiv();
413 });
414 }
415
416
417
418 function showAdvancedRestoreFor (backupName) {
419 chrome.storage.local.get(backupName, function(items) {
420 if(!items[backupName]) {
421 alert("An error occured. Please reload the page.");
422 return;
423 }
424
425 var backupTitleDivId = 'backup_title_' + backupName;
426
427 var elem = document.createElement("div");
428 var divId = "restoreDiv_" + backupName;
429
430 elem.id = divId;
431 elem.className = 'restoreDiv';
432 elem.innerHTML = '';
433
434 var expandCollapseDiv = document.createElement('div');
435 expandCollapseDiv.className = "restoreDivCollapseExpand";
436 //expandCollapseDiv.innerHTML = 'Collapse all';
437 var collapseAElem = document.createElement('a');
438 collapseAElem.innerHTML = "Collapse all";
439 var expandAElem = document.createElement('a');
440 expandAElem.innerHTML = "Expand all";
441
442
443 expandCollapseDiv.appendChild(collapseAElem);
444 expandCollapseDiv.appendChild(document.createTextNode(' / '));
445 expandCollapseDiv.appendChild(expandAElem);
446
447 elem.appendChild(expandCollapseDiv);
448
449 var allTabsDivsIds = [];
450
451 var fullBackup = items[backupName];
452
453 for(var i = 0; i < fullBackup.windows.length; i++) {
454 var window = fullBackup.windows[i];
455 var windowTabs = window.tabs;
456
457 var windowTitleDiv = document.createElement('div');
458
459 //windowTitleDiv.innerHTML = "<span>Window " + (i+1) + '</span>' +
460 // '<span style="float: right; font-size: 12px;">Nr. Tabs: ' + windowTabs.length + '</span>';
461
462 windowTitleDiv.className = 'windowTitleDiv';
463
464 var tabsDiv = document.createElement('div');
465 tabsDiv.id = 'tabsDiv_' + backupName + '_' + i;
466 tabsDiv.className = 'tabsDiv';
467 tabsDiv.hidden = true;
468
469 allTabsDivsIds.push(tabsDiv.id);
470
471 addClickListenerForWindowTitle(windowTitleDiv, tabsDiv.id);
472
473 var checkboxWindowId = 'checkbox_window_' + backupName + '_' + i;
474
475 var checkboxWindowElem = document.createElement('input');
476 checkboxWindowElem.type = "checkbox";
477 checkboxWindowElem.id = checkboxWindowId;
478 checkboxWindowElem.className = "regular-checkbox parentIgnoreClick";
479
480 checkboxWindowElem.tbrIsWindow = true;
481
482 var checkboxWindowLabelElem = document.createElement('label')
483 checkboxWindowLabelElem.className = "parentIgnoreClick";
484 checkboxWindowLabelElem.htmlFor = checkboxWindowId;
485 checkboxWindowLabelElem.style.cssText = 'margin-bottom: -4px; margin-right: 8px;';
486
487 addClickListenerForWindowCheckbox(checkboxWindowElem, windowTabs, backupName, i);
488
489
490 var windowTitleSpan = document.createElement('span');
491 windowTitleSpan.innerHTML = '<span style="font-weight: bold">Window ' + (i+1) + '</span>' +
492 '<span style="float: right; font-size: 11px;">Tabs: ' + windowTabs.length + '</span>';
493 //windowTitleSpan.innerHTML = '<span>Window ' + (i+1) + '</span>' +
494 // '<br /><span style="font-size: 10px;">Nr. Tabs: ' + windowTabs.length + '</span>';
495
496 windowTitleDiv.appendChild(checkboxWindowElem);
497 windowTitleDiv.appendChild(checkboxWindowLabelElem);
498 windowTitleDiv.appendChild(windowTitleSpan);
499
500
501
502
503 for (var j = 0; j < windowTabs.length; j++) {
504 var tab = windowTabs[j];
505 var tabTitle = tab.title;
506 var tabUrl = tab.url;
507
508 var checkboxId = 'checkbox_tab_' + backupName + '_' + i + '_' + j;
509
510 var tabElem = document.createElement('div');
511 tabElem.style.cssText = "position: relative";
512
513 var checkboxTabElem = document.createElement('input');
514 checkboxTabElem.type = "checkbox";
515 //checkboxTabElem.name = "name";
516 //checkboxTabElem.value = "value";
517 checkboxTabElem.id = checkboxId;
518 checkboxTabElem.className = "regular-checkbox";
519
520 // custom attributes
521 checkboxTabElem.tbrBackupName = backupName;
522 checkboxTabElem.tbrWindowIndex = i;
523 checkboxTabElem.tbrTabUrl = tabUrl;
524
525 var checkboxTabLabelElem = document.createElement('label')
526 checkboxTabLabelElem.htmlFor = checkboxId;
527
528 var tabSpanElem = document.createElement('span');
529 tabSpanElem.className = "restoreTabSpan";
530 var title = tabTitle === '' ? tabUrl : tabTitle;
531 tabSpanElem.innerHTML = '<a href="' + tabUrl + '" target="_blank">' + title + '</a>';
532
533 tabElem.appendChild(checkboxTabElem);
534 tabElem.appendChild(checkboxTabLabelElem);
535 tabElem.appendChild(tabSpanElem);
536
537 tabsDiv.appendChild(tabElem);
538
539 checkboxTabElem.addEventListener('change', function (e) {
540 console.log('cb changed - ' + e.target.id + ' : ' + e.target.checked);
541
542 updateRestoreSelectedDiv();
543 });
544 //addClickListenerFor(checkboxId
545 //checkboxTabElem.addEventListener('click', function() {
546 //});
547
548 //var checkboxId = 'checkbox_tab_' + backupName + '_' + i + '_' + j;
549 //var checkboxHtml = '<input type="checkbox" id="' + checkboxId + '" class="regular-checkbox" /><label for="' + checkboxId + '" class="labelCheckbox"></label>'
550 //tabsDiv.innerHTML += '<div style="position: relative">' + checkboxHtml + '<span class="restoreTabSpan"><a href="' + tabUrl + '" target="_blank">' + tabTitle + '</a></span>' + '<br />' +
551 // '</div>';
552 }
553
554
555 elem.appendChild(windowTitleDiv);
556 elem.appendChild(tabsDiv);
557
558 }
559
560
561 collapseAElem.addEventListener('click', function () {
562 for (var i = 0; i < allTabsDivsIds.length; i++) {
563 $(jq(allTabsDivsIds[i])).slideUp();
564 }
565 });
566
567 expandAElem.addEventListener('click', function () {
568 for (var i = 0; i < allTabsDivsIds.length; i++) {
569 $(jq(allTabsDivsIds[i])).slideDown();
570 }
571 });
572
573 var backupTitleDiv = document.getElementById(backupTitleDivId);
574 backupTitleDiv.appendChild(elem);
575 $(jq(divId)).hide();
576 $(jq(divId)).slideDown();
577 //$('#restoreSelectedDiv').slideDown();
578
579 //$('#restoreSelectedDiv').fadeIn(1000);
580
581 });
582 }
583
584 function removeBackupItemDiv (backupName) {
585 var divId = 'div_' + backupName;
586 var divIdClean = jq(divId);
587 var obj = $(divIdClean);
588 //obj.fadeOut();
589 //obj.slideUp();
590 obj.animate({ height: 0, opacity: 0 }, {
591 duration: 1000,
592 complete: function(){obj.remove();}
593 });
594
595 var backupItemDiv = document.getElementById (divId);
596 if (backupItemDiv.parentNode) {
597 // backupItemDiv.parentNode.removeChild(backupItemDiv);
598 }
599 }
600
601 function initBackupsList(showAll, callback) {
602 var backupsDiv = document.getElementById ('backupsDiv');
603 //var node = backupsDiv.childNodes[0];
604 backupsDiv.innerHTML = '';
605 //backupsDiv.style = 'display: none';
606 //$("#backupsDiv").html("");
607 /*while (backupsDiv.hasChildNodes()) {
608 backupsDiv.removeChild(backupsDiv.lastChild);
609 }*/
610
611 $("#showOlderBackupsDiv").hide();
612
613 if (!showAll) {
614 $("#backupsDiv").hide();
615 }
616
617 chrome.storage.local.get(null, function(items) {
618 var backupsList = [];
619 if(items.backups_list) {
620 backupsList = items.backups_list;
621 }
622
623 var numInsertedItems = 0;
624 for (var i = backupsList.length-1; i >= 0; i--) {
625 //for (var i = 0; i < backupsList.length; i++) {
626 var backupName = backupsList[i];
627 var backupObj = items[backupName];
628
629 if (!backupObj) {
630 continue;
631 }
632
633 if (backupObj.isAutomatic === undefined) {
634 backupObj.isAutomatic = true;
635 }
636
637 if (!showAll) {
638 if (numInsertedItems >= 10) {
639 $("#showOlderBackupsDiv").show();
640 break;
641 }
642 }
643
644 insertBackupItem(backupName, backupObj, false /*insertAtBeginning*/, false /*doAnimation*/);
645
646 numInsertedItems++;
647 }
648
649 if (!showAll) {
650 $("#backupsDiv").slideDown();
651 }
652
653 if (callback) {
654 callback();
655 }
656
657 });
658
659
660 }
661
662 var lastTimeBackupNowClicked = 0;
663
664 function menu_backupNow() {
665 // Ignore clicks if less than 1 second has passed since last click (avoids rapid useless backups)
666 if (lastTimeBackupNowClicked != 0) {
667 var diffTime = Math.abs(new Date().getTime() - lastTimeBackupNowClicked);
668 if (diffTime < 1000) {
669 return;
670 }
671 }
672
673 lastTimeBackupNowClicked = new Date().getTime();
674
675 chrome.runtime.getBackgroundPage((bg) => bg.backupNowManual(function(success, backupName, backupObj) {
676 if (success) {
677 //updateBackupsList();
678 insertBackupItem (backupName, backupObj, true /*insertAtBeginning*/, true /*doAnimation*/);
679
680
681 //bootbox.alert("Backup successfully created!");
682 } else {
683 alert('An error occured while creating the backup..');
684 }
685 }));
686
687 }
688
689 function menu_restoreNow() {
690 chrome.runtime.getBackgroundPage((bg) => bg.restoreNow('full_backup'));
691 }
692
693 //document.onload(function () {
694 //var a = document.getElementById("myid");
695 //a.innerHTML = "ciaociao";
696 //});
697
698 /*
699 var storageLocal = chrome.storage.local;
700 storageLocal.getBytesInUse(null, function(bytesInUse) {
701 var elem = document.createElement("div");
702 elem.innerHTML = "<b>BYTES IN USE: " + bytesInUse + "</b><br />";
703 document.body.appendChild(elem);
704 });*/