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.
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
);
15 document
.getElementById("restoreSelectedRadioSingleWindowSpanLabel").addEventListener('click', function() {
16 $('#restoreSelectedRadioSingleWindow').prop('checked', true);
19 document
.getElementById("restoreSelectedRadioMultipleWindowsSpanLabel").addEventListener('click', function() {
20 $('#restoreSelectedRadioMultipleWindows').prop('checked', true);
24 initBackupsList (false /*showAll*/);
27 $( "#dialog-confirm" ).dialog({
32 "Delete all items": function() {
33 $( this ).dialog( "close" );
36 $( this ).dialog( "close" );
45 function menu_ShowOptions () {
46 chrome
.tabs
.create({url
:chrome
.extension
.getURL("options.html")});
49 function menu_ShowAdvancedView() {
50 chrome
.tabs
.create({url
:chrome
.extension
.getURL("advanced.html")});
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;
62 updateRestoreSelectedDiv();
65 function menu_RestoreSelected_Real() {
66 var selectedCheckboxes
= $("input:checked");
68 var restoreToMultipleWindows
= $('#restoreSelectedRadioMultipleWindows').is(':checked');
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) {
83 //checkbox.tbrBackupName
84 //checkbox.tbrWindowIndex
85 console
.log("Restoring " + checkbox
.tbrBackupName
+ " --> " + checkbox
.tbrWindowIndex
);
87 var tabUrl
= checkbox
.tbrTabUrl
;
89 var windowIdx
= checkbox
.tbrWindowIndex
;
90 var bkpName
= checkbox
.tbrBackupName
;
91 var key
= bkpName
+ "_" + windowIdx
;
93 if (!(key
in windows
)) {
95 windowsKeys
.push(key
);
98 windows
[key
].push(tabUrl
);
100 allUrls
.push(checkbox
.tbrTabUrl
);
103 if (restoreToMultipleWindows
) {
104 for (var i
= 0; i
< windowsKeys
.length
; i
++) {
105 var key
= windowsKeys
[i
];
106 var urls
= windows
[key
];
108 var windowProperties
= {
112 // Create a new Window
113 chrome
.windows
.create(windowProperties
, function(createdWindow
) {
118 var windowProperties
= {
122 // Create a new Window
123 chrome
.windows
.create(windowProperties
, function(createdWindow
) {
129 function menu_RestoreSelected() {
130 bootbox
.confirm("Restore selection?", function(confirmed
) {
132 menu_RestoreSelected_Real();
140 function updateRestoreSelectedDiv() {
141 var selectedCheckboxes
= $("input:checked");
143 var numSelectedTabs
= 0;
144 var numSelectedWindows
= 0;
145 for (var i
= 0; i
< selectedCheckboxes
.length
; i
++) {
146 var checkbox
= selectedCheckboxes
[i
];
148 if (checkbox
.tbrIsWindow
!== undefined) {
149 if (checkbox
.tbrIsWindow
) {
150 numSelectedWindows
++;
154 if (checkbox
.tbrBackupName
=== undefined ||
155 checkbox
.tbrWindowIndex
=== undefined ||
156 checkbox
.tbrTabUrl
=== undefined) {
162 // find the first selected tab checkbox
166 $('#restoreSelectedInfoNumTabs').html(numSelectedTabs
);
168 var restoreDiv
= $('#floatingRightDiv');
170 if (numSelectedTabs
> 0) {
173 if (!restoreDiv
.is(':visible')) {
174 restoreDiv
.fadeIn(600);
180 if (restoreDiv
.is(':visible')) {
181 restoreDiv
.fadeOut(600);
186 function menu_ShowOlderBackups () {
187 // save current scrollbar position
188 //var scrollPosition = $(document).scrollTop();
190 // Re-initialize backups list
191 //initBackupsList(true /*showAll*/, function () {
192 // Update the scrollbar position to the saved one
193 // $(document).scrollTop(scrollPosition);
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);
204 var backupsDiv
= document
.getElementById ('backupsDiv');
206 chrome
.storage
.local
.get(null, function(items
) {
207 var backupsList
= [];
208 if(items
.backups_list
) {
209 backupsList
= items
.backups_list
;
212 var shouldInsert
= false;
214 for (var i
= backupsList
.length
-1; i
>= 0; i
--) {
215 var backupName
= backupsList
[i
];
216 var backupObj
= items
[backupName
];
222 if (backupObj
.isAutomatic
=== undefined) {
223 backupObj
.isAutomatic
= true;
226 if (oldestVisibleBackupName
== backupName
) {
227 // found last visible item, start inserting
232 insertBackupItem(backupName
, backupObj
, false /*insertAtBeginning*/, false /*doAnimation*/);
237 // Hide the "show all" link
238 $("#showOlderBackupsDiv").hide();
243 function insertBackupItem (backupName
, backupObj
, insertAtBeginning
, doAnimation
) {
244 var backupsDiv
= document
.getElementById ('backupsDiv');
246 var restoreButtonId
= 'restoreSelectedBackup_' + backupName
;
247 var deleteButtonId
= 'deleteSelectedBackup_' + backupName
;
248 var divId
= 'div_' + backupName
;
250 var elem
= document
.createElement("div");
252 // start with hidden element (only if we are doing the animation later)
253 elem
.style
.cssText
= 'display: none';
256 var backupTitleDivId
= 'backup_title_' + backupName
;
257 var backupItemClickId
= 'backup_click_' + backupName
;
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>' +
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>' +
274 '<div class="backupItemFooter">' +
275 (backupObj
.isAutomatic
? '<span class="backupItemFooterAutoBackup">AUTO BACKUP</span>' :
276 '<span class="backupItemFooterManualBackup">MANUAL BACKUP</span>') +
281 //elem.innerHTML += "# Windows: " +
282 //backupsDiv.appendChild(elem);
284 //var restoreFuncHandler = (function(backupName) {
285 // return function(event) {
286 // bootbox.confirm("Open Windows & Tabs of backup '" + backupName + "'?", function(confirmed) {
288 // chrome.extension.getBackgroundPage().restoreNow(backupName);
292 /*if (!confirm("Open Windows & Tabs of backup '" + backupName + "'?")) {
300 //var deleteFuncHandler = (function(backupName, elem) {
301 // return function(event) {
302 /*if (!confirm("Delete backup '" + backupName + "'?")) {
306 // bootbox.confirm("Delete backup '" + backupName + "'?", function(confirmed) {
308 // chrome.extension.getBackgroundPage().deleteBackup(backupName, function() {
312 //if (elem.parentNode) {
313 // elem.parentNode.removeChild(elem);
315 // removeBackupItemDiv (backupName);
321 //})(backupName, elem);
323 if (insertAtBeginning
&& backupsDiv
.childNodes
.length
> 0) {
324 // some items already exist
325 var firstNode
= backupsDiv
.childNodes
[0];
326 backupsDiv
.insertBefore(elem
, firstNode
);
328 backupsDiv
.appendChild(elem
);
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
);
338 if (restoreDiv
.is(':visible')) {
340 restoreDiv
.slideUp();
341 //$('#restoreSelectedDiv').slideUp();
343 restoreDiv
.slideDown();
344 //$('#restoreSelectedDiv').slideDown();
346 //restoreDiv.remove();
353 //document.getElementById(restoreButtonId).addEventListener('click', restoreFuncHandler);
354 //document.getElementById(deleteButtonId).addEventListener('click', deleteFuncHandler);
357 var divIdJQ
= jq(divId
);
358 $(divIdJQ
).slideDown(1000);
360 /*obj.animate({ height: 1, opacity: 1 }, {
362 complete: function(){obj.css('display', 'block');}
368 //$(divId).display = 'none';
369 //$(divId).slideUp();
370 //$(divId).fadeOut(1000);
371 /*var bkp = $("backupsDiv");
375 /*setTimeout( function() {
376 var obj = $("#" + divId);
383 return '#' + myid
.replace(/(:|\.| )/g,'\\$1');
386 function addClickListenerForWindowTitle (windowTitleDiv
, tabsDivId
) {
387 windowTitleDiv
.addEventListener('click', function(e
) {
388 var clickedElem
= e
.target
;
390 if (clickedElem
.className
.indexOf("parentIgnoreClick") != -1) {
395 $(jq(tabsDivId
)).slideToggle();
399 function addClickListenerForWindowCheckbox(checkboxWindowElem
, windowTabs
, backupName
, i
) {
400 checkboxWindowElem
.addEventListener('click', function(e
) {
401 var isChecked
= checkboxWindowElem
.checked
;
403 for (var j
= 0; j
< windowTabs
.length
; j
++) {
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;
412 updateRestoreSelectedDiv();
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.");
425 var backupTitleDivId
= 'backup_title_' + backupName
;
427 var elem
= document
.createElement("div");
428 var divId
= "restoreDiv_" + backupName
;
431 elem
.className
= 'restoreDiv';
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";
443 expandCollapseDiv
.appendChild(collapseAElem
);
444 expandCollapseDiv
.appendChild(document
.createTextNode(' / '));
445 expandCollapseDiv
.appendChild(expandAElem
);
447 elem
.appendChild(expandCollapseDiv
);
449 var allTabsDivsIds
= [];
451 var fullBackup
= items
[backupName
];
453 for(var i
= 0; i
< fullBackup
.windows
.length
; i
++) {
454 var window
= fullBackup
.windows
[i
];
455 var windowTabs
= window
.tabs
;
457 var windowTitleDiv
= document
.createElement('div');
459 //windowTitleDiv.innerHTML = "<span>Window " + (i+1) + '</span>' +
460 // '<span style="float: right; font-size: 12px;">Nr. Tabs: ' + windowTabs.length + '</span>';
462 windowTitleDiv
.className
= 'windowTitleDiv';
464 var tabsDiv
= document
.createElement('div');
465 tabsDiv
.id
= 'tabsDiv_' + backupName
+ '_' + i
;
466 tabsDiv
.className
= 'tabsDiv';
467 tabsDiv
.hidden
= true;
469 allTabsDivsIds
.push(tabsDiv
.id
);
471 addClickListenerForWindowTitle(windowTitleDiv
, tabsDiv
.id
);
473 var checkboxWindowId
= 'checkbox_window_' + backupName
+ '_' + i
;
475 var checkboxWindowElem
= document
.createElement('input');
476 checkboxWindowElem
.type
= "checkbox";
477 checkboxWindowElem
.id
= checkboxWindowId
;
478 checkboxWindowElem
.className
= "regular-checkbox parentIgnoreClick";
480 checkboxWindowElem
.tbrIsWindow
= true;
482 var checkboxWindowLabelElem
= document
.createElement('label')
483 checkboxWindowLabelElem
.className
= "parentIgnoreClick";
484 checkboxWindowLabelElem
.htmlFor
= checkboxWindowId
;
485 checkboxWindowLabelElem
.style
.cssText
= 'margin-bottom: -4px; margin-right: 8px;';
487 addClickListenerForWindowCheckbox(checkboxWindowElem
, windowTabs
, backupName
, i
);
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>';
496 windowTitleDiv
.appendChild(checkboxWindowElem
);
497 windowTitleDiv
.appendChild(checkboxWindowLabelElem
);
498 windowTitleDiv
.appendChild(windowTitleSpan
);
503 for (var j
= 0; j
< windowTabs
.length
; j
++) {
504 var tab
= windowTabs
[j
];
505 var tabTitle
= tab
.title
;
506 var tabUrl
= tab
.url
;
508 var checkboxId
= 'checkbox_tab_' + backupName
+ '_' + i
+ '_' + j
;
510 var tabElem
= document
.createElement('div');
511 tabElem
.style
.cssText
= "position: relative";
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";
521 checkboxTabElem
.tbrBackupName
= backupName
;
522 checkboxTabElem
.tbrWindowIndex
= i
;
523 checkboxTabElem
.tbrTabUrl
= tabUrl
;
525 var checkboxTabLabelElem
= document
.createElement('label')
526 checkboxTabLabelElem
.htmlFor
= checkboxId
;
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>';
533 tabElem
.appendChild(checkboxTabElem
);
534 tabElem
.appendChild(checkboxTabLabelElem
);
535 tabElem
.appendChild(tabSpanElem
);
537 tabsDiv
.appendChild(tabElem
);
539 checkboxTabElem
.addEventListener('change', function (e
) {
540 console
.log('cb changed - ' + e
.target
.id
+ ' : ' + e
.target
.checked
);
542 updateRestoreSelectedDiv();
544 //addClickListenerFor(checkboxId
545 //checkboxTabElem.addEventListener('click', function() {
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 />' +
555 elem
.appendChild(windowTitleDiv
);
556 elem
.appendChild(tabsDiv
);
561 collapseAElem
.addEventListener('click', function () {
562 for (var i
= 0; i
< allTabsDivsIds
.length
; i
++) {
563 $(jq(allTabsDivsIds
[i
])).slideUp();
567 expandAElem
.addEventListener('click', function () {
568 for (var i
= 0; i
< allTabsDivsIds
.length
; i
++) {
569 $(jq(allTabsDivsIds
[i
])).slideDown();
573 var backupTitleDiv
= document
.getElementById(backupTitleDivId
);
574 backupTitleDiv
.appendChild(elem
);
576 $(jq(divId
)).slideDown();
577 //$('#restoreSelectedDiv').slideDown();
579 //$('#restoreSelectedDiv').fadeIn(1000);
584 function removeBackupItemDiv (backupName
) {
585 var divId
= 'div_' + backupName
;
586 var divIdClean
= jq(divId
);
587 var obj
= $(divIdClean
);
590 obj
.animate({ height
: 0, opacity
: 0 }, {
592 complete: function(){obj
.remove();}
595 var backupItemDiv
= document
.getElementById (divId
);
596 if (backupItemDiv
.parentNode
) {
597 // backupItemDiv.parentNode.removeChild(backupItemDiv);
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);
611 $("#showOlderBackupsDiv").hide();
614 $("#backupsDiv").hide();
617 chrome
.storage
.local
.get(null, function(items
) {
618 var backupsList
= [];
619 if(items
.backups_list
) {
620 backupsList
= items
.backups_list
;
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
];
633 if (backupObj
.isAutomatic
=== undefined) {
634 backupObj
.isAutomatic
= true;
638 if (numInsertedItems
>= 10) {
639 $("#showOlderBackupsDiv").show();
644 insertBackupItem(backupName
, backupObj
, false /*insertAtBeginning*/, false /*doAnimation*/);
650 $("#backupsDiv").slideDown();
662 var lastTimeBackupNowClicked
= 0;
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) {
673 lastTimeBackupNowClicked
= new Date().getTime();
675 chrome
.extension
.getBackgroundPage().backupNowManual(function(success
, backupName
, backupObj
) {
677 //updateBackupsList();
678 insertBackupItem (backupName
, backupObj
, true /*insertAtBeginning*/, true /*doAnimation*/);
681 //bootbox.alert("Backup successfully created!");
683 alert('An error occured while creating the backup..');
689 function menu_restoreNow() {
690 chrome
.extension
.getBackgroundPage().restoreNow('full_backup');
693 //document.onload(function () {
694 //var a = document.getElementById("myid");
695 //a.innerHTML = "ciaociao";
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);