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