sync_setup_overlay.js revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
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. 4 5cr.define('options', function() { 6 /** @const */ var OptionsPage = options.OptionsPage; 7 8 // True if the synced account uses a custom passphrase. 9 var usePassphrase_ = false; 10 11 // True if the synced account uses 'encrypt everything'. 12 var useEncryptEverything_ = false; 13 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; 18 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_ = {}; 28 29 /** 30 * The user's selection in the synced data type drop-down menu, as an index. 31 * @enum {number} 32 * @const 33 */ 34 var DataTypeSelection = { 35 SYNC_EVERYTHING: 0, 36 CHOOSE_WHAT_TO_SYNC: 1, 37 SYNC_NOTHING: 2 38 }; 39 40 /** 41 * SyncSetupOverlay class 42 * Encapsulated handling of the 'Sync Setup' overlay page. 43 * @class 44 */ 45 function SyncSetupOverlay() { 46 OptionsPage.call(this, 'syncSetup', 47 loadTimeData.getString('syncSetupOverlayTabTitle'), 48 'sync-setup-overlay'); 49 } 50 51 cr.addSingletonGetter(SyncSetupOverlay); 52 53 SyncSetupOverlay.prototype = { 54 __proto__: OptionsPage.prototype, 55 56 /** 57 * Initializes the page. 58 */ 59 initializePage: function() { 60 OptionsPage.prototype.initializePage.call(this); 61 62 var self = this; 63 $('basic-encryption-option').onchange = 64 $('full-encryption-option').onchange = function() { 65 self.onEncryptionRadioChanged_(); 66 } 67 $('choose-datatypes-cancel').onclick = 68 $('confirm-everything-cancel').onclick = 69 $('stop-syncing-cancel').onclick = 70 $('sync-spinner-cancel').onclick = function() { 71 self.closeOverlay_(); 72 }; 73 $('confirm-everything-ok').onclick = function() { 74 self.sendConfiguration_(); 75 }; 76 $('timeout-ok').onclick = function() { 77 chrome.send('CloseTimeout'); 78 self.closeOverlay_(); 79 }; 80 $('stop-syncing-ok').onclick = function() { 81 chrome.send('SyncSetupStopSyncing'); 82 self.closeOverlay_(); 83 }; 84 }, 85 86 showOverlay_: function() { 87 OptionsPage.navigateToPage('syncSetup'); 88 }, 89 90 closeOverlay_: function() { 91 this.syncConfigureArgs_ = null; 92 this.dataTypeBoxes_ = {}; 93 94 // Required in order to determine whether to give focus to the OK button 95 // or passphrase field. See crbug.com/279770. 96 $('confirm-sync-preferences').hidden = true; 97 $('customize-sync-preferences').hidden = true; 98 99 var overlay = $('sync-setup-overlay'); 100 if (!overlay.hidden) 101 OptionsPage.closeOverlay(); 102 }, 103 104 /** @override */ 105 didShowPage: function() { 106 chrome.send('SyncSetupShowSetupUI'); 107 }, 108 109 /** @override */ 110 didClosePage: function() { 111 chrome.send('SyncSetupDidClosePage'); 112 }, 113 114 onEncryptionRadioChanged_: function() { 115 var visible = $('full-encryption-option').checked; 116 $('sync-custom-passphrase').hidden = !visible; 117 }, 118 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 }, 134 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 }, 151 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 }, 164 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 }, 182 183 // Returns true if none of the visible checkboxes are checked. 184 noDataTypesChecked_: function() { 185 var query = '.sync-type-checkbox:not([hidden]) input:checked'; 186 var checkboxes = $('choose-data-types-body').querySelectorAll(query); 187 return checkboxes.length == 0; 188 }, 189 190 checkPassphraseMatch_: function() { 191 var emptyError = $('empty-error'); 192 var mismatchError = $('mismatch-error'); 193 emptyError.hidden = true; 194 mismatchError.hidden = true; 195 196 var f = $('choose-data-types-form'); 197 if (!$('full-encryption-option').checked || 198 $('basic-encryption-option').disabled) { 199 return true; 200 } 201 202 var customPassphrase = $('custom-passphrase'); 203 if (customPassphrase.value.length == 0) { 204 emptyError.hidden = false; 205 return false; 206 } 207 208 var confirmPassphrase = $('confirm-passphrase'); 209 if (confirmPassphrase.value != customPassphrase.value) { 210 mismatchError.hidden = false; 211 return false; 212 } 213 214 return true; 215 }, 216 217 sendConfiguration_: function() { 218 // Trying to submit, so hide previous errors. 219 $('error-text').hidden = true; 220 221 var chooseWhatToSync = $('sync-select-datatypes').selectedIndex == 222 DataTypeSelection.CHOOSE_WHAT_TO_SYNC; 223 if (chooseWhatToSync && this.noDataTypesChecked_()) { 224 $('error-text').hidden = false; 225 return; 226 } 227 228 var encryptAllData = $('full-encryption-option').checked; 229 230 var usePassphrase; 231 var customPassphrase; 232 var googlePassphrase = false; 233 if (!$('sync-existing-passphrase-container').hidden) { 234 // If we were prompted for an existing passphrase, use it. 235 customPassphrase = $('choose-data-types-form').passphrase.value; 236 usePassphrase = true; 237 // If we were displaying the 'enter your old google password' prompt, 238 // then that means this is the user's google password. 239 googlePassphrase = !$('google-passphrase-needed-body').hidden; 240 // We allow an empty passphrase, in case the user has disabled 241 // all their encrypted datatypes. In that case, the PSS will accept 242 // the passphrase and finish configuration. If the user has enabled 243 // encrypted datatypes, the PSS will prompt again specifying that the 244 // passphrase failed. 245 } else if (!$('basic-encryption-option').disabled && 246 $('full-encryption-option').checked) { 247 // The user is setting a custom passphrase for the first time. 248 if (!this.checkPassphraseMatch_()) 249 return; 250 customPassphrase = $('custom-passphrase').value; 251 usePassphrase = true; 252 } else { 253 // The user is not setting a custom passphrase. 254 usePassphrase = false; 255 } 256 257 // Don't allow the user to tweak the settings once we send the 258 // configuration to the backend. 259 this.setInputElementsDisabledState_(true); 260 $('use-default-link').hidden = true; 261 $('use-default-link').disabled = true; 262 $('use-default-link').onclick = null; 263 264 // These values need to be kept in sync with where they are read in 265 // SyncSetupFlow::GetDataTypeChoiceData(). 266 var syncAll = $('sync-select-datatypes').selectedIndex == 267 DataTypeSelection.SYNC_EVERYTHING; 268 var syncNothing = $('sync-select-datatypes').selectedIndex == 269 DataTypeSelection.SYNC_NOTHING; 270 var result = JSON.stringify({ 271 'syncAllDataTypes': syncAll, 272 'syncNothing': syncNothing, 273 'bookmarksSynced': syncAll || $('bookmarks-checkbox').checked, 274 'preferencesSynced': syncAll || $('preferences-checkbox').checked, 275 'themesSynced': syncAll || $('themes-checkbox').checked, 276 'passwordsSynced': syncAll || $('passwords-checkbox').checked, 277 'autofillSynced': syncAll || $('autofill-checkbox').checked, 278 'extensionsSynced': syncAll || $('extensions-checkbox').checked, 279 'typedUrlsSynced': syncAll || $('typed-urls-checkbox').checked, 280 'appsSynced': syncAll || $('apps-checkbox').checked, 281 'tabsSynced': syncAll || $('tabs-checkbox').checked, 282 'encryptAllData': encryptAllData, 283 'usePassphrase': usePassphrase, 284 'isGooglePassphrase': googlePassphrase, 285 'passphrase': customPassphrase 286 }); 287 chrome.send('SyncSetupConfigure', [result]); 288 }, 289 290 /** 291 * Sets the disabled property of all input elements within the 'Customize 292 * Sync Preferences' screen. This is used to prohibit the user from changing 293 * the inputs after confirming the customized sync preferences, or resetting 294 * the state when re-showing the dialog. 295 * @param {boolean} disabled True if controls should be set to disabled. 296 * @private 297 */ 298 setInputElementsDisabledState_: function(disabled) { 299 var configureElements = 300 $('customize-sync-preferences').querySelectorAll('input'); 301 for (var i = 0; i < configureElements.length; i++) 302 configureElements[i].disabled = disabled; 303 $('sync-select-datatypes').disabled = disabled; 304 305 $('customize-link').hidden = disabled; 306 $('customize-link').disabled = disabled; 307 $('customize-link').onclick = (disabled ? null : function() { 308 SyncSetupOverlay.showCustomizePage(null, 309 DataTypeSelection.SYNC_EVERYTHING); 310 return false; 311 }); 312 }, 313 314 /** 315 * Shows or hides the sync data type checkboxes in the advanced sync 316 * settings dialog. Also initializes |dataTypeBoxes_| with their values, and 317 * makes their onclick handlers update |dataTypeBoxes_|. 318 * @param {Object} args The configuration data used to show/hide UI. 319 * @private 320 */ 321 setChooseDataTypesCheckboxes_: function(args) { 322 var datatypeSelect = $('sync-select-datatypes'); 323 datatypeSelect.selectedIndex = args.syncAllDataTypes ? 324 DataTypeSelection.SYNC_EVERYTHING : 325 DataTypeSelection.CHOOSE_WHAT_TO_SYNC; 326 327 $('bookmarks-checkbox').checked = args.bookmarksSynced; 328 dataTypeBoxes_['bookmarks-checkbox'] = args.bookmarksSynced; 329 $('bookmarks-checkbox').onclick = this.handleDataTypeClick_; 330 331 $('preferences-checkbox').checked = args.preferencesSynced; 332 dataTypeBoxes_['preferences-checkbox'] = args.preferencesSynced; 333 $('preferences-checkbox').onclick = this.handleDataTypeClick_; 334 335 $('themes-checkbox').checked = args.themesSynced; 336 dataTypeBoxes_['themes-checkbox'] = args.themesSynced; 337 $('themes-checkbox').onclick = this.handleDataTypeClick_; 338 339 if (args.passwordsRegistered) { 340 $('passwords-checkbox').checked = args.passwordsSynced; 341 dataTypeBoxes_['passwords-checkbox'] = args.passwordsSynced; 342 $('passwords-checkbox').onclick = this.handleDataTypeClick_; 343 $('passwords-item').hidden = false; 344 } else { 345 $('passwords-item').hidden = true; 346 } 347 if (args.autofillRegistered) { 348 $('autofill-checkbox').checked = args.autofillSynced; 349 dataTypeBoxes_['autofill-checkbox'] = args.autofillSynced; 350 $('autofill-checkbox').onclick = this.handleDataTypeClick_; 351 $('autofill-item').hidden = false; 352 } else { 353 $('autofill-item').hidden = true; 354 } 355 if (args.extensionsRegistered) { 356 $('extensions-checkbox').checked = args.extensionsSynced; 357 dataTypeBoxes_['extensions-checkbox'] = args.extensionsSynced; 358 $('extensions-checkbox').onclick = this.handleDataTypeClick_; 359 $('extensions-item').hidden = false; 360 } else { 361 $('extensions-item').hidden = true; 362 } 363 if (args.typedUrlsRegistered) { 364 $('typed-urls-checkbox').checked = args.typedUrlsSynced; 365 dataTypeBoxes_['typed-urls-checkbox'] = args.typedUrlsSynced; 366 $('typed-urls-checkbox').onclick = this.handleDataTypeClick_; 367 $('omnibox-item').hidden = false; 368 } else { 369 $('omnibox-item').hidden = true; 370 } 371 if (args.appsRegistered) { 372 $('apps-checkbox').checked = args.appsSynced; 373 dataTypeBoxes_['apps-checkbox'] = args.appsSynced; 374 $('apps-checkbox').onclick = this.handleDataTypeClick_; 375 $('apps-item').hidden = false; 376 } else { 377 $('apps-item').hidden = true; 378 } 379 if (args.tabsRegistered) { 380 $('tabs-checkbox').checked = args.tabsSynced; 381 dataTypeBoxes_['tabs-checkbox'] = args.tabsSynced; 382 $('tabs-checkbox').onclick = this.handleDataTypeClick_; 383 $('tabs-item').hidden = false; 384 } else { 385 $('tabs-item').hidden = true; 386 } 387 388 this.setDataTypeCheckboxes_(datatypeSelect.selectedIndex); 389 }, 390 391 /** 392 * Updates the cached values of the sync data type checkboxes stored in 393 * |dataTypeBoxes_|. Used as an onclick handler for each data type checkbox. 394 * @private 395 */ 396 handleDataTypeClick_: function() { 397 dataTypeBoxes_[this.id] = this.checked; 398 }, 399 400 setEncryptionRadios_: function(args) { 401 if (!args.encryptAllData && !args.usePassphrase) { 402 $('basic-encryption-option').checked = true; 403 } else { 404 $('full-encryption-option').checked = true; 405 $('full-encryption-option').disabled = true; 406 $('basic-encryption-option').disabled = true; 407 } 408 }, 409 410 setCheckboxesAndErrors_: function(args) { 411 this.setChooseDataTypesCheckboxes_(args); 412 this.setEncryptionRadios_(args); 413 }, 414 415 showConfigure_: function(args) { 416 var datatypeSelect = $('sync-select-datatypes'); 417 var self = this; 418 419 // Cache the sync config args so they can be reused when we transition 420 // between the drop-down menu items in the advanced settings dialog. 421 if (args) 422 this.syncConfigureArgs_ = args; 423 424 // Once the advanced sync settings dialog is visible, we transition 425 // between its drop-down menu items as follows: 426 // "Sync everything": Show encryption and passphrase sections, and disable 427 // and check all data type checkboxes. 428 // "Sync nothing": Hide encryption and passphrase sections, and disable 429 // and uncheck all data type checkboxes. 430 // "Choose what to sync": Show encryption and passphrase sections, enable 431 // data type checkboxes, and restore their checked state to the last time 432 // the "Choose what to sync" was selected while the dialog was still up. 433 datatypeSelect.onchange = function() { 434 if (this.selectedIndex == DataTypeSelection.SYNC_NOTHING) { 435 self.showSyncNothingPage_(); 436 } else { 437 self.showCustomizePage_(self.syncConfigureArgs_, this.selectedIndex); 438 if (this.selectedIndex == DataTypeSelection.SYNC_EVERYTHING) 439 self.checkAllDataTypeCheckboxes_(true); 440 else 441 self.restoreDataTypeCheckboxes_(); 442 } 443 }; 444 445 this.resetPage_('sync-setup-configure'); 446 $('sync-setup-configure').hidden = false; 447 448 // onsubmit is changed when submitting a passphrase. Reset it to its 449 // default. 450 $('choose-data-types-form').onsubmit = function() { 451 self.sendConfiguration_(); 452 return false; 453 }; 454 455 if (args) { 456 this.setCheckboxesAndErrors_(args); 457 458 this.useEncryptEverything_ = args.encryptAllData; 459 460 // Determine whether to display the 'OK, sync everything' confirmation 461 // dialog or the advanced sync settings dialog, and assign focus to the 462 // OK button, or to the passphrase field if a passphrase is required. 463 this.usePassphrase_ = args.usePassphrase; 464 if (args.showSyncEverythingPage == false || this.usePassphrase_ || 465 args.syncAllDataTypes == false || args.showPassphrase) { 466 var index = args.syncAllDataTypes ? 467 DataTypeSelection.SYNC_EVERYTHING : 468 DataTypeSelection.CHOOSE_WHAT_TO_SYNC; 469 this.showCustomizePage_(args, index); 470 } else { 471 this.showSyncEverythingPage_(); 472 } 473 } 474 }, 475 476 showSpinner_: function() { 477 this.resetPage_('sync-setup-spinner'); 478 $('sync-setup-spinner').hidden = false; 479 }, 480 481 showTimeoutPage_: function() { 482 this.resetPage_('sync-setup-timeout'); 483 $('sync-setup-timeout').hidden = false; 484 }, 485 486 showSyncEverythingPage_: function() { 487 // Determine whether to bring the OK button into focus. 488 var wasConfirmPageHidden = $('confirm-sync-preferences').hidden; 489 490 $('confirm-sync-preferences').hidden = false; 491 $('customize-sync-preferences').hidden = true; 492 493 // Reset the selection to 'Sync everything'. 494 $('sync-select-datatypes').selectedIndex = 0; 495 496 // The default state is to sync everything. 497 this.setDataTypeCheckboxes_(DataTypeSelection.SYNC_EVERYTHING); 498 499 if (!this.usePassphrase_) 500 $('sync-custom-passphrase').hidden = true; 501 502 if (!this.useEncryptEverything_ && !this.usePassphrase_) 503 $('basic-encryption-option').checked = true; 504 505 // Give the OK button focus only when the dialog wasn't already visible. 506 if (wasConfirmPageHidden) 507 $('confirm-everything-ok').focus(); 508 }, 509 510 /** 511 * Reveals the UI for when the user chooses not to sync any data types. 512 * This happens when the user signs in and selects "Sync nothing" in the 513 * advanced sync settings dialog. 514 * @private 515 */ 516 showSyncNothingPage_: function() { 517 // Reset the selection to 'Sync nothing'. 518 $('sync-select-datatypes').selectedIndex = DataTypeSelection.SYNC_NOTHING; 519 520 // Uncheck and disable the individual data type checkboxes. 521 this.checkAllDataTypeCheckboxes_(false); 522 this.setDataTypeCheckboxesEnabled_(false); 523 524 // Hide the encryption section. 525 $('customize-sync-encryption-new').hidden = true; 526 $('sync-custom-passphrase-container').hidden = true; 527 $('sync-existing-passphrase-container').hidden = true; 528 529 // Hide the "use default settings" link. 530 $('use-default-link').hidden = true; 531 $('use-default-link').disabled = true; 532 $('use-default-link').onclick = null; 533 }, 534 535 /** 536 * Reveals the UI for entering a custom passphrase during initial setup. 537 * This happens if the user has previously enabled a custom passphrase on a 538 * different machine. 539 * @param {Array} args The args that contain the passphrase UI 540 * configuration. 541 * @private 542 */ 543 showPassphraseContainer_: function(args) { 544 // Once we require a passphrase, we prevent the user from returning to 545 // the Sync Everything pane. 546 $('use-default-link').hidden = true; 547 $('use-default-link').disabled = true; 548 $('use-default-link').onclick = null; 549 $('sync-custom-passphrase-container').hidden = true; 550 $('sync-existing-passphrase-container').hidden = false; 551 552 // Hide the selection options within the new encryption section when 553 // prompting for a passphrase. 554 $('sync-new-encryption-section-container').hidden = true; 555 556 $('normal-body').hidden = true; 557 $('google-passphrase-needed-body').hidden = true; 558 // Display the correct prompt to the user depending on what type of 559 // passphrase is needed. 560 if (args.usePassphrase) 561 $('normal-body').hidden = false; 562 else 563 $('google-passphrase-needed-body').hidden = false; 564 565 $('passphrase-learn-more').hidden = false; 566 // Warn the user about their incorrect passphrase if we need a passphrase 567 // and the passphrase field is non-empty (meaning they tried to set it 568 // previously but failed). 569 $('incorrect-passphrase').hidden = 570 !(args.usePassphrase && args.passphraseFailed); 571 572 $('sync-passphrase-warning').hidden = false; 573 }, 574 575 /** 576 * Displays the advanced sync setting dialog, and pre-selects either the 577 * "Sync everything" or the "Choose what to sync" drop-down menu item. 578 * @param {cr.DataTypeSelection} index Index of item to pre-select. 579 * @private 580 */ 581 showCustomizePage_: function(args, index) { 582 // Determine whether to bring the OK button field into focus. 583 var wasCustomizePageHidden = $('customize-sync-preferences').hidden; 584 585 $('confirm-sync-preferences').hidden = true; 586 $('customize-sync-preferences').hidden = false; 587 588 $('sync-custom-passphrase-container').hidden = false; 589 $('sync-new-encryption-section-container').hidden = false; 590 $('customize-sync-encryption-new').hidden = false; 591 592 $('sync-existing-passphrase-container').hidden = true; 593 594 $('sync-select-datatypes').selectedIndex = index; 595 this.setDataTypeCheckboxesEnabled_( 596 index == DataTypeSelection.CHOOSE_WHAT_TO_SYNC); 597 598 // Give the OK button focus only when the dialog wasn't already visible. 599 if (wasCustomizePageHidden) 600 $('choose-datatypes-ok').focus(); 601 602 if (args && args.showPassphrase) { 603 this.showPassphraseContainer_(args); 604 // Give the passphrase field focus only when the dialog wasn't already 605 // visible. 606 if (wasCustomizePageHidden) 607 $('passphrase').focus(); 608 } else { 609 // We only show the 'Use Default' link if we're not prompting for an 610 // existing passphrase. 611 $('use-default-link').hidden = false; 612 $('use-default-link').disabled = false; 613 $('use-default-link').onclick = function() { 614 SyncSetupOverlay.showSyncEverythingPage(); 615 return false; 616 }; 617 } 618 }, 619 620 /** 621 * Shows the appropriate sync setup page. 622 * @param {string} page A page of the sync setup to show. 623 * @param {object} args Data from the C++ to forward on to the right 624 * section. 625 */ 626 showSyncSetupPage_: function(page, args) { 627 this.setThrobbersVisible_(false); 628 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; 635 636 this.setInputElementsDisabledState_(false); 637 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; 647 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 if (page == 'done') 653 this.closeOverlay_(); 654 else 655 this.showOverlay_(); 656 657 if (page == 'configure' || page == 'passphrase') 658 this.showConfigure_(args); 659 else if (page == 'spinner') 660 this.showSpinner_(); 661 else if (page == 'timeout') 662 this.showTimeoutPage_(); 663 }, 664 665 /** 666 * Changes the visibility of throbbers on this page. 667 * @param {boolean} visible Whether or not to set all throbber nodes 668 * visible. 669 */ 670 setThrobbersVisible_: function(visible) { 671 var throbbers = this.pageDiv.getElementsByClassName('throbber'); 672 for (var i = 0; i < throbbers.length; i++) 673 throbbers[i].style.visibility = visible ? 'visible' : 'hidden'; 674 }, 675 676 /** 677 * Reset the state of all descendant elements of a root element to their 678 * initial state. 679 * The initial state is specified by adding a class to the descendant 680 * element in sync_setup_overlay.html. 681 * @param {HTMLElement} pageElementId The root page element id. 682 * @private 683 */ 684 resetPage_: function(pageElementId) { 685 var page = $(pageElementId); 686 var forEach = function(arr, fn) { 687 var length = arr.length; 688 for (var i = 0; i < length; i++) { 689 fn(arr[i]); 690 } 691 }; 692 693 forEach(page.getElementsByClassName('reset-hidden'), 694 function(elt) { elt.hidden = true; }); 695 forEach(page.getElementsByClassName('reset-shown'), 696 function(elt) { elt.hidden = false; }); 697 forEach(page.getElementsByClassName('reset-disabled'), 698 function(elt) { elt.disabled = true; }); 699 forEach(page.getElementsByClassName('reset-enabled'), 700 function(elt) { elt.disabled = false; }); 701 forEach(page.getElementsByClassName('reset-value'), 702 function(elt) { elt.value = ''; }); 703 forEach(page.getElementsByClassName('reset-opaque'), 704 function(elt) { elt.classList.remove('transparent'); }); 705 }, 706 707 /** 708 * Displays the stop syncing dialog. 709 * @private 710 */ 711 showStopSyncingUI_: function() { 712 // Hide any visible children of the overlay. 713 var overlay = $('sync-setup-overlay'); 714 for (var i = 0; i < overlay.children.length; i++) 715 overlay.children[i].hidden = true; 716 717 // Bypass OptionsPage.navigateToPage because it will call didShowPage 718 // which will set its own visible page, based on the flow state. 719 this.visible = true; 720 721 $('sync-setup-stop-syncing').hidden = false; 722 $('stop-syncing-cancel').focus(); 723 }, 724 725 /** 726 * Determines the appropriate page to show in the Sync Setup UI based on 727 * the state of the Sync backend. Does nothing if the user is not signed in. 728 * @private 729 */ 730 showSetupUI_: function() { 731 chrome.send('SyncSetupShowSetupUI'); 732 }, 733 734 /** 735 * Starts the signin process for the user. Does nothing if the user is 736 * already signed in. 737 * @private 738 */ 739 startSignIn_: function() { 740 chrome.send('SyncSetupStartSignIn'); 741 }, 742 743 /** 744 * Forces user to sign out of Chrome for Chrome OS. 745 * @private 746 */ 747 doSignOutOnAuthError_: function() { 748 chrome.send('SyncSetupDoSignOutOnAuthError'); 749 }, 750 }; 751 752 // These methods are for general consumption. 753 SyncSetupOverlay.closeOverlay = function() { 754 SyncSetupOverlay.getInstance().closeOverlay_(); 755 }; 756 757 SyncSetupOverlay.showSetupUI = function() { 758 SyncSetupOverlay.getInstance().showSetupUI_(); 759 }; 760 761 SyncSetupOverlay.startSignIn = function() { 762 SyncSetupOverlay.getInstance().startSignIn_(); 763 }; 764 765 SyncSetupOverlay.doSignOutOnAuthError = function() { 766 SyncSetupOverlay.getInstance().doSignOutOnAuthError_(); 767 }; 768 769 SyncSetupOverlay.showSyncSetupPage = function(page, args) { 770 SyncSetupOverlay.getInstance().showSyncSetupPage_(page, args); 771 }; 772 773 SyncSetupOverlay.showCustomizePage = function(args, index) { 774 SyncSetupOverlay.getInstance().showCustomizePage_(args, index); 775 }; 776 777 SyncSetupOverlay.showSyncEverythingPage = function() { 778 SyncSetupOverlay.getInstance().showSyncEverythingPage_(); 779 }; 780 781 SyncSetupOverlay.showStopSyncingUI = function() { 782 SyncSetupOverlay.getInstance().showStopSyncingUI_(); 783 }; 784 785 // Export 786 return { 787 SyncSetupOverlay: SyncSetupOverlay 788 }; 789}); 790