|
1 /*! |
|
2 \file statusbar.js This module contains the StatusBar class. |
|
3 */ |
|
4 |
|
5 /*! |
|
6 Class to handle displaying and updating the status bar. Only 1 status bar |
|
7 should be created for the browser. This class is not designed to be code |
|
8 space efficient for creating multiple status bar objects. |
|
9 */ |
|
10 function StatusBar() |
|
11 { |
|
12 // Private Classes |
|
13 |
|
14 /*! |
|
15 Class to handle updating the status bar title. Only 1 title should be |
|
16 created for the browser status bar. This class is not designed to be code |
|
17 space efficient for creating multiple title objects. |
|
18 */ |
|
19 function Title() |
|
20 { |
|
21 // Private Methods |
|
22 |
|
23 //! Changes the current title to the specified title. |
|
24 /*! |
|
25 \param title new title to display |
|
26 \param doRepaint force immediate repaint if true |
|
27 */ |
|
28 function setTitle(title, doRepaint) |
|
29 { |
|
30 document.getElementById('title').innerHTML = title; |
|
31 if (doRepaint) |
|
32 window.snippets.StatusBarChromeId.repaint(); |
|
33 } |
|
34 |
|
35 // Public Methods |
|
36 |
|
37 //! Handles title change signal. |
|
38 /*! |
|
39 \param title new title |
|
40 */ |
|
41 this.handleTitleChange = function(title) |
|
42 { |
|
43 if ((!window.views.WebView.currentPageIsSuperPage()) && |
|
44 window.views.current().type == "webView") { |
|
45 if (title != "") |
|
46 setTitle(title, true); |
|
47 } |
|
48 } |
|
49 |
|
50 //! Handles title partial URL change signal. |
|
51 /*! |
|
52 \param partialUrl new title |
|
53 */ |
|
54 this.handlePartialUrlChange = function(partialUrl) |
|
55 { |
|
56 if ((!window.views.WebView.currentPageIsSuperPage()) && |
|
57 window.views.current().type == "webView") { |
|
58 setTitle(partialUrl, true); |
|
59 } |
|
60 } |
|
61 |
|
62 //! Handles title update in response to current view change signal. |
|
63 this.handleCurrentViewChange = function() |
|
64 { |
|
65 if(window.views.WebView.currentPageIsSuperPage()) { |
|
66 //alert(window.views.WebView.currentSuperPageName()); |
|
67 if (window.views.WebView.currentSuperPageName() == "BookmarkTreeView") { |
|
68 setTitle(window.localeDelegate.translateText("content_view_menu_bookmarks"), false); |
|
69 } |
|
70 else if (window.views.WebView.currentSuperPageName() == "BookmarkHistoryView") { |
|
71 setTitle(window.localeDelegate.translateText("content_view_menu_history"), false); |
|
72 } |
|
73 else if (window.views.WebView.currentSuperPageName() == "SettingsView") { |
|
74 setTitle(window.localeDelegate.translateText("settings_settings"), false); |
|
75 } |
|
76 } |
|
77 else { |
|
78 if (window.views.current().type == "webView") { |
|
79 /* For new windows, show title as 'New Window' */ |
|
80 if ((window.pageController.currentDocTitle == "") && |
|
81 (window.pageController.currentDocUrl == "")) { |
|
82 setTitle(window.localeDelegate.translateText("windows_new_window"), false); |
|
83 } |
|
84 else if (window.pageController.currentDocTitle == "") { |
|
85 setTitle(window.pageController.currentPartialUrl, false); |
|
86 } |
|
87 else { |
|
88 setTitle(window.pageController.currentDocTitle, false); |
|
89 } |
|
90 } |
|
91 else { |
|
92 if (window.views.current().type == "WindowView") |
|
93 setTitle(window.localeDelegate.translateText("windows_windows"), false); |
|
94 } |
|
95 } |
|
96 } |
|
97 |
|
98 } |
|
99 |
|
100 /*! |
|
101 Class to handle updating the lock status (show/remove lock icon). Only 1 |
|
102 LockStatus object should be created for the browser status bar. This class |
|
103 is not designed to be code space efficient for creating multiple objects. |
|
104 */ |
|
105 function LockStatus() |
|
106 { |
|
107 // Private Member Variables |
|
108 var secureIconSrc = "<img src=\"statusbar.snippet/icons/lock.png\">"; |
|
109 var noIconSrc = " "; |
|
110 |
|
111 // Public Methods |
|
112 |
|
113 //! Shows lock icon in status bar if in webView. |
|
114 this.showLockIcon = function() |
|
115 { |
|
116 if (window.views.current().type == "webView") { |
|
117 document.getElementById('lock').innerHTML = "<img src=\"statusbar.snippet/icons/lock.png\">"; |
|
118 //window.snippets.StatusBarChromeId.repaint(); |
|
119 } |
|
120 } |
|
121 |
|
122 //! Removes lock icon from status bar. |
|
123 this.removeLockIcon = function() |
|
124 { |
|
125 document.getElementById('lock').innerHTML = " "; |
|
126 } |
|
127 |
|
128 //! Handles lock status update in response to current view change signal. |
|
129 this.handleCurrentViewChange = function() |
|
130 { |
|
131 if(window.views.WebView.currentPageIsSuperPage()) { |
|
132 this.removeLockIcon(); |
|
133 } |
|
134 else{ |
|
135 if (window.views.current().type == "webView") { |
|
136 /* Secure icon */ |
|
137 if (window.pageController.secureState) |
|
138 this.showLockIcon(); |
|
139 else { |
|
140 this.removeLockIcon(); |
|
141 } |
|
142 } |
|
143 else { |
|
144 this.removeLockIcon(); |
|
145 } |
|
146 } |
|
147 } |
|
148 } |
|
149 |
|
150 /*! |
|
151 Class to handle updating the clock time. Only 1 Clock object should be |
|
152 created for the browser status bar. This class is not designed to be code |
|
153 space efficient for creating multiple objects. |
|
154 */ |
|
155 function Clock() |
|
156 { |
|
157 // Public Methods |
|
158 //! Updates the time displayed on the status bar. |
|
159 this.showtime = function() |
|
160 { |
|
161 var now = new Date(); |
|
162 var hours = now.getHours(); |
|
163 var minutes = now.getMinutes(); |
|
164 var timeValue = "" + ((hours > 12) ? hours - 12 : hours); |
|
165 timeValue += ((minutes < 10) ? ":0" : ":") + minutes; |
|
166 timeValue += (hours >=12) ? " pm": " am"; |
|
167 document.getElementById('clock').innerHTML = timeValue; |
|
168 } |
|
169 } |
|
170 |
|
171 /*! |
|
172 Class to handle updating the network status. Only 1 NetworkStatus object |
|
173 should be created for the browser status bar. This class is not designed |
|
174 to be code space efficient for creating multiple objects. |
|
175 */ |
|
176 function NetworkStatus() |
|
177 { |
|
178 // Private Member Variables |
|
179 var networkIconSrc = new Array( |
|
180 "<img src=\"statusbar.snippet/icons/signal/signal0.png\" alt=\"\">", |
|
181 "<img src=\"statusbar.snippet/icons/signal/signal0.png\" alt=\"\">", |
|
182 "<img src=\"statusbar.snippet/icons/signal/signal25.png\" alt=\"\">", |
|
183 "<img src=\"statusbar.snippet/icons/signal/signal50.png\" alt=\"\">", |
|
184 "<img src=\"statusbar.snippet/icons/signal/signal75.png\" alt=\"\">", |
|
185 "<img src=\"statusbar.snippet/icons/signal/signal100.png\" alt=\"\">"); |
|
186 var enumNetworkStrengths = new Object(); |
|
187 var currentState; // last known signal state - see enumNetworkStrengths |
|
188 |
|
189 enumNetworkStrengths.state = {Offline:0, NoSignal:1, Signal1:2, |
|
190 Signal2:3, Signal3:4, Signal4:5} |
|
191 |
|
192 currentState = enumNetworkStrengths.state.Offline; |
|
193 |
|
194 //! Encodes the specified string for display in HTML format. |
|
195 /*! |
|
196 \param str string to encode |
|
197 */ |
|
198 // Note: this function doesn't handle partial or double encoding. |
|
199 function htmlEncode(str) |
|
200 { |
|
201 var s; // function return |
|
202 |
|
203 // Encode special HTML characters (&, ", <, >, and '). |
|
204 s = str.replace(/&/g, '&'); |
|
205 s = s.replace(/\"/g, '"'); |
|
206 s = s.replace(/</g, '<'); |
|
207 s = s.replace(/>/g, '>'); |
|
208 s = s.replace(/'/g, '''); |
|
209 |
|
210 return (s); |
|
211 } |
|
212 |
|
213 //! Updates the field width for the network provider name. |
|
214 /*! |
|
215 \param s network provider name |
|
216 */ |
|
217 function updateFieldWidth(s) |
|
218 { |
|
219 if (document.getElementById) { |
|
220 var rulerSpan = document.getElementById('sbruler'); |
|
221 var fieldWidth; |
|
222 |
|
223 rulerSpan.innerHTML = s; |
|
224 fieldWidth = rulerSpan.offsetWidth + 10; // add 10 pixel padding |
|
225 document.getElementById('provider').width = fieldWidth + "px"; |
|
226 } |
|
227 } |
|
228 |
|
229 //! Converts the specified strength using a scale of -1 to 100 to the |
|
230 //! appropriate signal level state. |
|
231 /*! |
|
232 \param strength signal strength to convert |
|
233 */ |
|
234 function convertStrengthToState(strength) |
|
235 { |
|
236 var state; |
|
237 |
|
238 if (strength < 0) // unknown network mode or error |
|
239 state = enumNetworkStrengths.state.Offline; |
|
240 else if (strength == 0) // no signal |
|
241 state = enumNetworkStrengths.state.NoSignal; |
|
242 else if (strength < 40) // less than 40/100 |
|
243 state = enumNetworkStrengths.state.Signal1; |
|
244 else if (strength < 65) // less than 65/100 |
|
245 state = enumNetworkStrengths.state.Signal2; |
|
246 else if (strength < 90) // less than 90/100 |
|
247 state = enumNetworkStrengths.state.Signal3; |
|
248 else // 90/100 or higher - full signal |
|
249 state = enumNetworkStrengths.state.Signal4; |
|
250 |
|
251 return (state); |
|
252 } |
|
253 |
|
254 //! Changes the displayed network provider name. |
|
255 /*! |
|
256 \param networkName New network provider name to display |
|
257 */ |
|
258 function changeName(networkName) |
|
259 { |
|
260 // truncate name if it's too long |
|
261 if (networkName.length > NetworkStatus.MAX_NAME_LEN) |
|
262 networkName = networkName.substring(0, NetworkStatus.MAX_NAME_LEN); |
|
263 // set field width to the appropriate width and change the name |
|
264 updateFieldWidth(htmlEncode(networkName)); |
|
265 document.getElementById('provider').innerHTML = htmlEncode(networkName); |
|
266 |
|
267 // repaint if status bar exists (first call to this function, it doesn't) |
|
268 if (window.snippets.StatusBarChromeId) |
|
269 window.snippets.StatusBarChromeId.repaint(); |
|
270 } |
|
271 |
|
272 //! Gets the appropriate image tag HTML string for the current network |
|
273 //! signal strength. |
|
274 this.getInitialStrengthImgTag = function() |
|
275 { |
|
276 var strength = window.deviceDelegate.networkSignalStrength; |
|
277 |
|
278 currentState = convertStrengthToState(strength); |
|
279 return (networkIconSrc[currentState]); |
|
280 } |
|
281 |
|
282 //! Displays the initial network name. |
|
283 this.showInitialNetworkName = function() |
|
284 { |
|
285 // if we went offline, set the provider name to "offline" |
|
286 if (currentState == enumNetworkStrengths.state.Offline) |
|
287 changeName(window.localeDelegate.translateText("offline")); |
|
288 else |
|
289 changeName(window.deviceDelegate.networkName); |
|
290 } |
|
291 |
|
292 //! Handles the signal strength change signal. |
|
293 /*! |
|
294 \param strength new signal strength |
|
295 */ |
|
296 this.handleSignalStrengthChange = function(strength) |
|
297 { |
|
298 var state = convertStrengthToState(strength); |
|
299 |
|
300 // only interested in state changes |
|
301 if (currentState != state) { |
|
302 lastState = currentState; // save former state |
|
303 // update current state and network icon |
|
304 currentState = state; |
|
305 document.getElementById('strength').innerHTML = |
|
306 networkIconSrc[currentState]; |
|
307 window.snippets.StatusBarChromeId.repaint(); |
|
308 |
|
309 // if we went offline, change the provider name to "offline" |
|
310 if (currentState == enumNetworkStrengths.state.Offline) |
|
311 changeName(window.localeDelegate.translateText("offline")); |
|
312 // if we just came online, get and update provider name |
|
313 else if (lastState == enumNetworkStrengths.state.Offline) |
|
314 changeName(window.deviceDelegate.networkName); |
|
315 } |
|
316 } |
|
317 |
|
318 //! Handles the network name change signal. |
|
319 /*! |
|
320 \param networkName new network name |
|
321 */ |
|
322 this.handleNameChange = function(networkName) |
|
323 { |
|
324 // Offline network name is hard coded. |
|
325 if (currentState != enumNetworkStrengths.state.Offline) |
|
326 changeName(networkName); |
|
327 } |
|
328 } |
|
329 |
|
330 // class property (i.e. property of the class constructor function) |
|
331 NetworkStatus.MAX_NAME_LEN = 20; // max length of provider name |
|
332 |
|
333 /*! |
|
334 Class to handle updating the battery level. Only 1 BatteryStatus object |
|
335 should be created for the browser status bar. This class is not designed |
|
336 to be code space efficient for creating multiple objects. |
|
337 */ |
|
338 function BatteryStatus() |
|
339 { |
|
340 // Private Member Variables |
|
341 var batteryIconSrc = new Array( |
|
342 "<img src=\"statusbar.snippet/icons/battery/batt10.png\" alt=\"\">", |
|
343 "<img src=\"statusbar.snippet/icons/battery/batt20.png\" alt=\"\">", |
|
344 "<img src=\"statusbar.snippet/icons/battery/batt30.png\" alt=\"\">", |
|
345 "<img src=\"statusbar.snippet/icons/battery/batt40.png\" alt=\"\">", |
|
346 "<img src=\"statusbar.snippet/icons/battery/batt50.png\" alt=\"\">", |
|
347 "<img src=\"statusbar.snippet/icons/battery/batt60.png\" alt=\"\">", |
|
348 "<img src=\"statusbar.snippet/icons/battery/batt70.png\" alt=\"\">", |
|
349 "<img src=\"statusbar.snippet/icons/battery/batt80.png\" alt=\"\">", |
|
350 "<img src=\"statusbar.snippet/icons/battery/batt90.png\" alt=\"\">", |
|
351 "<img src=\"statusbar.snippet/icons/battery/batt100.png\" alt=\"\">", |
|
352 "<img src=\"statusbar.snippet/icons/battery/batt100_charging.png\" alt=\"\">"); |
|
353 var enumBatteryLevels = new Object(); |
|
354 |
|
355 enumBatteryLevels.state = {Level10:0, Level20:1, Level30:2, Level40:3, |
|
356 Level50:4, Level60:5, Level70:6, Level80:7, Level90:8, Level100:9, |
|
357 LevelCharging:10} |
|
358 |
|
359 //! Converts the specified battery level (1 to 100) to a battery state. |
|
360 /*! |
|
361 \param level battery level (1 to 100) |
|
362 */ |
|
363 function convertLevelToState(level) |
|
364 { |
|
365 var state; |
|
366 |
|
367 // Don't report battery level as being any higher than it actually is. |
|
368 // Unless it is under 10% in which case user story specifies one bar be displayed. |
|
369 if (window.deviceDelegate.batteryCharging) |
|
370 state = enumBatteryLevels.state.LevelCharging; |
|
371 else if (level < 20) // less than 20% full |
|
372 state = enumBatteryLevels.state.Level10; |
|
373 else if (level < 30) // less than 30% full |
|
374 state = enumBatteryLevels.state.Level20; |
|
375 else if (level < 40) // less than 40% full |
|
376 state = enumBatteryLevels.state.Level30; |
|
377 else if (level < 50) // less than 50% full |
|
378 state = enumBatteryLevels.state.Level40; |
|
379 else if (level < 60) // less than 60% full |
|
380 state = enumBatteryLevels.state.Level50; |
|
381 else if (level < 70) // less than 70% full |
|
382 state = enumBatteryLevels.state.Level60; |
|
383 else if (level < 80) // less than 80% full |
|
384 state = enumBatteryLevels.state.Level70; |
|
385 else if (level < 90) // less than 90% full |
|
386 state = enumBatteryLevels.state.Level80; |
|
387 else if (level < 100) // less than 100% full |
|
388 state = enumBatteryLevels.state.Level90; |
|
389 else // 100% full |
|
390 state = enumBatteryLevels.state.Level100; |
|
391 |
|
392 return (state); |
|
393 } |
|
394 |
|
395 //! Gets the initial battery level image tag HTML string. |
|
396 this.getInitialLevelImgTag = function() |
|
397 { |
|
398 return (batteryIconSrc[convertLevelToState( |
|
399 window.deviceDelegate.batteryLevel)]); |
|
400 } |
|
401 |
|
402 //! Handles battery level change signal. |
|
403 /*! |
|
404 \param level new battery level |
|
405 */ |
|
406 this.handleLevelChange = function(level) |
|
407 { |
|
408 document.getElementById('battery').innerHTML = |
|
409 batteryIconSrc[convertLevelToState(level)]; |
|
410 window.snippets.StatusBarChromeId.repaint(); |
|
411 } |
|
412 } |
|
413 |
|
414 /*! |
|
415 Class to handle updating the download indicator. |
|
416 */ |
|
417 function DownloadStatus() |
|
418 { |
|
419 function _enableDownloadIndicator() |
|
420 { |
|
421 var src = 'statusbar.snippet/icons/download_statusbar_icon.png'; |
|
422 var tag = '<img id="downloadImage" src="' + src + '" alt="">'; |
|
423 document.getElementById('download').innerHTML = tag; |
|
424 window.snippets.StatusBarChromeId.repaint(); |
|
425 } |
|
426 |
|
427 function _disableDownloadIndicator() |
|
428 { |
|
429 document.getElementById('download').innerHTML = ""; |
|
430 window.snippets.StatusBarChromeId.repaint(); |
|
431 } |
|
432 |
|
433 function _connectDownloadSignals() |
|
434 { |
|
435 window.downloads.downloadCreated.connect(_enableDownloadIndicator); |
|
436 window.downloads.downloadsCleared.connect(_disableDownloadIndicator); |
|
437 } |
|
438 |
|
439 if (window.downloads != null) { |
|
440 window.chrome.chromeComplete.connect(_connectDownloadSignals); |
|
441 } |
|
442 } |
|
443 |
|
444 // Private Member Variables |
|
445 var sbTitle = new Title(); //!< status bar title |
|
446 var sbLockStatus = new LockStatus(); //!< status bar lock status |
|
447 var sbClock = new Clock(); //!< status bar clock |
|
448 var sbNetworkStatus = new NetworkStatus(); //!< status bar network status |
|
449 var sbBatteryStatus = new BatteryStatus(); //!< status bar battery status |
|
450 var sbDownloadStatus = new DownloadStatus(); //!< status bar download status |
|
451 |
|
452 // Private Methods |
|
453 //! Write status bar HTML code to document. |
|
454 function _statusbar_write() |
|
455 { |
|
456 var downloadHTML = ''; |
|
457 if (window.downloads != null) { |
|
458 downloadHTML = '<td class="rightalign" id="download"></td>'; |
|
459 } |
|
460 |
|
461 var html = ''+ |
|
462 '<table>'+ |
|
463 '<tr>'+ |
|
464 '<td class="leftalign" id="strength">' + sbNetworkStatus.getInitialStrengthImgTag() + '</td>'+ |
|
465 '<td class="centeralign" id="provider"> </td>'+ |
|
466 '<td class="leftalign"><div id="title">Bedrock Browser</div></td>'+ |
|
467 '<td class="rightalign" id ="lock"> </td>'+ |
|
468 downloadHTML + |
|
469 '<td class="centeralign" id="clock">time: </td>' + |
|
470 '<td class="rightalign" id="battery">' + sbBatteryStatus.getInitialLevelImgTag() + '</td>'+ |
|
471 '</tr>'+ |
|
472 '</table>'+ |
|
473 // ruler span used for getting the width of network name |
|
474 // style included here because style sheet not applied early |
|
475 // enough for sbNetworkStatus.showInitialNetworkName call below |
|
476 // which needs text width which depends on font |
|
477 '<span id="sbruler" style="font-size:12px;font-weight:bold;visibility:hidden;"></span>'; |
|
478 document.write(html); |
|
479 |
|
480 sbNetworkStatus.showInitialNetworkName(); |
|
481 } |
|
482 |
|
483 // StatusBar Constructor |
|
484 _statusbar_write(); // write status bar HTML code to document |
|
485 sbClock.showtime(); // display current time on status bar |
|
486 // Update displayed time every 30 seconds. |
|
487 setInterval(function() {sbClock.showtime();}, 30000); |
|
488 |
|
489 // Note that in the slots below the "this" object is never used directly. |
|
490 // This is because they don't have access to "this" as they are invoked |
|
491 // as functions rather than as methods. |
|
492 |
|
493 // Connect page controller signals to slots. |
|
494 window.pageController.titleChanged.connect( |
|
495 function(title) {sbTitle.handleTitleChange(title);}); |
|
496 window.pageController.partialUrlChanged.connect( |
|
497 function(partialUrl) {sbTitle.handlePartialUrlChange(partialUrl);}); |
|
498 window.pageController.hideSecureIcon.connect( |
|
499 function() {sbLockStatus.removeLockIcon();}); |
|
500 window.pageController.showSecureIcon.connect( |
|
501 function() {sbLockStatus.showLockIcon();}); |
|
502 |
|
503 // Connect view manager signals to slots. |
|
504 window.views.currentViewChanged.connect( |
|
505 function() { |
|
506 sbTitle.handleCurrentViewChange(); |
|
507 sbLockStatus.handleCurrentViewChange(); |
|
508 } |
|
509 ); |
|
510 |
|
511 window.ViewStack.currentViewChanged.connect( |
|
512 function() { |
|
513 sbTitle.handleCurrentViewChange(); |
|
514 sbLockStatus.handleCurrentViewChange(); |
|
515 } |
|
516 ); |
|
517 |
|
518 // Connect device delegate signals to slots. |
|
519 window.deviceDelegate.batteryLevelChanged.connect( |
|
520 function(level) {sbBatteryStatus.handleLevelChange(level);}); |
|
521 window.deviceDelegate.networkSignalStrengthChanged.connect( |
|
522 function(strength) {sbNetworkStatus.handleSignalStrengthChange(strength);}); |
|
523 window.deviceDelegate.networkNameChanged.connect( |
|
524 function(networkName) {sbNetworkStatus.handleNameChange(networkName);}); |
|
525 } |