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