Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / resources / sync_setup_overlay.js
blob909aa0a6d41c9f5106170f865957a98bfa858813
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 cr.define('options', function() {
6   /** @const */ var OptionsPage = options.OptionsPage;
8   // True if the synced account uses a custom passphrase.
9   var usePassphrase_ = false;
11   // True if the synced account uses 'encrypt everything'.
12   var useEncryptEverything_ = false;
14   // An object used as a cache of the arguments passed in while initially
15   // displaying the advanced sync settings dialog. Used to switch between the
16   // options in the main drop-down menu. Reset when the dialog is closed.
17   var syncConfigureArgs_ = null;
19   // A dictionary that maps the sync data type checkbox names to their checked
20   // state. Initialized when the advanced settings dialog is first brought up,
21   // updated any time a box is checked / unchecked, and reset when the dialog is
22   // closed. Used to restore checkbox state while switching between the options
23   // in the main drop-down menu. All checkboxes are checked and disabled when
24   // the "Sync everything" menu-item is selected, and unchecked and disabled
25   // when "Sync nothing" is selected. When "Choose what to sync" is selected,
26   // the boxes are restored to their most recent checked state from this cache.
27   var dataTypeBoxes_ = {};
29   // Used to determine whether to bring the OK button / passphrase field into
30   // focus.
31   var confirmPageVisible_ = false;
32   var customizePageVisible_ = false;
34   /**
35    * The user's selection in the synced data type drop-down menu, as an index.
36    * @enum {number}
37    * @const
38    */
39   var DataTypeSelection = {
40     SYNC_EVERYTHING: 0,
41     CHOOSE_WHAT_TO_SYNC: 1,
42     SYNC_NOTHING: 2
43   };
45   /**
46    * SyncSetupOverlay class
47    * Encapsulated handling of the 'Sync Setup' overlay page.
48    * @class
49    */
50   function SyncSetupOverlay() {
51     OptionsPage.call(this, 'syncSetup',
52                      loadTimeData.getString('syncSetupOverlayTabTitle'),
53                      'sync-setup-overlay');
54   }
56   cr.addSingletonGetter(SyncSetupOverlay);
58   SyncSetupOverlay.prototype = {
59     __proto__: OptionsPage.prototype,
61     /**
62      * Initializes the page.
63      */
64     initializePage: function() {
65       OptionsPage.prototype.initializePage.call(this);
67       var self = this;
68       $('basic-encryption-option').onchange =
69           $('full-encryption-option').onchange = function() {
70         self.onEncryptionRadioChanged_();
71       }
72       $('choose-datatypes-cancel').onclick =
73           $('confirm-everything-cancel').onclick =
74           $('stop-syncing-cancel').onclick =
75           $('sync-spinner-cancel').onclick = function() {
76         self.closeOverlay_();
77       };
78       $('confirm-everything-ok').onclick = function() {
79         self.sendConfiguration_();
80       };
81       $('timeout-ok').onclick = function() {
82         chrome.send('CloseTimeout');
83         self.closeOverlay_();
84       };
85       $('stop-syncing-ok').onclick = function() {
86         chrome.send('SyncSetupStopSyncing');
87         self.closeOverlay_();
88       };
89     },
91     showOverlay_: function() {
92       OptionsPage.navigateToPage('syncSetup');
93     },
95     closeOverlay_: function() {
96       this.syncConfigureArgs_ = null;
97       this.dataTypeBoxes_ = {};
99       var overlay = $('sync-setup-overlay');
100       if (!overlay.hidden)
101         OptionsPage.closeOverlay();
102     },
104     /** @override */
105     didShowPage: function() {
106       chrome.send('SyncSetupShowSetupUI');
107     },
109     /** @override */
110     didClosePage: function() {
111       chrome.send('SyncSetupDidClosePage');
112     },
114     onEncryptionRadioChanged_: function() {
115       var visible = $('full-encryption-option').checked;
116       $('sync-custom-passphrase').hidden = !visible;
117     },
119     /**
120      * Sets the checked state of the individual sync data type checkboxes in the
121      * advanced sync settings dialog.
122      * @param {boolean} value True for checked, false for unchecked.
123      * @private
124      */
125     checkAllDataTypeCheckboxes_: function(value) {
126       // Only check / uncheck the visible ones (since there's no way to uncheck
127       // / check the invisible ones).
128       var checkboxes = $('choose-data-types-body').querySelectorAll(
129           '.sync-type-checkbox:not([hidden]) input');
130       for (var i = 0; i < checkboxes.length; i++) {
131         checkboxes[i].checked = value;
132       }
133     },
135     /**
136      * Restores the checked states of the sync data type checkboxes in the
137      * advanced sync settings dialog. Called when "Choose what to sync" is
138      * selected. Required because all the checkboxes are checked when
139      * "Sync everything" is selected, and unchecked when "Sync nothing" is
140      * selected. Note: We only restore checkboxes for data types that are
141      * actually visible and whose old values are found in the cache, since it's
142      * possible for some data types to not be registered, and therefore, their
143      * checkboxes remain hidden, and never get cached.
144      * @private
145      */
146     restoreDataTypeCheckboxes_: function() {
147       for (dataType in dataTypeBoxes_) {
148         $(dataType).checked = dataTypeBoxes_[dataType];
149       }
150     },
152     /**
153      * Enables / grays out the sync data type checkboxes in the advanced
154      * settings dialog.
155      * @param {boolean} enabled True for enabled, false for grayed out.
156      * @private
157      */
158     setDataTypeCheckboxesEnabled_: function(enabled) {
159       var checkboxes = $('choose-data-types-body').querySelectorAll('input');
160       for (var i = 0; i < checkboxes.length; i++) {
161         checkboxes[i].disabled = !enabled;
162       }
163     },
165     /**
166      * Sets the state of the sync data type checkboxes based on whether "Sync
167      * everything", "Choose what to sync", or "Sync nothing" are selected in the
168      * drop-down menu of the advanced settings dialog.
169      * @param {cr.DataTypeSelection} selectedIndex Index of user's selection.
170      * @private
171      */
172     setDataTypeCheckboxes_: function(selectedIndex) {
173       if (selectedIndex == DataTypeSelection.CHOOSE_WHAT_TO_SYNC) {
174         this.setDataTypeCheckboxesEnabled_(true);
175         this.restoreDataTypeCheckboxes_();
176       } else {
177         this.setDataTypeCheckboxesEnabled_(false);
178         this.checkAllDataTypeCheckboxes_(selectedIndex ==
179                                          DataTypeSelection.SYNC_EVERYTHING);
180       }
181     },
183     checkPassphraseMatch_: function() {
184       var emptyError = $('empty-error');
185       var mismatchError = $('mismatch-error');
186       emptyError.hidden = true;
187       mismatchError.hidden = true;
189       var f = $('choose-data-types-form');
190       if (!$('full-encryption-option').checked ||
191            $('basic-encryption-option').disabled) {
192         return true;
193       }
195       var customPassphrase = $('custom-passphrase');
196       if (customPassphrase.value.length == 0) {
197         emptyError.hidden = false;
198         return false;
199       }
201       var confirmPassphrase = $('confirm-passphrase');
202       if (confirmPassphrase.value != customPassphrase.value) {
203         mismatchError.hidden = false;
204         return false;
205       }
207       return true;
208     },
210     sendConfiguration_: function() {
211       var encryptAllData = $('full-encryption-option').checked;
213       var usePassphrase;
214       var customPassphrase;
215       var googlePassphrase = false;
216       if (!$('sync-existing-passphrase-container').hidden) {
217         // If we were prompted for an existing passphrase, use it.
218         customPassphrase = $('choose-data-types-form').passphrase.value;
219         usePassphrase = true;
220         // If we were displaying the 'enter your old google password' prompt,
221         // then that means this is the user's google password.
222         googlePassphrase = !$('google-passphrase-needed-body').hidden;
223         // We allow an empty passphrase, in case the user has disabled
224         // all their encrypted datatypes. In that case, the PSS will accept
225         // the passphrase and finish configuration. If the user has enabled
226         // encrypted datatypes, the PSS will prompt again specifying that the
227         // passphrase failed.
228       } else if (!$('basic-encryption-option').disabled &&
229                   $('full-encryption-option').checked) {
230         // The user is setting a custom passphrase for the first time.
231         if (!this.checkPassphraseMatch_())
232           return;
233         customPassphrase = $('custom-passphrase').value;
234         usePassphrase = true;
235       } else {
236         // The user is not setting a custom passphrase.
237         usePassphrase = false;
238       }
240       // Don't allow the user to tweak the settings once we send the
241       // configuration to the backend.
242       this.setInputElementsDisabledState_(true);
243       $('use-default-link').hidden = true;
244       $('use-default-link').disabled = true;
245       $('use-default-link').onclick = null;
247       // These values need to be kept in sync with where they are read in
248       // SyncSetupFlow::GetDataTypeChoiceData().
249       var syncAll = $('sync-select-datatypes').selectedIndex ==
250                     DataTypeSelection.SYNC_EVERYTHING;
251       var syncNothing = $('sync-select-datatypes').selectedIndex ==
252                         DataTypeSelection.SYNC_NOTHING;
253       var result = JSON.stringify({
254         'syncAllDataTypes': syncAll,
255         'syncNothing': syncNothing,
256         'bookmarksSynced': syncAll || $('bookmarks-checkbox').checked,
257         'preferencesSynced': syncAll || $('preferences-checkbox').checked,
258         'themesSynced': syncAll || $('themes-checkbox').checked,
259         'passwordsSynced': syncAll || $('passwords-checkbox').checked,
260         'autofillSynced': syncAll || $('autofill-checkbox').checked,
261         'extensionsSynced': syncAll || $('extensions-checkbox').checked,
262         'typedUrlsSynced': syncAll || $('typed-urls-checkbox').checked,
263         'appsSynced': syncAll || $('apps-checkbox').checked,
264         'tabsSynced': syncAll || $('tabs-checkbox').checked,
265         'encryptAllData': encryptAllData,
266         'usePassphrase': usePassphrase,
267         'isGooglePassphrase': googlePassphrase,
268         'passphrase': customPassphrase
269       });
270       chrome.send('SyncSetupConfigure', [result]);
271     },
273     /**
274      * Sets the disabled property of all input elements within the 'Customize
275      * Sync Preferences' screen. This is used to prohibit the user from changing
276      * the inputs after confirming the customized sync preferences, or resetting
277      * the state when re-showing the dialog.
278      * @param {boolean} disabled True if controls should be set to disabled.
279      * @private
280      */
281     setInputElementsDisabledState_: function(disabled) {
282       var configureElements =
283           $('customize-sync-preferences').querySelectorAll('input');
284       for (var i = 0; i < configureElements.length; i++)
285         configureElements[i].disabled = disabled;
286       $('sync-select-datatypes').disabled = disabled;
288       $('customize-link').hidden = disabled;
289       $('customize-link').disabled = disabled;
290       $('customize-link').onclick = (disabled ? null : function() {
291         SyncSetupOverlay.showCustomizePage(null,
292                                            DataTypeSelection.SYNC_EVERYTHING);
293         return false;
294       });
295     },
297     /**
298      * Shows or hides the sync data type checkboxes in the advanced sync
299      * settings dialog. Also initializes |dataTypeBoxes_| with their values, and
300      * makes their onclick handlers update |dataTypeBoxes_|.
301      * @param {Object} args The configuration data used to show/hide UI.
302      * @private
303      */
304     setChooseDataTypesCheckboxes_: function(args) {
305       var datatypeSelect = $('sync-select-datatypes');
306       datatypeSelect.selectedIndex = args.syncAllDataTypes ?
307                                          DataTypeSelection.SYNC_EVERYTHING :
308                                          DataTypeSelection.CHOOSE_WHAT_TO_SYNC;
310       $('bookmarks-checkbox').checked = args.bookmarksSynced;
311       dataTypeBoxes_['bookmarks-checkbox'] = args.bookmarksSynced;
312       $('bookmarks-checkbox').onclick = this.handleDataTypeClick_;
314       $('preferences-checkbox').checked = args.preferencesSynced;
315       dataTypeBoxes_['preferences-checkbox'] = args.preferencesSynced;
316       $('preferences-checkbox').onclick = this.handleDataTypeClick_;
318       $('themes-checkbox').checked = args.themesSynced;
319       dataTypeBoxes_['themes-checkbox'] = args.themesSynced;
320       $('themes-checkbox').onclick = this.handleDataTypeClick_;
322       if (args.passwordsRegistered) {
323         $('passwords-checkbox').checked = args.passwordsSynced;
324         dataTypeBoxes_['passwords-checkbox'] = args.passwordsSynced;
325         $('passwords-checkbox').onclick = this.handleDataTypeClick_;
326         $('passwords-item').hidden = false;
327       } else {
328         $('passwords-item').hidden = true;
329       }
330       if (args.autofillRegistered) {
331         $('autofill-checkbox').checked = args.autofillSynced;
332         dataTypeBoxes_['autofill-checkbox'] = args.autofillSynced;
333         $('autofill-checkbox').onclick = this.handleDataTypeClick_;
334         $('autofill-item').hidden = false;
335       } else {
336         $('autofill-item').hidden = true;
337       }
338       if (args.extensionsRegistered) {
339         $('extensions-checkbox').checked = args.extensionsSynced;
340         dataTypeBoxes_['extensions-checkbox'] = args.extensionsSynced;
341         $('extensions-checkbox').onclick = this.handleDataTypeClick_;
342         $('extensions-item').hidden = false;
343       } else {
344         $('extensions-item').hidden = true;
345       }
346       if (args.typedUrlsRegistered) {
347         $('typed-urls-checkbox').checked = args.typedUrlsSynced;
348         dataTypeBoxes_['typed-urls-checkbox'] = args.typedUrlsSynced;
349         $('typed-urls-checkbox').onclick = this.handleDataTypeClick_;
350         $('omnibox-item').hidden = false;
351       } else {
352         $('omnibox-item').hidden = true;
353       }
354       if (args.appsRegistered) {
355         $('apps-checkbox').checked = args.appsSynced;
356         dataTypeBoxes_['apps-checkbox'] = args.appsSynced;
357         $('apps-checkbox').onclick = this.handleDataTypeClick_;
358         $('apps-item').hidden = false;
359       } else {
360         $('apps-item').hidden = true;
361       }
362       if (args.tabsRegistered) {
363         $('tabs-checkbox').checked = args.tabsSynced;
364         dataTypeBoxes_['tabs-checkbox'] = args.tabsSynced;
365         $('tabs-checkbox').onclick = this.handleDataTypeClick_;
366         $('tabs-item').hidden = false;
367       } else {
368         $('tabs-item').hidden = true;
369       }
371       this.setDataTypeCheckboxes_(datatypeSelect.selectedIndex);
372     },
374     /**
375      * Updates the cached values of the sync data type checkboxes stored in
376      * |dataTypeBoxes_|. Used as an onclick handler for each data type checkbox.
377      * @private
378      */
379     handleDataTypeClick_: function() {
380       dataTypeBoxes_[this.id] = this.checked;
381     },
383     setEncryptionRadios_: function(args) {
384       if (!args.encryptAllData && !args.usePassphrase) {
385         $('basic-encryption-option').checked = true;
386       } else {
387         $('full-encryption-option').checked = true;
388         $('full-encryption-option').disabled = true;
389         $('basic-encryption-option').disabled = true;
390       }
391     },
393     setCheckboxesAndErrors_: function(args) {
394       this.setChooseDataTypesCheckboxes_(args);
395       this.setEncryptionRadios_(args);
396     },
398     showConfigure_: function(args) {
399       var datatypeSelect = $('sync-select-datatypes');
400       var self = this;
402       // Cache the sync config args so they can be reused when we transition
403       // between the drop-down menu items in the advanced settings dialog.
404       if (args)
405         this.syncConfigureArgs_ = args;
407       // Required in order to determine whether to give focus to the OK button
408       // or passphrase field. See crbug.com/310555 and crbug.com/306353.
409       this.confirmPageVisible_ = false;
410       this.customizePageVisible_ = false;
412       // Once the advanced sync settings dialog is visible, we transition
413       // between its drop-down menu items as follows:
414       // "Sync everything": Show encryption and passphrase sections, and disable
415       // and check all data type checkboxes.
416       // "Sync nothing": Hide encryption and passphrase sections, and disable
417       // and uncheck all data type checkboxes.
418       // "Choose what to sync": Show encryption and passphrase sections, enable
419       // data type checkboxes, and restore their checked state to the last time
420       // the "Choose what to sync" was selected while the dialog was still up.
421       datatypeSelect.onchange = function() {
422         if (this.selectedIndex == DataTypeSelection.SYNC_NOTHING) {
423           self.showSyncNothingPage_();
424         } else {
425           self.showCustomizePage_(self.syncConfigureArgs_, this.selectedIndex);
426           if (this.selectedIndex == DataTypeSelection.SYNC_EVERYTHING)
427             self.checkAllDataTypeCheckboxes_(true);
428           else
429             self.restoreDataTypeCheckboxes_();
430         }
431       };
433       this.resetPage_('sync-setup-configure');
434       $('sync-setup-configure').hidden = false;
436       // onsubmit is changed when submitting a passphrase. Reset it to its
437       // default.
438       $('choose-data-types-form').onsubmit = function() {
439         self.sendConfiguration_();
440         return false;
441       };
443       if (args) {
444         this.setCheckboxesAndErrors_(args);
446         this.useEncryptEverything_ = args.encryptAllData;
448         // Determine whether to display the 'OK, sync everything' confirmation
449         // dialog or the advanced sync settings dialog, and assign focus to the
450         // OK button, or to the passphrase field if a passphrase is required.
451         this.usePassphrase_ = args.usePassphrase;
452         if (args.showSyncEverythingPage == false || this.usePassphrase_ ||
453             args.syncAllDataTypes == false || args.showPassphrase) {
454           var index = args.syncAllDataTypes ?
455                           DataTypeSelection.SYNC_EVERYTHING :
456                           DataTypeSelection.CHOOSE_WHAT_TO_SYNC;
457           this.showCustomizePage_(args, index);
458         } else {
459           this.showSyncEverythingPage_();
460         }
461       }
462     },
464     showSpinner_: function() {
465       this.resetPage_('sync-setup-spinner');
466       $('sync-setup-spinner').hidden = false;
467     },
469     showTimeoutPage_: function() {
470       this.resetPage_('sync-setup-timeout');
471       $('sync-setup-timeout').hidden = false;
472     },
474     showSyncEverythingPage_: function() {
475       // Determine whether to bring the OK button into focus.
476       var wasConfirmPageHidden = !this.confirmPageVisible_;
477       this.confirmPageVisible_ = true;
478       this.customizePageVisible_ = false;
480       $('confirm-sync-preferences').hidden = false;
481       $('customize-sync-preferences').hidden = true;
483       // Reset the selection to 'Sync everything'.
484       $('sync-select-datatypes').selectedIndex = 0;
486       // The default state is to sync everything.
487       this.setDataTypeCheckboxes_(DataTypeSelection.SYNC_EVERYTHING);
489       if (!this.usePassphrase_)
490         $('sync-custom-passphrase').hidden = true;
492       if (!this.useEncryptEverything_ && !this.usePassphrase_)
493         $('basic-encryption-option').checked = true;
495       // Give the OK button focus only when the dialog wasn't already visible.
496       if (wasConfirmPageHidden)
497         $('confirm-everything-ok').focus();
498     },
500     /**
501      * Reveals the UI for when the user chooses not to sync any data types.
502      * This happens when the user signs in and selects "Sync nothing" in the
503      * advanced sync settings dialog.
504      * @private
505      */
506     showSyncNothingPage_: function() {
507       // Reset the selection to 'Sync nothing'.
508       $('sync-select-datatypes').selectedIndex = DataTypeSelection.SYNC_NOTHING;
510       // Uncheck and disable the individual data type checkboxes.
511       this.checkAllDataTypeCheckboxes_(false);
512       this.setDataTypeCheckboxesEnabled_(false);
514       // Hide the encryption section.
515       $('customize-sync-encryption-new').hidden = true;
516       $('sync-custom-passphrase-container').hidden = true;
517       $('sync-existing-passphrase-container').hidden = true;
519       // Hide the "use default settings" link.
520       $('use-default-link').hidden = true;
521       $('use-default-link').disabled = true;
522       $('use-default-link').onclick = null;
523     },
525     /**
526      * Reveals the UI for entering a custom passphrase during initial setup.
527      * This happens if the user has previously enabled a custom passphrase on a
528      * different machine.
529      * @param {Array} args The args that contain the passphrase UI
530      *     configuration.
531      * @private
532      */
533     showPassphraseContainer_: function(args) {
534       // Once we require a passphrase, we prevent the user from returning to
535       // the Sync Everything pane.
536       $('use-default-link').hidden = true;
537       $('use-default-link').disabled = true;
538       $('use-default-link').onclick = null;
539       $('sync-custom-passphrase-container').hidden = true;
540       $('sync-existing-passphrase-container').hidden = false;
542       // Hide the selection options within the new encryption section when
543       // prompting for a passphrase.
544       $('sync-new-encryption-section-container').hidden = true;
546       $('normal-body').hidden = true;
547       $('google-passphrase-needed-body').hidden = true;
548       // Display the correct prompt to the user depending on what type of
549       // passphrase is needed.
550       if (args.usePassphrase)
551         $('normal-body').hidden = false;
552       else
553         $('google-passphrase-needed-body').hidden = false;
555       $('passphrase-learn-more').hidden = false;
556       // Warn the user about their incorrect passphrase if we need a passphrase
557       // and the passphrase field is non-empty (meaning they tried to set it
558       // previously but failed).
559       $('incorrect-passphrase').hidden =
560           !(args.usePassphrase && args.passphraseFailed);
562       $('sync-passphrase-warning').hidden = false;
563     },
565     /**
566      * Displays the advanced sync setting dialog, and pre-selects either the
567      * "Sync everything" or the "Choose what to sync" drop-down menu item.
568      * @param {cr.DataTypeSelection} index Index of item to pre-select.
569      * @private
570      */
571     showCustomizePage_: function(args, index) {
572       // Determine whether to bring the OK button field into focus.
573       var wasCustomizePageHidden = !this.customizePageVisible_;
574       this.customizePageVisible_ = true;
575       this.confirmPageVisible_ = false;
577       $('confirm-sync-preferences').hidden = true;
578       $('customize-sync-preferences').hidden = false;
580       $('sync-custom-passphrase-container').hidden = false;
581       $('sync-new-encryption-section-container').hidden = false;
582       $('customize-sync-encryption-new').hidden = false;
584       $('sync-existing-passphrase-container').hidden = true;
586       $('sync-select-datatypes').selectedIndex = index;
587       this.setDataTypeCheckboxesEnabled_(
588           index == DataTypeSelection.CHOOSE_WHAT_TO_SYNC);
590       // Give the OK button focus only when the dialog wasn't already visible.
591       if (wasCustomizePageHidden)
592         $('choose-datatypes-ok').focus();
594       if (args && args.showPassphrase) {
595         this.showPassphraseContainer_(args);
596         // Give the passphrase field focus only when the dialog wasn't already
597         // visible.
598         if (wasCustomizePageHidden)
599           $('passphrase').focus();
600       } else {
601         // We only show the 'Use Default' link if we're not prompting for an
602         // existing passphrase.
603         $('use-default-link').hidden = false;
604         $('use-default-link').disabled = false;
605         $('use-default-link').onclick = function() {
606           SyncSetupOverlay.showSyncEverythingPage();
607           return false;
608         };
609       }
610     },
612     /**
613      * Shows the appropriate sync setup page.
614      * @param {string} page A page of the sync setup to show.
615      * @param {object} args Data from the C++ to forward on to the right
616      *     section.
617      */
618     showSyncSetupPage_: function(page, args) {
619       // If the user clicks the OK button, dismiss the dialog immediately, and
620       // do not go through the process of hiding elements of the overlay.
621       // See crbug.com/308873.
622       if (page == 'done') {
623         this.closeOverlay_();
624         return;
625       }
627       this.setThrobbersVisible_(false);
629       // Hide an existing visible overlay (ensuring the close button is not
630       // hidden).
631       var children = document.querySelectorAll(
632           '#sync-setup-overlay > *:not(.close-button)');
633       for (var i = 0; i < children.length; i++)
634         children[i].hidden = true;
636       this.setInputElementsDisabledState_(false);
638       // If new passphrase bodies are present, overwrite the existing ones.
639       if (args && args.enterPassphraseBody != undefined)
640         $('normal-body').innerHTML = args.enterPassphraseBody;
641       if (args && args.enterGooglePassphraseBody != undefined) {
642         $('google-passphrase-needed-body').innerHTML =
643             args.enterGooglePassphraseBody;
644       }
645       if (args && args.fullEncryptionBody != undefined)
646         $('full-encryption-body').innerHTML = args.fullEncryptionBody;
648       // NOTE: Because both showGaiaLogin_() and showConfigure_() change the
649       // focus, we need to ensure that the overlay container and dialog aren't
650       // [hidden] (as trying to focus() nodes inside of a [hidden] DOM section
651       // doesn't work).
652       this.showOverlay_();
654       if (page == 'configure' || page == 'passphrase')
655         this.showConfigure_(args);
656       else if (page == 'spinner')
657         this.showSpinner_();
658       else if (page == 'timeout')
659         this.showTimeoutPage_();
660     },
662     /**
663      * Changes the visibility of throbbers on this page.
664      * @param {boolean} visible Whether or not to set all throbber nodes
665      *     visible.
666      */
667     setThrobbersVisible_: function(visible) {
668       var throbbers = this.pageDiv.getElementsByClassName('throbber');
669       for (var i = 0; i < throbbers.length; i++)
670         throbbers[i].style.visibility = visible ? 'visible' : 'hidden';
671     },
673     /**
674      * Reset the state of all descendant elements of a root element to their
675      * initial state.
676      * The initial state is specified by adding a class to the descendant
677      * element in sync_setup_overlay.html.
678      * @param {HTMLElement} pageElementId The root page element id.
679      * @private
680      */
681     resetPage_: function(pageElementId) {
682       var page = $(pageElementId);
683       var forEach = function(arr, fn) {
684         var length = arr.length;
685         for (var i = 0; i < length; i++) {
686           fn(arr[i]);
687         }
688       };
690       forEach(page.getElementsByClassName('reset-hidden'),
691           function(elt) { elt.hidden = true; });
692       forEach(page.getElementsByClassName('reset-shown'),
693           function(elt) { elt.hidden = false; });
694       forEach(page.getElementsByClassName('reset-disabled'),
695           function(elt) { elt.disabled = true; });
696       forEach(page.getElementsByClassName('reset-enabled'),
697           function(elt) { elt.disabled = false; });
698       forEach(page.getElementsByClassName('reset-value'),
699           function(elt) { elt.value = ''; });
700       forEach(page.getElementsByClassName('reset-opaque'),
701           function(elt) { elt.classList.remove('transparent'); });
702     },
704     /**
705      * Displays the stop syncing dialog.
706      * @private
707      */
708     showStopSyncingUI_: function() {
709       // Hide any visible children of the overlay.
710       var overlay = $('sync-setup-overlay');
711       for (var i = 0; i < overlay.children.length; i++)
712         overlay.children[i].hidden = true;
714       // Bypass OptionsPage.navigateToPage because it will call didShowPage
715       // which will set its own visible page, based on the flow state.
716       this.visible = true;
718       $('sync-setup-stop-syncing').hidden = false;
719       $('stop-syncing-cancel').focus();
720     },
722     /**
723      * Determines the appropriate page to show in the Sync Setup UI based on
724      * the state of the Sync backend. Does nothing if the user is not signed in.
725      * @private
726      */
727     showSetupUI_: function() {
728       chrome.send('SyncSetupShowSetupUI');
729     },
731     /**
732      * Starts the signin process for the user. Does nothing if the user is
733      * already signed in.
734      * @private
735      */
736     startSignIn_: function() {
737       chrome.send('SyncSetupStartSignIn');
738     },
740     /**
741      * Forces user to sign out of Chrome for Chrome OS.
742      * @private
743      */
744     doSignOutOnAuthError_: function() {
745       chrome.send('SyncSetupDoSignOutOnAuthError');
746     },
747   };
749   // These methods are for general consumption.
750   SyncSetupOverlay.closeOverlay = function() {
751     SyncSetupOverlay.getInstance().closeOverlay_();
752   };
754   SyncSetupOverlay.showSetupUI = function() {
755     SyncSetupOverlay.getInstance().showSetupUI_();
756   };
758   SyncSetupOverlay.startSignIn = function() {
759     SyncSetupOverlay.getInstance().startSignIn_();
760   };
762   SyncSetupOverlay.doSignOutOnAuthError = function() {
763     SyncSetupOverlay.getInstance().doSignOutOnAuthError_();
764   };
766   SyncSetupOverlay.showSyncSetupPage = function(page, args) {
767     SyncSetupOverlay.getInstance().showSyncSetupPage_(page, args);
768   };
770   SyncSetupOverlay.showCustomizePage = function(args, index) {
771     SyncSetupOverlay.getInstance().showCustomizePage_(args, index);
772   };
774   SyncSetupOverlay.showSyncEverythingPage = function() {
775     SyncSetupOverlay.getInstance().showSyncEverythingPage_();
776   };
778   SyncSetupOverlay.showStopSyncingUI = function() {
779     SyncSetupOverlay.getInstance().showStopSyncingUI_();
780   };
782   // Export
783   return {
784     SyncSetupOverlay: SyncSetupOverlay
785   };