1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <title>Send to Picasa</title> 6 <style type="text/css"> 7 .invisible { display: none; } 8 .cancel-button { 9 cursor: pointer; 10 } 11 </style> 12 </head> 13 14 <body> 15 <div id="progress-container"> 16 <div id="files-sent-div">A of B files sent.</div> 17 <div> 18 <progress id="files-sent-progress">progress</progress> 19 <span class="cancel-button"> 20 <img id="cancel-normal" src="images/cancel_normal-16.png"> 21 <img id="cancel-hover" src="images/cancel_hover-16.png" class="invisible"> 22 </span> 23 </div> 24 <div id="time-remaining-div">Time remaining: unknown.</div> 25 </div> 26 <div id="completed-container" class="invisible"> 27 <div style="float:left;height:100%;padding:5px;"> 28 <img src="images/green_check-32.png" /> 29 </div> 30 <div style="float:left;height:100%;"> 31 <span id="files-completed-span">X files sent.</span> 32 <br><a id="view-album-link" href="" target="_blank">View Picasa Web Album</a> 33 </div> 34 </div> 35 <div id="failed-container" class="invisible"> 36 <span id="failure-span">Failure. A of B files sent.</span> 37 </div> 38 <div id="canceled-container" class="invisible"> 39 <span id="canceled-span">Canceled. X files sent.</span> 40 </div> 41 42 <script> 43 44 /** 45 * Notification constructor. 46 * 47 * Notification object is responsible for manipulating notification dom. 48 */ 49 function Notification() { 50 this.progressContainer_ = document.getElementById('progress-container'); 51 this.filesSentDiv_ = document.getElementById('files-sent-div'); 52 this.filesSentProgress_ = document.getElementById('files-sent-progress'); 53 54 this.cancelButton_ = document.querySelector('.cancel-button'); 55 this.cancelButton_.addEventListener('click', 56 this.handleOnCancelClicked_.bind(this)) 57 this.cancelButton_.addEventListener('mouseover', 58 this.handleOnCancelOver_.bind(this)) 59 this.cancelButton_.addEventListener('mouseout', 60 this.handleOnCancelOut_.bind(this)) 61 this.cancelNormal_ = document.getElementById('cancel-normal'); 62 this.cancelHover_ = document.getElementById('cancel-hover'); 63 64 this.timeRemainingDiv_ = document.getElementById('time-remaining-div'); 65 66 this.completedContainer_ = document.getElementById('completed-container'); 67 this.filesCompletedSpan_ = document.getElementById('files-completed-span'); 68 this.viewAlbumLink_ = document.getElementById('view-album-link'); 69 70 this.failedContainer_ = document.getElementById('failed-container'); 71 this.failureSpan_ = document.getElementById('failure-span'); 72 73 this.canceledContainer_ = document.getElementById('canceled-container'); 74 this.canceledSpan_ = document.getElementById('canceled-span'); 75 76 // Pass this to uploader object, so it will call update methods when needed. 77 chrome.extension.getBackgroundPage().bg.getUploader(window.location.hash). 78 setNotification(this); 79 } 80 81 Notification.prototype = { 82 /** 83 * Updates notification progress. 84 * @param {number} done Number of files uploaded. 85 * @param {number} total Total number of files to upload. 86 * @param {number} timeRemaining Estimated remaining time. 87 */ 88 update: function(done, total, timeRemaining) { 89 this.filesSentDiv_.textContent = done + ' of ' + total + ' files sent.'; 90 this.filesSentProgress_.max = total; 91 this.filesSentProgress_.value = done; 92 93 var timeStr = timeRemaining != null ? 94 this.timeToStr(Math.round(timeRemaining / 1000)) : 'unknown'; 95 this.timeRemainingDiv_.textContent = 'Time remaining: ' + timeStr + '.'; 96 }, 97 98 /** 99 * Converts time to user-readable string. 100 * @param {number} time Time interval. 101 * @return {string} String representation of time. 102 */ 103 timeToStr: function(time) { 104 var hours = Math.floor(time / 3600); 105 var minutes = Math.floor((time % 3600) / 60); 106 var seconds = time % 60; 107 if (hours > 0) { 108 seconds = 0; 109 } 110 var result = ''; 111 if (hours > 0) { 112 result += hours + ' hours '; 113 } 114 if (minutes > 0) { 115 result += minutes + ' minutes'; 116 } 117 if (seconds > 0 || time == 0) { 118 result += seconds + ' seconds'; 119 } 120 return result; 121 }, 122 123 /** 124 * Shows information about upload failure. 125 * @param {number} done Number of files uploaded. 126 * @param {number} total Total number of files to upload. 127 */ 128 showFailed: function(done, total) { 129 this.progressContainer_.classList.add('invisible'); 130 this.failedContainer_.classList.remove('invisible'); 131 this.failureSpan_.textContent = 132 'Failure. ' + done + ' of ' + total + ' files sent.'; 133 }, 134 135 /** 136 * Shows information about upload cancelation. 137 * @param {number} done Number of files uploaded. 138 * @param {number} total Total number of files to upload. 139 */ 140 showCanceled: function(done, total) { 141 this.progressContainer_.classList.add('invisible'); 142 this.canceledContainer_.classList.remove('invisible'); 143 this.canceledSpan_.textContent = 144 'Canceled. ' + done + ' of ' + total + ' files sent.'; 145 }, 146 147 /** 148 * Shows information about upload success. 149 * @param {number} done Number of files uploaded. 150 * @param {string} link Link to the picasa web album. 151 */ 152 showCompleted: function(done, link) { 153 this.progressContainer_.classList.add('invisible'); 154 this.completedContainer_.classList.remove('invisible'); 155 this.filesCompletedSpan_.textContent = done + ' files sent.'; 156 this.viewAlbumLink_.setAttribute('href', link); 157 }, 158 159 /** 160 * Event handler for cancel button clicked. 161 * @param {Event} e Event. 162 */ 163 handleOnCancelClicked_: function(e) { 164 chrome.extension.getBackgroundPage().bg.getUploader(window.location.hash). 165 cancel(); 166 }, 167 168 /** 169 * Event handler for cancel button mouseover. 170 * @param {Event} e Event. 171 */ 172 handleOnCancelOver_: function(e) { 173 this.cancelNormal_.classList.add('invisible'); 174 this.cancelHover_.classList.remove('invisible'); 175 }, 176 177 /** 178 * Event handler for cancel button mouseout. 179 * @param {Event} e Event. 180 */ 181 handleOnCancelOut_: function(e) { 182 this.cancelNormal_.classList.remove('invisible'); 183 this.cancelHover_.classList.add('invisible'); 184 } 185 }; 186 187 /** 188 * The single notification object. 189 * @type {Notification} 190 */ 191 var notification = new Notification(); 192 193 </script> 194 195 </body> 196 </html> 197