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();