OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 <include src="../uber/uber_page_manager_observer.js"> | |
5 <include src="../uber/uber_utils.js"> | 6 <include src="../uber/uber_utils.js"> |
6 | 7 |
7 cr.define('help', function() { | 8 var ChannelChangePage = help.ChannelChangePage; |
8 /** | 9 var HelpPage = help.HelpPage; |
9 * Encapsulated handling of the help page. | 10 var PageManager = cr.ui.pageManager.PageManager; |
10 */ | |
11 function HelpPage() {} | |
12 | |
13 cr.addSingletonGetter(HelpPage); | |
14 | |
15 HelpPage.prototype = { | |
16 __proto__: help.HelpBasePage.prototype, | |
17 | |
18 /** | |
19 * True if after update powerwash button should be displayed. | |
20 * @private | |
21 */ | |
22 powerwashAfterUpdate_: false, | |
23 | |
24 /** | |
25 * List of the channels names. | |
26 * @private | |
27 */ | |
28 channelList_: ['dev-channel', 'beta-channel', 'stable-channel'], | |
29 | |
30 /** | |
31 * Bubble for error messages and notifications. | |
32 * @private | |
33 */ | |
34 bubble_: null, | |
35 | |
36 /** | |
37 * Name of the channel the device is currently on. | |
38 * @private | |
39 */ | |
40 currentChannel_: null, | |
41 | |
42 /** | |
43 * Name of the channel the device is supposed to be on. | |
44 * @private | |
45 */ | |
46 targetChannel_: null, | |
47 | |
48 /** | |
49 * Perform initial setup. | |
50 */ | |
51 initialize: function() { | |
52 help.HelpBasePage.prototype.initialize.call(this, 'help-page'); | |
53 | |
54 var self = this; | |
55 | |
56 uber.onContentFrameLoaded(); | |
57 | |
58 // Set the title. | |
59 uber.setTitle(loadTimeData.getString('aboutTitle')); | |
60 | |
61 $('product-license').innerHTML = loadTimeData.getString('productLicense'); | |
62 if (cr.isChromeOS) { | |
63 $('product-os-license').innerHTML = | |
64 loadTimeData.getString('productOsLicense'); | |
65 } | |
66 | |
67 var productTOS = $('product-tos'); | |
68 if (productTOS) | |
69 productTOS.innerHTML = loadTimeData.getString('productTOS'); | |
70 | |
71 $('get-help').onclick = function() { | |
72 chrome.send('openHelpPage'); | |
73 }; | |
74 <if expr="_google_chrome"> | |
75 $('report-issue').onclick = function() { | |
76 chrome.send('openFeedbackDialog'); | |
77 }; | |
78 </if> | |
79 | |
80 this.maybeSetOnClick_($('more-info-expander'), | |
81 this.toggleMoreInfo_.bind(this)); | |
82 | |
83 this.maybeSetOnClick_($('promote'), function() { | |
84 chrome.send('promoteUpdater'); | |
85 }); | |
86 this.maybeSetOnClick_($('relaunch'), function() { | |
87 chrome.send('relaunchNow'); | |
88 }); | |
89 if (cr.isChromeOS) { | |
90 this.maybeSetOnClick_($('relaunch-and-powerwash'), function() { | |
91 chrome.send('relaunchAndPowerwash'); | |
92 }); | |
93 | |
94 this.channelTable_ = { | |
95 'stable-channel': { | |
96 'name': loadTimeData.getString('stable'), | |
97 'label': loadTimeData.getString('currentChannelStable'), | |
98 }, | |
99 'beta-channel': { | |
100 'name': loadTimeData.getString('beta'), | |
101 'label': loadTimeData.getString('currentChannelBeta') | |
102 }, | |
103 'dev-channel': { | |
104 'name': loadTimeData.getString('dev'), | |
105 'label': loadTimeData.getString('currentChannelDev') | |
106 } | |
107 }; | |
108 } | |
109 | |
110 var channelChanger = $('channel-changer'); | |
111 if (channelChanger) { | |
112 channelChanger.onchange = function(event) { | |
113 self.setChannel_(event.target.value, false); | |
114 }; | |
115 } | |
116 | |
117 if (cr.isChromeOS) { | |
118 help.ChannelChangePage.getInstance().initialize(); | |
119 this.registerOverlay(help.ChannelChangePage.getInstance()); | |
120 | |
121 cr.ui.overlay.setupOverlay($('overlay-container')); | |
122 cr.ui.overlay.globalInitialization(); | |
123 $('overlay-container').addEventListener('cancelOverlay', function() { | |
124 self.closeOverlay(); | |
125 }); | |
126 $('change-channel').onclick = function() { | |
127 self.showOverlay('channel-change-page'); | |
128 }; | |
129 | |
130 var channelChangeDisallowedError = document.createElement('div'); | |
131 channelChangeDisallowedError.className = 'channel-change-error-bubble'; | |
132 | |
133 var channelChangeDisallowedIcon = document.createElement('div'); | |
134 channelChangeDisallowedIcon.classList.add('help-page-icon-large'); | |
135 channelChangeDisallowedIcon.classList.add('channel-change-error-icon'); | |
136 channelChangeDisallowedError.appendChild(channelChangeDisallowedIcon); | |
137 | |
138 var channelChangeDisallowedText = document.createElement('div'); | |
139 channelChangeDisallowedText.className = 'channel-change-error-text'; | |
140 channelChangeDisallowedText.textContent = | |
141 loadTimeData.getString('channelChangeDisallowedMessage'); | |
142 channelChangeDisallowedError.appendChild(channelChangeDisallowedText); | |
143 | |
144 $('channel-change-disallowed-icon').onclick = function() { | |
145 self.showBubble_(channelChangeDisallowedError, | |
146 $('help-container'), | |
147 $('channel-change-disallowed-icon'), | |
148 cr.ui.ArrowLocation.TOP_END); | |
149 }; | |
150 } | |
151 | |
152 cr.ui.FocusManager.disableMouseFocusOnButtons(); | |
153 help.HelpFocusManager.getInstance().initialize(); | |
154 | |
155 // Attempt to update. | |
156 chrome.send('onPageLoaded'); | |
157 }, | |
158 | |
159 /** | |
160 * Shows the bubble. | |
161 * @param {HTMLDivElement} content The content of the bubble. | |
162 * @param {HTMLElement} target The element at which the bubble points. | |
163 * @param {HTMLElement} domSibling The element after which the bubble is | |
164 * added to the DOM. | |
165 * @param {cr.ui.ArrowLocation} location The arrow location. | |
166 * @private | |
167 */ | |
168 showBubble_: function(content, domSibling, target, location) { | |
169 if (!cr.isChromeOS) | |
170 return; | |
171 this.hideBubble_(); | |
172 var bubble = new cr.ui.AutoCloseBubble; | |
173 bubble.anchorNode = target; | |
174 bubble.domSibling = domSibling; | |
175 bubble.arrowLocation = location; | |
176 bubble.content = content; | |
177 bubble.show(); | |
178 this.bubble_ = bubble; | |
179 }, | |
180 | |
181 /** | |
182 * Hides the bubble. | |
183 * @private | |
184 */ | |
185 hideBubble_: function() { | |
186 if (!cr.isChromeOS) | |
187 return; | |
188 if (this.bubble_) | |
189 this.bubble_.hide(); | |
190 }, | |
191 | |
192 /** | |
193 * Toggles the visible state of the 'More Info' section. | |
194 * @private | |
195 */ | |
196 toggleMoreInfo_: function() { | |
197 var moreInfo = $('more-info-container'); | |
198 var visible = moreInfo.className == 'visible'; | |
199 moreInfo.className = visible ? '' : 'visible'; | |
200 moreInfo.style.height = visible ? '' : moreInfo.scrollHeight + 'px'; | |
201 moreInfo.addEventListener('webkitTransitionEnd', function(event) { | |
202 $('more-info-expander').textContent = visible ? | |
203 loadTimeData.getString('showMoreInfo') : | |
204 loadTimeData.getString('hideMoreInfo'); | |
205 }); | |
206 }, | |
207 | |
208 /** | |
209 * Assigns |method| to the onclick property of |el| if |el| exists. | |
210 * @private | |
211 */ | |
212 maybeSetOnClick_: function(el, method) { | |
213 if (el) | |
214 el.onclick = method; | |
215 }, | |
216 | |
217 /** | |
218 * @private | |
219 */ | |
220 setUpdateImage_: function(state) { | |
221 $('update-status-icon').className = 'help-page-icon ' + state; | |
222 }, | |
223 | |
224 /** | |
225 * @return {boolean} True, if new channel switcher UI is used, | |
226 * false otherwise. | |
227 * @private | |
228 */ | |
229 isNewChannelSwitcherUI_: function() { | |
230 return !loadTimeData.valueExists('disableNewChannelSwitcherUI'); | |
231 }, | |
232 | |
233 /** | |
234 * @return {boolean} True if target and current channels are not | |
235 * null and not equals | |
236 * @private | |
237 */ | |
238 channelsDiffer_: function() { | |
239 var current = this.currentChannel_; | |
240 var target = this.targetChannel_; | |
241 return (current != null && target != null && current != target); | |
242 }, | |
243 | |
244 /** | |
245 * @private | |
246 */ | |
247 setUpdateStatus_: function(status, message) { | |
248 if (cr.isMac && | |
249 $('update-status-message') && | |
250 $('update-status-message').hidden) { | |
251 // Chrome has reached the end of the line on this system. The | |
252 // update-obsolete-system message is displayed. No other auto-update | |
253 // status should be displayed. | |
254 return; | |
255 } | |
256 | |
257 var channel = this.targetChannel_; | |
258 if (status == 'checking') { | |
259 this.setUpdateImage_('working'); | |
260 $('update-status-message').innerHTML = | |
261 loadTimeData.getString('updateCheckStarted'); | |
262 } else if (status == 'updating') { | |
263 this.setUpdateImage_('working'); | |
264 if (this.channelsDiffer_()) { | |
265 $('update-status-message').innerHTML = | |
266 loadTimeData.getStringF('updatingChannelSwitch', | |
267 this.channelTable_[channel].label); | |
268 } else { | |
269 $('update-status-message').innerHTML = | |
270 loadTimeData.getStringF('updating'); | |
271 } | |
272 } else if (status == 'nearly_updated') { | |
273 this.setUpdateImage_('up-to-date'); | |
274 if (this.channelsDiffer_()) { | |
275 $('update-status-message').innerHTML = | |
276 loadTimeData.getString('successfulChannelSwitch'); | |
277 } else { | |
278 $('update-status-message').innerHTML = | |
279 loadTimeData.getString('updateAlmostDone'); | |
280 } | |
281 } else if (status == 'updated') { | |
282 this.setUpdateImage_('up-to-date'); | |
283 $('update-status-message').innerHTML = | |
284 loadTimeData.getString('upToDate'); | |
285 } else if (status == 'failed') { | |
286 this.setUpdateImage_('failed'); | |
287 $('update-status-message').innerHTML = message; | |
288 } | |
289 | |
290 // Following invariant must be established at the end of this function: | |
291 // { ~$('relaunch_and_powerwash').hidden -> $('relaunch').hidden } | |
292 var relaunchAndPowerwashHidden = true; | |
293 if ($('relaunch-and-powerwash')) { | |
294 // It's allowed to do powerwash only for customer devices, | |
295 // when user explicitly decides to update to a more stable | |
296 // channel. | |
297 relaunchAndPowerwashHidden = | |
298 !this.powerwashAfterUpdate_ || status != 'nearly_updated'; | |
299 $('relaunch-and-powerwash').hidden = relaunchAndPowerwashHidden; | |
300 } | |
301 | |
302 var container = $('update-status-container'); | |
303 if (container) { | |
304 container.hidden = status == 'disabled'; | |
305 $('relaunch').hidden = | |
306 (status != 'nearly_updated') || !relaunchAndPowerwashHidden; | |
307 | |
308 if (!cr.isMac) | |
309 $('update-percentage').hidden = status != 'updating'; | |
310 } | |
311 }, | |
312 | |
313 /** | |
314 * @private | |
315 */ | |
316 setProgress_: function(progress) { | |
317 $('update-percentage').innerHTML = progress + '%'; | |
318 }, | |
319 | |
320 /** | |
321 * @private | |
322 */ | |
323 setAllowedConnectionTypesMsg_: function(message) { | |
324 $('allowed-connection-types-message').innerText = message; | |
325 }, | |
326 | |
327 /** | |
328 * @private | |
329 */ | |
330 showAllowedConnectionTypesMsg_: function(visible) { | |
331 $('allowed-connection-types-message').hidden = !visible; | |
332 }, | |
333 | |
334 /** | |
335 * @private | |
336 */ | |
337 setPromotionState_: function(state) { | |
338 if (state == 'hidden') { | |
339 $('promote').hidden = true; | |
340 } else if (state == 'enabled') { | |
341 $('promote').disabled = false; | |
342 $('promote').hidden = false; | |
343 } else if (state == 'disabled') { | |
344 $('promote').disabled = true; | |
345 $('promote').hidden = false; | |
346 } | |
347 }, | |
348 | |
349 /** | |
350 * @private | |
351 */ | |
352 setObsoleteSystem_: function(obsolete) { | |
353 if (cr.isMac && $('update-obsolete-system-container')) { | |
354 $('update-obsolete-system-container').hidden = !obsolete; | |
355 } | |
356 }, | |
357 | |
358 /** | |
359 * @private | |
360 */ | |
361 setObsoleteSystemEndOfTheLine_: function(endOfTheLine) { | |
362 if (cr.isMac && | |
363 $('update-obsolete-system-container') && | |
364 !$('update-obsolete-system-container').hidden && | |
365 $('update-status-message')) { | |
366 $('update-status-message').hidden = endOfTheLine; | |
367 if (endOfTheLine) { | |
368 this.setUpdateImage_('failed'); | |
369 } | |
370 } | |
371 }, | |
372 | |
373 /** | |
374 * @private | |
375 */ | |
376 setOSVersion_: function(version) { | |
377 if (!cr.isChromeOS) | |
378 console.error('OS version unsupported on non-CrOS'); | |
379 | |
380 $('os-version').parentNode.hidden = (version == ''); | |
381 $('os-version').textContent = version; | |
382 }, | |
383 | |
384 /** | |
385 * @private | |
386 */ | |
387 setOSFirmware_: function(firmware) { | |
388 if (!cr.isChromeOS) | |
389 console.error('OS firmware unsupported on non-CrOS'); | |
390 | |
391 $('firmware').parentNode.hidden = (firmware == ''); | |
392 $('firmware').textContent = firmware; | |
393 }, | |
394 | |
395 /** | |
396 * Updates name of the current channel, i.e. the name of the | |
397 * channel the device is currently on. | |
398 * @param {string} channel The name of the current channel | |
399 * @private | |
400 */ | |
401 updateCurrentChannel_: function(channel) { | |
402 if (this.channelList_.indexOf(channel) < 0) | |
403 return; | |
404 $('current-channel').textContent = loadTimeData.getStringF( | |
405 'currentChannel', this.channelTable_[channel].label); | |
406 this.currentChannel_ = channel; | |
407 help.ChannelChangePage.updateCurrentChannel(channel); | |
408 }, | |
409 | |
410 /** | |
411 * |enabled| is true if the release channel can be enabled. | |
412 * @private | |
413 */ | |
414 updateEnableReleaseChannel_: function(enabled) { | |
415 this.updateChannelChangerContainerVisibility_(enabled); | |
416 $('change-channel').disabled = !enabled; | |
417 $('channel-change-disallowed-icon').hidden = enabled; | |
418 }, | |
419 | |
420 /** | |
421 * Sets the device target channel. | |
422 * @param {string} channel The name of the target channel | |
423 * @param {boolean} isPowerwashAllowed True iff powerwash is allowed | |
424 * @private | |
425 */ | |
426 setChannel_: function(channel, isPowerwashAllowed) { | |
427 this.powerwashAfterUpdate_ = isPowerwashAllowed; | |
428 this.targetChannel_ = channel; | |
429 chrome.send('setChannel', [channel, isPowerwashAllowed]); | |
430 $('channel-change-confirmation').hidden = false; | |
431 $('channel-change-confirmation').textContent = loadTimeData.getStringF( | |
432 'channel-changed', this.channelTable_[channel].name); | |
433 }, | |
434 | |
435 /** | |
436 * Sets the value of the "Build Date" field of the "More Info" section. | |
437 * @param {string} buildDate The date of the build. | |
438 * @private | |
439 */ | |
440 setBuildDate_: function(buildDate) { | |
441 $('build-date-container').classList.remove('empty'); | |
442 $('build-date').textContent = buildDate; | |
443 }, | |
444 | |
445 /** | |
446 * Updates channel-change-page-container visibility according to | |
447 * internal state. | |
448 * @private | |
449 */ | |
450 updateChannelChangePageContainerVisibility_: function() { | |
451 if (!this.isNewChannelSwitcherUI_()) { | |
452 $('channel-change-page-container').hidden = true; | |
453 return; | |
454 } | |
455 $('channel-change-page-container').hidden = | |
456 !help.ChannelChangePage.isPageReady(); | |
457 }, | |
458 | |
459 /** | |
460 * Updates channel-changer dropdown visibility if |visible| is | |
461 * true and new channel switcher UI is disallowed. | |
462 * @param {boolean} visible True if channel-changer should be | |
463 * displayed, false otherwise. | |
464 * @private | |
465 */ | |
466 updateChannelChangerContainerVisibility_: function(visible) { | |
467 if (this.isNewChannelSwitcherUI_()) { | |
468 $('channel-changer').hidden = true; | |
469 return; | |
470 } | |
471 $('channel-changer').hidden = !visible; | |
472 }, | |
473 }; | |
474 | |
475 HelpPage.setUpdateStatus = function(status, message) { | |
476 HelpPage.getInstance().setUpdateStatus_(status, message); | |
477 }; | |
478 | |
479 HelpPage.setProgress = function(progress) { | |
480 HelpPage.getInstance().setProgress_(progress); | |
481 }; | |
482 | |
483 HelpPage.setAndShowAllowedConnectionTypesMsg = function(message) { | |
484 HelpPage.getInstance().setAllowedConnectionTypesMsg_(message); | |
485 HelpPage.getInstance().showAllowedConnectionTypesMsg_(true); | |
486 }; | |
487 | |
488 HelpPage.showAllowedConnectionTypesMsg = function(visible) { | |
489 HelpPage.getInstance().showAllowedConnectionTypesMsg_(visible); | |
490 }; | |
491 | |
492 HelpPage.setPromotionState = function(state) { | |
493 HelpPage.getInstance().setPromotionState_(state); | |
494 }; | |
495 | |
496 HelpPage.setObsoleteSystem = function(obsolete) { | |
497 HelpPage.getInstance().setObsoleteSystem_(obsolete); | |
498 }; | |
499 | |
500 HelpPage.setObsoleteSystemEndOfTheLine = function(endOfTheLine) { | |
501 HelpPage.getInstance().setObsoleteSystemEndOfTheLine_(endOfTheLine); | |
502 }; | |
503 | |
504 HelpPage.setOSVersion = function(version) { | |
505 HelpPage.getInstance().setOSVersion_(version); | |
506 }; | |
507 | |
508 HelpPage.setOSFirmware = function(firmware) { | |
509 HelpPage.getInstance().setOSFirmware_(firmware); | |
510 }; | |
511 | |
512 HelpPage.showOverlay = function(name) { | |
513 HelpPage.getInstance().showOverlay(name); | |
514 }; | |
515 | |
516 HelpPage.cancelOverlay = function() { | |
517 HelpPage.getInstance().closeOverlay(); | |
518 }; | |
519 | |
520 HelpPage.getTopmostVisiblePage = function() { | |
521 return HelpPage.getInstance().getTopmostVisiblePage(); | |
522 }; | |
523 | |
524 HelpPage.updateIsEnterpriseManaged = function(isEnterpriseManaged) { | |
525 if (!cr.isChromeOS) | |
526 return; | |
527 help.ChannelChangePage.updateIsEnterpriseManaged(isEnterpriseManaged); | |
528 }; | |
529 | |
530 HelpPage.updateCurrentChannel = function(channel) { | |
531 if (!cr.isChromeOS) | |
532 return; | |
533 HelpPage.getInstance().updateCurrentChannel_(channel); | |
534 }; | |
535 | |
536 HelpPage.updateTargetChannel = function(channel) { | |
537 if (!cr.isChromeOS) | |
538 return; | |
539 help.ChannelChangePage.updateTargetChannel(channel); | |
540 }; | |
541 | |
542 HelpPage.updateEnableReleaseChannel = function(enabled) { | |
543 HelpPage.getInstance().updateEnableReleaseChannel_(enabled); | |
544 }; | |
545 | |
546 HelpPage.setChannel = function(channel, isPowerwashAllowed) { | |
547 HelpPage.getInstance().setChannel_(channel, isPowerwashAllowed); | |
548 }; | |
549 | |
550 HelpPage.setBuildDate = function(buildDate) { | |
551 HelpPage.getInstance().setBuildDate_(buildDate); | |
552 }; | |
553 | |
554 HelpPage.updateChannelChangePageContainerVisibility = function() { | |
555 HelpPage.getInstance().updateChannelChangePageContainerVisibility_(); | |
556 }; | |
557 | |
558 // Export | |
559 return { | |
560 HelpPage: HelpPage | |
561 }; | |
562 }); | |
563 | 11 |
564 /** | 12 /** |
565 * onload listener to initialize the HelpPage. | 13 * DOMContentLoaded handler, sets up the page. |
566 */ | 14 */ |
567 window.onload = function() { | 15 function load() { |
568 help.HelpPage.getInstance().initialize(); | 16 PageManager.register(HelpPage.getInstance()); |
17 | |
18 if (cr.isChromeOS) { | |
19 PageManager.registerOverlay(ChannelChangePage.getInstance(), | |
20 HelpPage.getInstance()); | |
21 } | |
22 cr.ui.FocusManager.disableMouseFocusOnButtons(); | |
23 PageManager.addObserver(new uber.PageManagerObserver()); | |
24 PageManager.initialize(HelpPage.getInstance()); | |
25 uber.onContentFrameLoaded(); | |
26 | |
27 var pageName = PageManager.getPageNameFromPath(); | |
28 // Still update history so that chrome://help/nonexistant redirects | |
29 // appropriately to chrome://help/. If the URL matches, updateHistory | |
30 // will avoid adding the extra state. | |
31 PageManager.showPageByName(pageName, true, {replaceState: true}); | |
stevenjb
2014/08/05 21:40:22
nit: Document 'true' with a comment or well named
michaelpg
2014/08/06 21:58:18
Done.
| |
32 } | |
33 | |
34 document.addEventListener('DOMContentLoaded', load); | |
35 | |
36 /** | |
37 * Listener for the |beforeunload| event. | |
38 */ | |
39 window.onbeforeunload = function() { | |
40 PageManager.willClose(); | |
569 }; | 41 }; |
42 | |
43 /** | |
44 * Listener for the |popstate| event. | |
45 * @param {Event} e The |popstate| event. | |
46 */ | |
47 window.onpopstate = function(e) { | |
48 var pageName = PageManager.getPageNameFromPath(); | |
49 PageManager.setState(pageName, e.state); | |
50 }; | |
OLD | NEW |