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