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 <include src
="../uber/uber_utils.js">
7 cr
.define('help', function() {
9 * Encapsulated handling of the help page.
11 function HelpPage() {}
13 cr
.addSingletonGetter(HelpPage
);
15 HelpPage
.prototype = {
16 __proto__
: help
.HelpBasePage
.prototype,
19 * True if after update powerwash button should be displayed.
22 powerwashAfterUpdate_
: false,
25 * List of the channels names.
28 channelList_
: ['dev-channel', 'beta-channel', 'stable-channel'],
31 * Bubble for error messages and notifications.
37 * Name of the channel the device is currently on.
40 currentChannel_
: null,
43 * Name of the channel the device is supposed to be on.
49 * Perform initial setup.
51 initialize: function() {
52 help
.HelpBasePage
.prototype.initialize
.call(this, 'help-page');
56 uber
.onContentFrameLoaded();
59 var title
= loadTimeData
.getString('helpTitle');
60 uber
.invokeMethodOnParent('setTitle', {title
: title
});
62 $('product-license').innerHTML
= loadTimeData
.getString('productLicense');
64 $('product-os-license').innerHTML
=
65 loadTimeData
.getString('productOsLicense');
68 var productTOS
= $('product-tos');
70 productTOS
.innerHTML
= loadTimeData
.getString('productTOS');
72 $('get-help').onclick = function() {
73 chrome
.send('openHelpPage');
75 <if expr
="pp_ifdef('_google_chrome')">
76 $('report-issue').onclick = function() {
77 chrome
.send('openFeedbackDialog');
81 this.maybeSetOnClick_($('more-info-expander'),
82 this.toggleMoreInfo_
.bind(this));
84 this.maybeSetOnClick_($('promote'), function() {
85 chrome
.send('promoteUpdater');
87 this.maybeSetOnClick_($('relaunch'), function() {
88 chrome
.send('relaunchNow');
91 this.maybeSetOnClick_($('relaunch-and-powerwash'), function() {
92 chrome
.send('relaunchAndPowerwash');
95 this.channelTable_
= {
97 'name': loadTimeData
.getString('stable'),
98 'label': loadTimeData
.getString('currentChannelStable'),
101 'name': loadTimeData
.getString('beta'),
102 'label': loadTimeData
.getString('currentChannelBeta')
105 'name': loadTimeData
.getString('dev'),
106 'label': loadTimeData
.getString('currentChannelDev')
111 var channelChanger
= $('channel-changer');
112 if (channelChanger
) {
113 channelChanger
.onchange = function(event
) {
114 self
.setChannel_(event
.target
.value
, false);
119 help
.ChannelChangePage
.getInstance().initialize();
120 this.registerOverlay(help
.ChannelChangePage
.getInstance());
122 cr
.ui
.overlay
.setupOverlay($('overlay-container'));
123 cr
.ui
.overlay
.globalInitialization();
124 $('overlay-container').addEventListener('cancelOverlay', function() {
127 $('change-channel').onclick = function() {
128 self
.showOverlay('channel-change-page');
131 var channelChangeDisallowedError
= document
.createElement('div');
132 channelChangeDisallowedError
.className
= 'channel-change-error-bubble';
134 var channelChangeDisallowedIcon
= document
.createElement('div');
135 channelChangeDisallowedIcon
.classList
.add('help-page-icon-large');
136 channelChangeDisallowedIcon
.classList
.add('channel-change-error-icon');
137 channelChangeDisallowedError
.appendChild(channelChangeDisallowedIcon
);
139 var channelChangeDisallowedText
= document
.createElement('div');
140 channelChangeDisallowedText
.className
= 'channel-change-error-text';
141 channelChangeDisallowedText
.textContent
=
142 loadTimeData
.getString('channelChangeDisallowedMessage');
143 channelChangeDisallowedError
.appendChild(channelChangeDisallowedText
);
145 $('channel-change-disallowed-icon').onclick = function() {
146 self
.showBubble_(channelChangeDisallowedError
,
148 $('channel-change-disallowed-icon'),
149 cr
.ui
.ArrowLocation
.TOP_END
);
153 cr
.ui
.FocusManager
.disableMouseFocusOnButtons();
154 help
.HelpFocusManager
.getInstance().initialize();
156 // Attempt to update.
157 chrome
.send('onPageLoaded');
162 * @param {HTMLDivElement} content The content of the bubble.
163 * @param {HTMLElement} target The element at which the bubble points.
164 * @param {HTMLElement} domSibling The element after which the bubble is
166 * @param {cr.ui.ArrowLocation} location The arrow location.
169 showBubble_: function(content
, domSibling
, target
, location
) {
173 var bubble
= new cr
.ui
.AutoCloseBubble
;
174 bubble
.anchorNode
= target
;
175 bubble
.domSibling
= domSibling
;
176 bubble
.arrowLocation
= location
;
177 bubble
.content
= content
;
179 this.bubble_
= bubble
;
186 hideBubble_: function() {
194 * Toggles the visible state of the 'More Info' section.
197 toggleMoreInfo_: function() {
198 var moreInfo
= $('more-info-container');
199 var visible
= moreInfo
.className
== 'visible';
200 moreInfo
.className
= visible
? '' : 'visible';
201 moreInfo
.style
.height
= visible
? '' : moreInfo
.scrollHeight
+ 'px';
202 moreInfo
.addEventListener('webkitTransitionEnd', function(event
) {
203 $('more-info-expander').textContent
= visible
?
204 loadTimeData
.getString('showMoreInfo') :
205 loadTimeData
.getString('hideMoreInfo');
210 * Assigns |method| to the onclick property of |el| if |el| exists.
213 maybeSetOnClick_: function(el
, method
) {
221 setUpdateImage_: function(state
) {
222 $('update-status-icon').className
= 'help-page-icon ' + state
;
226 * @return {boolean} True, if new channel switcher UI is used,
230 isNewChannelSwitcherUI_: function() {
231 return !loadTimeData
.valueExists('disableNewChannelSwitcherUI');
235 * @return {boolean} True if target and current channels are not
236 * null and not equals
239 channelsDiffer_: function() {
240 var current
= this.currentChannel_
;
241 var target
= this.targetChannel_
;
242 return (current
!= null && target
!= null && current
!= target
);
248 setUpdateStatus_: function(status
, message
) {
250 $('update-status-message') &&
251 $('update-status-message').hidden
) {
252 // Chrome has reached the end of the line on this system. The
253 // update-obsolete-system message is displayed. No other auto-update
254 // status should be displayed.
258 var channel
= this.targetChannel_
;
259 if (status
== 'checking') {
260 this.setUpdateImage_('working');
261 $('update-status-message').innerHTML
=
262 loadTimeData
.getString('updateCheckStarted');
263 } else if (status
== 'updating') {
264 this.setUpdateImage_('working');
265 if (this.channelsDiffer_()) {
266 $('update-status-message').innerHTML
=
267 loadTimeData
.getStringF('updatingChannelSwitch',
268 this.channelTable_
[channel
].label
);
270 $('update-status-message').innerHTML
=
271 loadTimeData
.getStringF('updating');
273 } else if (status
== 'nearly_updated') {
274 this.setUpdateImage_('up-to-date');
275 if (this.channelsDiffer_()) {
276 $('update-status-message').innerHTML
=
277 loadTimeData
.getString('successfulChannelSwitch');
279 $('update-status-message').innerHTML
=
280 loadTimeData
.getString('updateAlmostDone');
282 } else if (status
== 'updated') {
283 this.setUpdateImage_('up-to-date');
284 $('update-status-message').innerHTML
=
285 loadTimeData
.getString('upToDate');
286 } else if (status
== 'failed') {
287 this.setUpdateImage_('failed');
288 $('update-status-message').innerHTML
= message
;
291 // Following invariant must be established at the end of this function:
292 // { ~$('relaunch_and_powerwash').hidden -> $('relaunch').hidden }
293 var relaunchAndPowerwashHidden
= true;
294 if ($('relaunch-and-powerwash')) {
295 // It's allowed to do powerwash only for customer devices,
296 // when user explicitly decides to update to a more stable
298 relaunchAndPowerwashHidden
=
299 !this.powerwashAfterUpdate_
|| status
!= 'nearly_updated';
300 $('relaunch-and-powerwash').hidden
= relaunchAndPowerwashHidden
;
303 var container
= $('update-status-container');
305 container
.hidden
= status
== 'disabled';
306 $('relaunch').hidden
=
307 (status
!= 'nearly_updated') || !relaunchAndPowerwashHidden
;
310 $('update-percentage').hidden
= status
!= 'updating';
317 setProgress_: function(progress
) {
318 $('update-percentage').innerHTML
= progress
+ '%';
324 setAllowedConnectionTypesMsg_: function(message
) {
325 $('allowed-connection-types-message').innerText
= message
;
331 showAllowedConnectionTypesMsg_: function(visible
) {
332 $('allowed-connection-types-message').hidden
= !visible
;
338 setPromotionState_: function(state
) {
339 if (state
== 'hidden') {
340 $('promote').hidden
= true;
341 } else if (state
== 'enabled') {
342 $('promote').disabled
= false;
343 $('promote').hidden
= false;
344 } else if (state
== 'disabled') {
345 $('promote').disabled
= true;
346 $('promote').hidden
= false;
353 setObsoleteSystem_: function(obsolete
) {
354 if (cr
.isMac
&& $('update-obsolete-system-container')) {
355 $('update-obsolete-system-container').hidden
= !obsolete
;
362 setObsoleteSystemEndOfTheLine_: function(endOfTheLine
) {
364 $('update-obsolete-system-container') &&
365 !$('update-obsolete-system-container').hidden
&&
366 $('update-status-message')) {
367 $('update-status-message').hidden
= endOfTheLine
;
369 this.setUpdateImage_('failed');
377 setOSVersion_: function(version
) {
379 console
.error('OS version unsupported on non-CrOS');
381 $('os-version').parentNode
.hidden
= (version
== '');
382 $('os-version').textContent
= version
;
388 setOSFirmware_: function(firmware
) {
390 console
.error('OS firmware unsupported on non-CrOS');
392 $('firmware').parentNode
.hidden
= (firmware
== '');
393 $('firmware').textContent
= firmware
;
397 * Updates name of the current channel, i.e. the name of the
398 * channel the device is currently on.
399 * @param {string} channel The name of the current channel
402 updateCurrentChannel_: function(channel
) {
403 if (this.channelList_
.indexOf(channel
) < 0)
405 $('current-channel').textContent
= loadTimeData
.getStringF(
406 'currentChannel', this.channelTable_
[channel
].label
);
407 this.currentChannel_
= channel
;
408 help
.ChannelChangePage
.updateCurrentChannel(channel
);
412 * |enabled| is true if the release channel can be enabled.
415 updateEnableReleaseChannel_: function(enabled
) {
416 this.updateChannelChangerContainerVisibility_(enabled
);
417 $('change-channel').disabled
= !enabled
;
418 $('channel-change-disallowed-icon').hidden
= enabled
;
422 * Sets the device target channel.
423 * @param {string} channel The name of the target channel
424 * @param {boolean} isPowerwashAllowed True iff powerwash is allowed
427 setChannel_: function(channel
, isPowerwashAllowed
) {
428 this.powerwashAfterUpdate_
= isPowerwashAllowed
;
429 this.targetChannel_
= channel
;
430 chrome
.send('setChannel', [channel
, isPowerwashAllowed
]);
431 $('channel-change-confirmation').hidden
= false;
432 $('channel-change-confirmation').textContent
= loadTimeData
.getStringF(
433 'channel-changed', this.channelTable_
[channel
].name
);
437 * Sets the value of the "Build Date" field of the "More Info" section.
438 * @param {string} buildDate The date of the build.
441 setBuildDate_: function(buildDate
) {
442 $('build-date-container').classList
.remove('empty');
443 $('build-date').textContent
= buildDate
;
447 * Updates channel-change-page-container visibility according to
451 updateChannelChangePageContainerVisibility_: function() {
452 if (!this.isNewChannelSwitcherUI_()) {
453 $('channel-change-page-container').hidden
= true;
456 $('channel-change-page-container').hidden
=
457 !help
.ChannelChangePage
.isPageReady();
461 * Updates channel-changer dropdown visibility if |visible| is
462 * true and new channel switcher UI is disallowed.
463 * @param {boolean} visible True if channel-changer should be
464 * displayed, false otherwise.
467 updateChannelChangerContainerVisibility_: function(visible
) {
468 if (this.isNewChannelSwitcherUI_()) {
469 $('channel-changer').hidden
= true;
472 $('channel-changer').hidden
= !visible
;
476 HelpPage
.setUpdateStatus = function(status
, message
) {
477 HelpPage
.getInstance().setUpdateStatus_(status
, message
);
480 HelpPage
.setProgress = function(progress
) {
481 HelpPage
.getInstance().setProgress_(progress
);
484 HelpPage
.setAndShowAllowedConnectionTypesMsg = function(message
) {
485 HelpPage
.getInstance().setAllowedConnectionTypesMsg_(message
);
486 HelpPage
.getInstance().showAllowedConnectionTypesMsg_(true);
489 HelpPage
.showAllowedConnectionTypesMsg = function(visible
) {
490 HelpPage
.getInstance().showAllowedConnectionTypesMsg_(visible
);
493 HelpPage
.setPromotionState = function(state
) {
494 HelpPage
.getInstance().setPromotionState_(state
);
497 HelpPage
.setObsoleteSystem = function(obsolete
) {
498 HelpPage
.getInstance().setObsoleteSystem_(obsolete
);
501 HelpPage
.setObsoleteSystemEndOfTheLine = function(endOfTheLine
) {
502 HelpPage
.getInstance().setObsoleteSystemEndOfTheLine_(endOfTheLine
);
505 HelpPage
.setOSVersion = function(version
) {
506 HelpPage
.getInstance().setOSVersion_(version
);
509 HelpPage
.setOSFirmware = function(firmware
) {
510 HelpPage
.getInstance().setOSFirmware_(firmware
);
513 HelpPage
.showOverlay = function(name
) {
514 HelpPage
.getInstance().showOverlay(name
);
517 HelpPage
.cancelOverlay = function() {
518 HelpPage
.getInstance().closeOverlay();
521 HelpPage
.getTopmostVisiblePage = function() {
522 return HelpPage
.getInstance().getTopmostVisiblePage();
525 HelpPage
.updateIsEnterpriseManaged = function(isEnterpriseManaged
) {
528 help
.ChannelChangePage
.updateIsEnterpriseManaged(isEnterpriseManaged
);
531 HelpPage
.updateCurrentChannel = function(channel
) {
534 HelpPage
.getInstance().updateCurrentChannel_(channel
);
537 HelpPage
.updateTargetChannel = function(channel
) {
540 help
.ChannelChangePage
.updateTargetChannel(channel
);
543 HelpPage
.updateEnableReleaseChannel = function(enabled
) {
544 HelpPage
.getInstance().updateEnableReleaseChannel_(enabled
);
547 HelpPage
.setChannel = function(channel
, isPowerwashAllowed
) {
548 HelpPage
.getInstance().setChannel_(channel
, isPowerwashAllowed
);
551 HelpPage
.setBuildDate = function(buildDate
) {
552 HelpPage
.getInstance().setBuildDate_(buildDate
);
555 HelpPage
.updateChannelChangePageContainerVisibility = function() {
556 HelpPage
.getInstance().updateChannelChangePageContainerVisibility_();
566 * onload listener to initialize the HelpPage.
568 window
.onload = function() {
569 help
.HelpPage
.getInstance().initialize();