sync_setup_overlay.js revision 3240926e260ce088908e02ac07a6cf7b0c0cbf44
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 $('use-default-link').hidden = true; 255 $('use-default-link').disabled = true; 256 $('use-default-link').onclick = null; 257 258 // These values need to be kept in sync with where they are read in 259 // SyncSetupFlow::GetDataTypeChoiceData(). 260 var syncAll = $('sync-select-datatypes').selectedIndex == 261 DataTypeSelection.SYNC_EVERYTHING; 262 var syncNothing = $('sync-select-datatypes').selectedIndex == 263 DataTypeSelection.SYNC_NOTHING; 264 var result = JSON.stringify({ 265 'syncAllDataTypes': syncAll, 266 'syncNothing': syncNothing, 267 'bookmarksSynced': syncAll || $('bookmarks-checkbox').checked, 268 'preferencesSynced': syncAll || $('preferences-checkbox').checked, 269 'themesSynced': syncAll || $('themes-checkbox').checked, 270 'passwordsSynced': syncAll || $('passwords-checkbox').checked, 271 'autofillSynced': syncAll || $('autofill-checkbox').checked, 272 'extensionsSynced': syncAll || $('extensions-checkbox').checked, 273 'typedUrlsSynced': syncAll || $('typed-urls-checkbox').checked, 274 'appsSynced': syncAll || $('apps-checkbox').checked, 275 'tabsSynced': syncAll || $('tabs-checkbox').checked, 276 'encryptAllData': encryptAllData, 277 'usePassphrase': usePassphrase, 278 'isGooglePassphrase': googlePassphrase, 279 'passphrase': customPassphrase 280 }); 281 chrome.send('SyncSetupConfigure', [result]); 282 }, 283 284 /** 285 * Sets the disabled property of all input elements within the 'Customize 286 * Sync Preferences' screen. This is used to prohibit the user from changing 287 * the inputs after confirming the customized sync preferences, or resetting 288 * the state when re-showing the dialog. 289 * @param {boolean} disabled True if controls should be set to disabled. 290 * @private 291 */ 292 setInputElementsDisabledState_: function(disabled) { 293 var configureElements = 294 $('customize-sync-preferences').querySelectorAll('input'); 295 for (var i = 0; i < configureElements.length; i++) 296 configureElements[i].disabled = disabled; 297 $('sync-select-datatypes').disabled = disabled; 298 299 $('customize-link').hidden = disabled; 300 $('customize-link').disabled = disabled; 301 $('customize-link').onclick = (disabled ? null : function() { 302 SyncSetupOverlay.showCustomizePage(null, 303 DataTypeSelection.SYNC_EVERYTHING); 304 return false; 305 }); 306 }, 307 308 /** 309 * Shows or hides the sync data type checkboxes in the advanced sync 310 * settings dialog. Also initializes |dataTypeBoxes_| with their values, and 311 * makes their onclick handlers update |dataTypeBoxes_|. 312 * @param {Object} args The configuration data used to show/hide UI. 313 * @private 314 */ 315 setChooseDataTypesCheckboxes_: function(args) { 316 var datatypeSelect = $('sync-select-datatypes'); 317 datatypeSelect.selectedIndex = args.syncAllDataTypes ? 318 DataTypeSelection.SYNC_EVERYTHING : 319 DataTypeSelection.CHOOSE_WHAT_TO_SYNC; 320 321 $('bookmarks-checkbox').checked = args.bookmarksSynced; 322 dataTypeBoxes_['bookmarks-checkbox'] = args.bookmarksSynced; 323 $('bookmarks-checkbox').onclick = this.handleDataTypeClick_; 324 325 $('preferences-checkbox').checked = args.preferencesSynced; 326 dataTypeBoxes_['preferences-checkbox'] = args.preferencesSynced; 327 $('preferences-checkbox').onclick = this.handleDataTypeClick_; 328 329 $('themes-checkbox').checked = args.themesSynced; 330 dataTypeBoxes_['themes-checkbox'] = args.themesSynced; 331 $('themes-checkbox').onclick = this.handleDataTypeClick_; 332 333 if (args.passwordsRegistered) { 334 $('passwords-checkbox').checked = args.passwordsSynced; 335 dataTypeBoxes_['passwords-checkbox'] = args.passwordsSynced; 336 $('passwords-checkbox').onclick = this.handleDataTypeClick_; 337 $('passwords-item').hidden = false; 338 } else { 339 $('passwords-item').hidden = true; 340 } 341 if (args.autofillRegistered) { 342 $('autofill-checkbox').checked = args.autofillSynced; 343 dataTypeBoxes_['autofill-checkbox'] = args.autofillSynced; 344 $('autofill-checkbox').onclick = this.handleDataTypeClick_; 345 $('autofill-item').hidden = false; 346 } else { 347 $('autofill-item').hidden = true; 348 } 349 if (args.extensionsRegistered) { 350 $('extensions-checkbox').checked = args.extensionsSynced; 351 dataTypeBoxes_['extensions-checkbox'] = args.extensionsSynced; 352 $('extensions-checkbox').onclick = this.handleDataTypeClick_; 353 $('extensions-item').hidden = false; 354 } else { 355 $('extensions-item').hidden = true; 356 } 357 if (args.typedUrlsRegistered) { 358 $('typed-urls-checkbox').checked = args.typedUrlsSynced; 359 dataTypeBoxes_['typed-urls-checkbox'] = args.typedUrlsSynced; 360 $('typed-urls-checkbox').onclick = this.handleDataTypeClick_; 361 $('omnibox-item').hidden = false; 362 } else { 363 $('omnibox-item').hidden = true; 364 } 365 if (args.appsRegistered) { 366 $('apps-checkbox').checked = args.appsSynced; 367 dataTypeBoxes_['apps-checkbox'] = args.appsSynced; 368 $('apps-checkbox').onclick = this.handleDataTypeClick_; 369 $('apps-item').hidden = false; 370 } else { 371 $('apps-item').hidden = true; 372 } 373 if (args.tabsRegistered) { 374 $('tabs-checkbox').checked = args.tabsSynced; 375 dataTypeBoxes_['tabs-checkbox'] = args.tabsSynced; 376 $('tabs-checkbox').onclick = this.handleDataTypeClick_; 377 $('tabs-item').hidden = false; 378 } else { 379 $('tabs-item').hidden = true; 380 } 381 382 this.setDataTypeCheckboxes_(datatypeSelect.selectedIndex); 383 }, 384 385 /** 386 * Updates the cached values of the sync data type checkboxes stored in 387 * |dataTypeBoxes_|. Used as an onclick handler for each data type checkbox. 388 * @private 389 */ 390 handleDataTypeClick_: function() { 391 dataTypeBoxes_[this.id] = this.checked; 392 }, 393 394 setEncryptionRadios_: function(args) { 395 if (!args.encryptAllData && !args.usePassphrase) { 396 $('basic-encryption-option').checked = true; 397 } else { 398 $('full-encryption-option').checked = true; 399 $('full-encryption-option').disabled = true; 400 $('basic-encryption-option').disabled = true; 401 } 402 }, 403 404 setCheckboxesAndErrors_: function(args) { 405 this.setChooseDataTypesCheckboxes_(args); 406 this.setEncryptionRadios_(args); 407 }, 408 409 showConfigure_: function(args) { 410 var datatypeSelect = $('sync-select-datatypes'); 411 var self = this; 412 413 // Cache the sync config args so they can be reused when we transition 414 // between the drop-down menu items in the advanced settings dialog. 415 if (args) 416 this.syncConfigureArgs_ = args; 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. 456 this.usePassphrase_ = args.usePassphrase; 457 if (args.showSyncEverythingPage == false || this.usePassphrase_ || 458 args.syncAllDataTypes == false || args.showPassphrase) { 459 var index = args.syncAllDataTypes ? 460 DataTypeSelection.SYNC_EVERYTHING : 461 DataTypeSelection.CHOOSE_WHAT_TO_SYNC; 462 this.showCustomizePage_(args, index); 463 } else { 464 this.showSyncEverythingPage_(); 465 } 466 } 467 }, 468 469 showSpinner_: function() { 470 this.resetPage_('sync-setup-spinner'); 471 $('sync-setup-spinner').hidden = false; 472 }, 473 474 showTimeoutPage_: function() { 475 this.resetPage_('sync-setup-timeout'); 476 $('sync-setup-timeout').hidden = false; 477 }, 478 479 showSyncEverythingPage_: function() { 480 $('confirm-sync-preferences').hidden = false; 481 $('customize-sync-preferences').hidden = true; 482 483 // Reset the selection to 'Sync everything'. 484 $('sync-select-datatypes').selectedIndex = 0; 485 486 // The default state is to sync everything. 487 this.setDataTypeCheckboxes_(DataTypeSelection.SYNC_EVERYTHING); 488 489 if (!this.usePassphrase_) 490 $('sync-custom-passphrase').hidden = true; 491 492 if (!this.useEncryptEverything_ && !this.usePassphrase_) 493 $('basic-encryption-option').checked = true; 494 495 $('confirm-everything-ok').focus(); 496 }, 497 498 /** 499 * Reveals the UI for when the user chooses not to sync any data types. 500 * This happens when the user signs in and selects "Sync nothing" in the 501 * advanced sync settings dialog. 502 * @private 503 */ 504 showSyncNothingPage_: function() { 505 // Reset the selection to 'Sync nothing'. 506 $('sync-select-datatypes').selectedIndex = DataTypeSelection.SYNC_NOTHING; 507 508 // Uncheck and disable the individual data type checkboxes. 509 this.checkAllDataTypeCheckboxes_(false); 510 this.setDataTypeCheckboxesEnabled_(false); 511 512 // Hide the encryption section. 513 $('customize-sync-encryption-new').hidden = true; 514 $('sync-custom-passphrase-container').hidden = true; 515 $('sync-existing-passphrase-container').hidden = true; 516 517 // Hide the "use default settings" link. 518 $('use-default-link').hidden = true; 519 $('use-default-link').disabled = true; 520 $('use-default-link').onclick = null; 521 }, 522 523 /** 524 * Reveals the UI for entering a custom passphrase during initial setup. 525 * This happens if the user has previously enabled a custom passphrase on a 526 * different machine. 527 * @param {Array} args The args that contain the passphrase UI 528 * configuration. 529 * @private 530 */ 531 showPassphraseContainer_: function(args) { 532 // Once we require a passphrase, we prevent the user from returning to 533 // the Sync Everything pane. 534 $('use-default-link').hidden = true; 535 $('use-default-link').disabled = true; 536 $('use-default-link').onclick = null; 537 $('sync-custom-passphrase-container').hidden = true; 538 $('sync-existing-passphrase-container').hidden = false; 539 540 // Hide the selection options within the new encryption section when 541 // prompting for a passphrase. 542 $('sync-new-encryption-section-container').hidden = true; 543 544 $('normal-body').hidden = true; 545 $('google-passphrase-needed-body').hidden = true; 546 // Display the correct prompt to the user depending on what type of 547 // passphrase is needed. 548 if (args.usePassphrase) 549 $('normal-body').hidden = false; 550 else 551 $('google-passphrase-needed-body').hidden = false; 552 553 $('passphrase-learn-more').hidden = false; 554 // Warn the user about their incorrect passphrase if we need a passphrase 555 // and the passphrase field is non-empty (meaning they tried to set it 556 // previously but failed). 557 $('incorrect-passphrase').hidden = 558 !(args.usePassphrase && args.passphraseFailed); 559 560 $('sync-passphrase-warning').hidden = false; 561 $('passphrase').focus(); 562 }, 563 564 /** 565 * Displays the advanced sync setting dialog, and pre-selects either the 566 * "Sync everything" or the "Choose what to sync" drop-down menu item. 567 * @param {cr.DataTypeSelection} index Index of item to pre-select. 568 * @private 569 */ 570 showCustomizePage_: function(args, index) { 571 $('confirm-sync-preferences').hidden = true; 572 $('customize-sync-preferences').hidden = false; 573 574 $('sync-custom-passphrase-container').hidden = false; 575 $('sync-custom-passphrase').hidden = true; 576 $('sync-new-encryption-section-container').hidden = false; 577 $('customize-sync-encryption-new').hidden = false; 578 579 $('sync-existing-passphrase-container').hidden = true; 580 581 $('sync-select-datatypes').selectedIndex = index; 582 this.setDataTypeCheckboxesEnabled_( 583 index == DataTypeSelection.CHOOSE_WHAT_TO_SYNC); 584 585 // The passphrase input may need to take over focus from the OK button, so 586 // set focus before that logic. 587 $('choose-datatypes-ok').focus(); 588 589 if (args && args.showPassphrase) { 590 this.showPassphraseContainer_(args); 591 } else { 592 // We only show the 'Use Default' link if we're not prompting for an 593 // existing passphrase. 594 $('use-default-link').hidden = false; 595 $('use-default-link').disabled = false; 596 $('use-default-link').onclick = function() { 597 SyncSetupOverlay.showSyncEverythingPage(); 598 return false; 599 }; 600 } 601 }, 602 603 /** 604 * Shows the appropriate sync setup page. 605 * @param {string} page A page of the sync setup to show. 606 * @param {object} args Data from the C++ to forward on to the right 607 * section. 608 */ 609 showSyncSetupPage_: function(page, args) { 610 this.setThrobbersVisible_(false); 611 612 // Hide an existing visible overlay (ensuring the close button is not 613 // hidden). 614 var children = document.querySelectorAll( 615 '#sync-setup-overlay > *:not(.close-button)'); 616 for (var i = 0; i < children.length; i++) 617 children[i].hidden = true; 618 619 this.setInputElementsDisabledState_(false); 620 621 // If new passphrase bodies are present, overwrite the existing ones. 622 if (args && args.enterPassphraseBody != undefined) 623 $('normal-body').innerHTML = args.enterPassphraseBody; 624 if (args && args.enterGooglePassphraseBody != undefined) { 625 $('google-passphrase-needed-body').innerHTML = 626 args.enterGooglePassphraseBody; 627 } 628 if (args && args.fullEncryptionBody != undefined) 629 $('full-encryption-body').innerHTML = args.fullEncryptionBody; 630 631 // NOTE: Because both showGaiaLogin_() and showConfigure_() change the 632 // focus, we need to ensure that the overlay container and dialog aren't 633 // [hidden] (as trying to focus() nodes inside of a [hidden] DOM section 634 // doesn't work). 635 if (page == 'done') 636 this.closeOverlay_(); 637 else 638 this.showOverlay_(); 639 640 if (page == 'configure' || page == 'passphrase') 641 this.showConfigure_(args); 642 else if (page == 'spinner') 643 this.showSpinner_(); 644 else if (page == 'timeout') 645 this.showTimeoutPage_(); 646 }, 647 648 /** 649 * Changes the visibility of throbbers on this page. 650 * @param {boolean} visible Whether or not to set all throbber nodes 651 * visible. 652 */ 653 setThrobbersVisible_: function(visible) { 654 var throbbers = this.pageDiv.getElementsByClassName('throbber'); 655 for (var i = 0; i < throbbers.length; i++) 656 throbbers[i].style.visibility = visible ? 'visible' : 'hidden'; 657 }, 658 659 /** 660 * Reset the state of all descendant elements of a root element to their 661 * initial state. 662 * The initial state is specified by adding a class to the descendant 663 * element in sync_setup_overlay.html. 664 * @param {HTMLElement} pageElementId The root page element id. 665 * @private 666 */ 667 resetPage_: function(pageElementId) { 668 var page = $(pageElementId); 669 var forEach = function(arr, fn) { 670 var length = arr.length; 671 for (var i = 0; i < length; i++) { 672 fn(arr[i]); 673 } 674 }; 675 676 forEach(page.getElementsByClassName('reset-hidden'), 677 function(elt) { elt.hidden = true; }); 678 forEach(page.getElementsByClassName('reset-shown'), 679 function(elt) { elt.hidden = false; }); 680 forEach(page.getElementsByClassName('reset-disabled'), 681 function(elt) { elt.disabled = true; }); 682 forEach(page.getElementsByClassName('reset-enabled'), 683 function(elt) { elt.disabled = false; }); 684 forEach(page.getElementsByClassName('reset-value'), 685 function(elt) { elt.value = ''; }); 686 forEach(page.getElementsByClassName('reset-opaque'), 687 function(elt) { elt.classList.remove('transparent'); }); 688 }, 689 690 /** 691 * Displays the stop syncing dialog. 692 * @private 693 */ 694 showStopSyncingUI_: function() { 695 // Hide any visible children of the overlay. 696 var overlay = $('sync-setup-overlay'); 697 for (var i = 0; i < overlay.children.length; i++) 698 overlay.children[i].hidden = true; 699 700 // Bypass OptionsPage.navigateToPage because it will call didShowPage 701 // which will set its own visible page, based on the flow state. 702 this.visible = true; 703 704 $('sync-setup-stop-syncing').hidden = false; 705 $('stop-syncing-cancel').focus(); 706 }, 707 708 /** 709 * Determines the appropriate page to show in the Sync Setup UI based on 710 * the state of the Sync backend. Does nothing if the user is not signed in. 711 * @private 712 */ 713 showSetupUI_: function() { 714 chrome.send('SyncSetupShowSetupUI'); 715 }, 716 717 /** 718 * Starts the signin process for the user. Does nothing if the user is 719 * already signed in. 720 * @private 721 */ 722 startSignIn_: function() { 723 chrome.send('SyncSetupStartSignIn'); 724 }, 725 726 /** 727 * Forces user to sign out of Chrome for Chrome OS. 728 * @private 729 */ 730 doSignOutOnAuthError_: function() { 731 chrome.send('SyncSetupDoSignOutOnAuthError'); 732 }, 733 }; 734 735 // These methods are for general consumption. 736 SyncSetupOverlay.closeOverlay = function() { 737 SyncSetupOverlay.getInstance().closeOverlay_(); 738 }; 739 740 SyncSetupOverlay.showSetupUI = function() { 741 SyncSetupOverlay.getInstance().showSetupUI_(); 742 }; 743 744 SyncSetupOverlay.startSignIn = function() { 745 SyncSetupOverlay.getInstance().startSignIn_(); 746 }; 747 748 SyncSetupOverlay.doSignOutOnAuthError = function() { 749 SyncSetupOverlay.getInstance().doSignOutOnAuthError_(); 750 }; 751 752 SyncSetupOverlay.showSyncSetupPage = function(page, args) { 753 SyncSetupOverlay.getInstance().showSyncSetupPage_(page, args); 754 }; 755 756 SyncSetupOverlay.showCustomizePage = function(args, index) { 757 SyncSetupOverlay.getInstance().showCustomizePage_(args, index); 758 }; 759 760 SyncSetupOverlay.showSyncEverythingPage = function() { 761 SyncSetupOverlay.getInstance().showSyncEverythingPage_(); 762 }; 763 764 SyncSetupOverlay.showStopSyncingUI = function() { 765 SyncSetupOverlay.getInstance().showStopSyncingUI_(); 766 }; 767 768 // Export 769 return { 770 SyncSetupOverlay: SyncSetupOverlay 771 }; 772}); 773