Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / help / help_page.js
1 // Copyright 2014 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.
4
5 cr.define('help', function() {
6   var Page = cr.ui.pageManager.Page;
7   var PageManager = cr.ui.pageManager.PageManager;
8
9   /**
10    * Encapsulated handling of the About page. Called 'help' internally to avoid
11    * confusion with generic AboutUI (about:memory, about:sandbox, etc.).
12    */
13   function HelpPage() {
14     var id = loadTimeData.valueExists('aboutOverlayTabTitle') ?
15       'aboutOverlayTabTitle' : 'aboutTitle';
16     Page.call(this, 'help', loadTimeData.getString(id), 'help-page');
17   }
18
19   cr.addSingletonGetter(HelpPage);
20
21   HelpPage.prototype = {
22     __proto__: Page.prototype,
23
24     /**
25      * List of the channel names. Should be ordered in increasing level of
26      * stability.
27      * @private
28      */
29     channelList_: ['dev-channel', 'beta-channel', 'stable-channel'],
30
31     /**
32      * Name of the channel the device is currently on.
33      * @private
34      */
35     currentChannel_: null,
36
37     /**
38      * Name of the channel the device is supposed to be on.
39      * @private
40      */
41     targetChannel_: null,
42
43     /**
44      * Last status received from the version updater.
45      * @private
46      */
47     status_: null,
48
49     /**
50      * Last message received from the version updater.
51      * @private
52      */
53     message_: null,
54
55     /** @override */
56     initializePage: function() {
57       Page.prototype.initializePage.call(this);
58
59       $('product-license').innerHTML = loadTimeData.getString('productLicense');
60       if (cr.isChromeOS) {
61         $('product-os-license').innerHTML =
62             loadTimeData.getString('productOsLicense');
63       }
64
65       var productTOS = $('product-tos');
66       if (productTOS)
67         productTOS.innerHTML = loadTimeData.getString('productTOS');
68
69       $('get-help').onclick = function() {
70         chrome.send('openHelpPage');
71       };
72 <if expr="_google_chrome">
73       $('report-issue').onclick = function() {
74         chrome.send('openFeedbackDialog');
75       };
76 </if>
77
78       this.maybeSetOnClick_($('more-info-expander'),
79           this.toggleMoreInfo_.bind(this));
80
81       this.maybeSetOnClick_($('promote'), function() {
82         chrome.send('promoteUpdater');
83       });
84       this.maybeSetOnClick_($('relaunch'), function() {
85         chrome.send('relaunchNow');
86       });
87       if (cr.isChromeOS) {
88         this.maybeSetOnClick_($('relaunch-and-powerwash'), function() {
89           chrome.send('relaunchAndPowerwash');
90         });
91
92         this.channelTable_ = {
93           'stable-channel': {
94             'name': loadTimeData.getString('stable'),
95             'label': loadTimeData.getString('currentChannelStable'),
96           },
97           'beta-channel': {
98             'name': loadTimeData.getString('beta'),
99             'label': loadTimeData.getString('currentChannelBeta')
100           },
101           'dev-channel': {
102             'name': loadTimeData.getString('dev'),
103             'label': loadTimeData.getString('currentChannelDev')
104           }
105         };
106       }
107       this.maybeSetOnClick_($('about-done'), function() {
108         // Event listener for the close button when shown as an overlay.
109         PageManager.closeOverlay();
110       });
111
112       var self = this;
113       var channelChanger = $('channel-changer');
114       if (channelChanger) {
115         channelChanger.onchange = function(event) {
116           self.setChannel_(event.target.value, false);
117         };
118       }
119
120       if (cr.isChromeOS) {
121         // Add event listener for the check for and apply updates button.
122         this.maybeSetOnClick_($('request-update'), function() {
123           self.setUpdateStatus_('checking');
124           $('request-update').disabled = true;
125           chrome.send('requestUpdate');
126         });
127
128         $('change-channel').onclick = function() {
129           PageManager.showPageByName('channel-change-page', false);
130         };
131
132         var channelChangeDisallowedError = document.createElement('div');
133         channelChangeDisallowedError.className = 'channel-change-error-bubble';
134
135         var channelChangeDisallowedIcon = document.createElement('div');
136         channelChangeDisallowedIcon.classList.add('help-page-icon-large');
137         channelChangeDisallowedIcon.classList.add('channel-change-error-icon');
138         channelChangeDisallowedError.appendChild(channelChangeDisallowedIcon);
139
140         var channelChangeDisallowedText = document.createElement('div');
141         channelChangeDisallowedText.className = 'channel-change-error-text';
142         channelChangeDisallowedText.textContent =
143             loadTimeData.getString('channelChangeDisallowedMessage');
144         channelChangeDisallowedError.appendChild(channelChangeDisallowedText);
145
146         $('channel-change-disallowed-icon').onclick = function() {
147           PageManager.showBubble(channelChangeDisallowedError,
148                                  $('channel-change-disallowed-icon'),
149                                  $('help-container'),
150                                  cr.ui.ArrowLocation.TOP_END);
151         };
152       }
153
154       // Attempt to update.
155       chrome.send('onPageLoaded');
156     },
157
158     /** @override */
159     didClosePage: function() {
160       this.setMoreInfoVisible_(false);
161     },
162
163     /**
164      * Sets the visible state of the 'More Info' section.
165      * @param {boolean} visible Whether the section should be visible.
166      * @private
167      */
168     setMoreInfoVisible_: function(visible) {
169       var moreInfo = $('more-info-container');
170       if (visible == moreInfo.classList.contains('visible'))
171         return;
172
173       moreInfo.classList.toggle('visible', visible);
174       moreInfo.style.height = visible ? moreInfo.scrollHeight + 'px' : '';
175       moreInfo.addEventListener('webkitTransitionEnd', function(event) {
176         $('more-info-expander').textContent = visible ?
177             loadTimeData.getString('hideMoreInfo') :
178             loadTimeData.getString('showMoreInfo');
179       });
180     },
181
182     /**
183      * Toggles the visible state of the 'More Info' section.
184      * @private
185      */
186     toggleMoreInfo_: function() {
187       var moreInfo = $('more-info-container');
188       this.setMoreInfoVisible_(!moreInfo.classList.contains('visible'));
189     },
190
191     /**
192      * Assigns |method| to the onclick property of |el| if |el| exists.
193      * @param {HTMLElement} el The element on which to set the click handler.
194      * @param {Function} method The click handler.
195      * @private
196      */
197     maybeSetOnClick_: function(el, method) {
198       if (el)
199         el.onclick = method;
200     },
201
202     /**
203      * @param {string} state The state of the update.
204      * private
205      */
206     setUpdateImage_: function(state) {
207       $('update-status-icon').className = 'help-page-icon ' + state;
208     },
209
210     /**
211      * @return {boolean} True, if new channel switcher UI is used,
212      *    false otherwise.
213      * @private
214      */
215     isNewChannelSwitcherUI_: function() {
216       return !loadTimeData.valueExists('disableNewChannelSwitcherUI');
217     },
218
219     /**
220      * @return {boolean} True if target and current channels are not null and
221      *     not equal.
222      * @private
223      */
224     channelsDiffer_: function() {
225       var current = this.currentChannel_;
226       var target = this.targetChannel_;
227       return (current != null && target != null && current != target);
228     },
229
230     /**
231      * @return {boolean} True if target channel is more stable than the current
232      *     one, and false otherwise.
233      * @private
234      */
235     targetChannelIsMoreStable_: function() {
236       var current = this.currentChannel_;
237       var target = this.targetChannel_;
238       if (current == null || target == null)
239         return false;
240       var currentIndex = this.channelList_.indexOf(current);
241       var targetIndex = this.channelList_.indexOf(target);
242       if (currentIndex < 0 || targetIndex < 0)
243         return false;
244       return currentIndex < targetIndex;
245     },
246
247     /**
248      * @param {string} status The status of the update.
249      * @param {string} message Failure message to display.
250      * @private
251      */
252     setUpdateStatus_: function(status, message) {
253       this.status_ = status;
254       this.message_ = message;
255
256       this.updateUI_();
257     },
258
259     /**
260       * Updates UI elements on the page according to current state.
261       * @private
262       */
263     updateUI_: function() {
264       var status = this.status_;
265       var message = this.message_;
266       var channel = this.targetChannel_;
267
268       if (this.channelList_.indexOf(channel) >= 0) {
269         $('current-channel').textContent = loadTimeData.getStringF(
270             'currentChannel', this.channelTable_[channel].label);
271         this.updateChannelChangePageContainerVisibility_();
272       }
273
274       if (status == null)
275         return;
276
277       if (cr.isMac &&
278           $('update-status-message') &&
279           $('update-status-message').hidden) {
280         // Chrome has reached the end of the line on this system. The
281         // update-obsolete-system message is displayed. No other auto-update
282         // status should be displayed.
283         return;
284       }
285
286       if (status == 'checking') {
287         this.setUpdateImage_('working');
288         $('update-status-message').innerHTML =
289             loadTimeData.getString('updateCheckStarted');
290       } else if (status == 'updating') {
291         this.setUpdateImage_('working');
292         if (this.channelsDiffer_()) {
293           $('update-status-message').innerHTML =
294               loadTimeData.getStringF('updatingChannelSwitch',
295                                       this.channelTable_[channel].label);
296         } else {
297           $('update-status-message').innerHTML =
298               loadTimeData.getStringF('updating');
299         }
300       } else if (status == 'nearly_updated') {
301         this.setUpdateImage_('up-to-date');
302         if (this.channelsDiffer_()) {
303           $('update-status-message').innerHTML =
304               loadTimeData.getString('successfulChannelSwitch');
305         } else {
306           $('update-status-message').innerHTML =
307               loadTimeData.getString('updateAlmostDone');
308         }
309       } else if (status == 'updated') {
310         this.setUpdateImage_('up-to-date');
311         $('update-status-message').innerHTML =
312             loadTimeData.getString('upToDate');
313       } else if (status == 'failed') {
314         this.setUpdateImage_('failed');
315         $('update-status-message').innerHTML = message;
316       }
317
318       // Following invariant must be established at the end of this function:
319       // { ~$('relaunch_and_powerwash').hidden -> $('relaunch').hidden }
320       var relaunchAndPowerwashHidden = true;
321       if ($('relaunch-and-powerwash')) {
322         // It's allowed to do powerwash only for customer devices,
323         // when user explicitly decides to update to a more stable
324         // channel.
325         relaunchAndPowerwashHidden =
326             !this.targetChannelIsMoreStable_() || status != 'nearly_updated';
327         $('relaunch-and-powerwash').hidden = relaunchAndPowerwashHidden;
328       }
329
330       if (cr.isChromeOS) {
331         // Only enable the update button if it hasn't been used yet or the
332         // status isn't 'updated'.
333         if (!$('request-update').disabled || status != 'updated') {
334           // Disable the button if an update is already in progress.
335           $('request-update').disabled =
336             ['checking', 'updating', 'nearly_updated'].indexOf(status) > -1;
337         }
338       }
339
340       var container = $('update-status-container');
341       if (container) {
342         container.hidden = status == 'disabled';
343         $('relaunch').hidden =
344             (status != 'nearly_updated') || !relaunchAndPowerwashHidden;
345
346         if (cr.isChromeOS) {
347           // Assume the "updated" status is stale if we haven't checked yet.
348           if (status == 'updated' && !$('request-update').disabled)
349             container.hidden = true;
350
351           // Hide the request update button if auto-updating is disabled or
352           // a relaunch button is showing.
353           $('request-update').hidden = status == 'disabled' ||
354             !$('relaunch').hidden || !relaunchAndPowerwashHidden;
355         }
356
357         if (!cr.isMac)
358           $('update-percentage').hidden = status != 'updating';
359       }
360     },
361
362     /**
363      * @param {number} progress The percent completion.
364      * @private
365      */
366     setProgress_: function(progress) {
367       $('update-percentage').innerHTML = progress + '%';
368     },
369
370     /**
371      * @param {string} message The allowed connection types message.
372      * @private
373      */
374     setAllowedConnectionTypesMsg_: function(message) {
375       $('allowed-connection-types-message').innerText = message;
376     },
377
378     /**
379      * @param {boolean} visible Whether to show the message.
380      * @private
381      */
382     showAllowedConnectionTypesMsg_: function(visible) {
383       $('allowed-connection-types-message').hidden = !visible;
384     },
385
386     /**
387      * @param {string} state The promote state to set.
388      * @private
389      */
390     setPromotionState_: function(state) {
391       if (state == 'hidden') {
392         $('promote').hidden = true;
393       } else if (state == 'enabled') {
394         $('promote').disabled = false;
395         $('promote').hidden = false;
396       } else if (state == 'disabled') {
397         $('promote').disabled = true;
398         $('promote').hidden = false;
399       }
400     },
401
402     /**
403      * @param {boolean} obsolete Whether the system is obsolete.
404      * @private
405      */
406     setObsoleteSystem_: function(obsolete) {
407       if (cr.isMac && $('update-obsolete-system-container')) {
408         $('update-obsolete-system-container').hidden = !obsolete;
409       }
410     },
411
412     /**
413      * @param {boolean} endOfTheLine Whether the train has rolled into
414      *     the station.
415      * @private
416      */
417     setObsoleteSystemEndOfTheLine_: function(endOfTheLine) {
418       if (cr.isMac &&
419           $('update-obsolete-system-container') &&
420           !$('update-obsolete-system-container').hidden &&
421           $('update-status-message')) {
422         $('update-status-message').hidden = endOfTheLine;
423         if (endOfTheLine) {
424           this.setUpdateImage_('failed');
425         }
426       }
427     },
428
429     /**
430      * @param {string} version Version of Chrome OS.
431      * @private
432      */
433     setOSVersion_: function(version) {
434       if (!cr.isChromeOS)
435         console.error('OS version unsupported on non-CrOS');
436
437       $('os-version').parentNode.hidden = (version == '');
438       $('os-version').textContent = version;
439     },
440
441     /**
442      * @param {string} firmware Firmware on Chrome OS.
443      * @private
444      */
445     setOSFirmware_: function(firmware) {
446       if (!cr.isChromeOS)
447         console.error('OS firmware unsupported on non-CrOS');
448
449       $('firmware').parentNode.hidden = (firmware == '');
450       $('firmware').textContent = firmware;
451     },
452
453     /**
454      * Updates page UI according to device owhership policy.
455      * @param {boolean} isEnterpriseManaged True if the device is
456      *     enterprise managed.
457      * @private
458      */
459     updateIsEnterpriseManaged_: function(isEnterpriseManaged) {
460       help.ChannelChangePage.updateIsEnterpriseManaged(isEnterpriseManaged);
461       this.updateUI_();
462     },
463
464     /**
465      * Updates name of the current channel, i.e. the name of the
466      * channel the device is currently on.
467      * @param {string} channel The name of the current channel.
468      * @private
469      */
470     updateCurrentChannel_: function(channel) {
471       if (this.channelList_.indexOf(channel) < 0)
472         return;
473       this.currentChannel_ = channel;
474       help.ChannelChangePage.updateCurrentChannel(channel);
475       this.updateUI_();
476     },
477
478     /**
479      * Updates name of the target channel, i.e. the name of the
480      * channel the device is supposed to be.
481      * @param {string} channel The name of the target channel.
482      * @private
483      */
484     updateTargetChannel_: function(channel) {
485       if (this.channelList_.indexOf(channel) < 0)
486         return;
487       this.targetChannel_ = channel;
488       help.ChannelChangePage.updateTargetChannel(channel);
489       this.updateUI_();
490     },
491
492     /**
493      * @param {boolean} enabled True if the release channel can be enabled.
494      * @private
495      */
496     updateEnableReleaseChannel_: function(enabled) {
497       this.updateChannelChangerContainerVisibility_(enabled);
498       $('change-channel').disabled = !enabled;
499       $('channel-change-disallowed-icon').hidden = enabled;
500     },
501
502     /**
503      * Sets the device target channel.
504      * @param {string} channel The name of the target channel.
505      * @param {boolean} isPowerwashAllowed True iff powerwash is allowed.
506      * @private
507      */
508     setChannel_: function(channel, isPowerwashAllowed) {
509       chrome.send('setChannel', [channel, isPowerwashAllowed]);
510       $('channel-change-confirmation').hidden = false;
511       $('channel-change-confirmation').textContent = loadTimeData.getStringF(
512           'channel-changed', this.channelTable_[channel].name);
513       this.updateTargetChannel_(channel);
514     },
515
516     /**
517      * Sets the value of the "Build Date" field of the "More Info" section.
518      * @param {string} buildDate The date of the build.
519      * @private
520      */
521     setBuildDate_: function(buildDate) {
522       $('build-date-container').classList.remove('empty');
523       $('build-date').textContent = buildDate;
524     },
525
526     /**
527      * Updates channel-change-page-container visibility according to
528      * internal state.
529      * @private
530      */
531     updateChannelChangePageContainerVisibility_: function() {
532       if (!this.isNewChannelSwitcherUI_()) {
533         $('channel-change-page-container').hidden = true;
534         return;
535       }
536       $('channel-change-page-container').hidden =
537           !help.ChannelChangePage.isPageReady();
538     },
539
540     /**
541      * Updates channel-changer dropdown visibility if |visible| is
542      * true and new channel switcher UI is disallowed.
543      * @param {boolean} visible True if channel-changer should be
544      *     displayed, false otherwise.
545      * @private
546      */
547     updateChannelChangerContainerVisibility_: function(visible) {
548       if (this.isNewChannelSwitcherUI_()) {
549         $('channel-changer').hidden = true;
550         return;
551       }
552       $('channel-changer').hidden = !visible;
553     },
554   };
555
556   HelpPage.setUpdateStatus = function(status, message) {
557     HelpPage.getInstance().setUpdateStatus_(status, message);
558   };
559
560   HelpPage.setProgress = function(progress) {
561     HelpPage.getInstance().setProgress_(progress);
562   };
563
564   HelpPage.setAndShowAllowedConnectionTypesMsg = function(message) {
565     HelpPage.getInstance().setAllowedConnectionTypesMsg_(message);
566     HelpPage.getInstance().showAllowedConnectionTypesMsg_(true);
567   };
568
569   HelpPage.showAllowedConnectionTypesMsg = function(visible) {
570     HelpPage.getInstance().showAllowedConnectionTypesMsg_(visible);
571   };
572
573   HelpPage.setPromotionState = function(state) {
574     HelpPage.getInstance().setPromotionState_(state);
575   };
576
577   HelpPage.setObsoleteSystem = function(obsolete) {
578     HelpPage.getInstance().setObsoleteSystem_(obsolete);
579   };
580
581   HelpPage.setObsoleteSystemEndOfTheLine = function(endOfTheLine) {
582     HelpPage.getInstance().setObsoleteSystemEndOfTheLine_(endOfTheLine);
583   };
584
585   HelpPage.setOSVersion = function(version) {
586     HelpPage.getInstance().setOSVersion_(version);
587   };
588
589   HelpPage.setOSFirmware = function(firmware) {
590     HelpPage.getInstance().setOSFirmware_(firmware);
591   };
592
593   HelpPage.updateIsEnterpriseManaged = function(isEnterpriseManaged) {
594     if (!cr.isChromeOS)
595       return;
596     HelpPage.getInstance().updateIsEnterpriseManaged_(isEnterpriseManaged);
597   };
598
599   HelpPage.updateCurrentChannel = function(channel) {
600     if (!cr.isChromeOS)
601       return;
602     HelpPage.getInstance().updateCurrentChannel_(channel);
603   };
604
605   HelpPage.updateTargetChannel = function(channel) {
606     if (!cr.isChromeOS)
607       return;
608     HelpPage.getInstance().updateTargetChannel_(channel);
609   };
610
611   HelpPage.updateEnableReleaseChannel = function(enabled) {
612     HelpPage.getInstance().updateEnableReleaseChannel_(enabled);
613   };
614
615   HelpPage.setChannel = function(channel, isPowerwashAllowed) {
616     HelpPage.getInstance().setChannel_(channel, isPowerwashAllowed);
617   };
618
619   HelpPage.setBuildDate = function(buildDate) {
620     HelpPage.getInstance().setBuildDate_(buildDate);
621   };
622
623   // Export
624   return {
625     HelpPage: HelpPage
626   };
627 });