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 /** 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, 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 if (args.showPassphrase) 465 $('passphrase').focus(); 466 else 467 $('choose-datatypes-ok').focus(); 468 } else { 469 this.showSyncEverythingPage_(); 470 $('confirm-everything-ok').focus(); 471 } 472 } 473 }, 474 475 showSpinner_: function() { 476 this.resetPage_('sync-setup-spinner'); 477 $('sync-setup-spinner').hidden = false; 478 }, 479 480 showTimeoutPage_: function() { 481 this.resetPage_('sync-setup-timeout'); 482 $('sync-setup-timeout').hidden = false; 483 }, 484 485 showSyncEverythingPage_: function() { 486 $('confirm-sync-preferences').hidden = false; 487 $('customize-sync-preferences').hidden = true; 488 489 // Reset the selection to 'Sync everything'. 490 $('sync-select-datatypes').selectedIndex = 0; 491 492 // The default state is to sync everything. 493 this.setDataTypeCheckboxes_(DataTypeSelection.SYNC_EVERYTHING); 494 495 if (!this.usePassphrase_) 496 $('sync-custom-passphrase').hidden = true; 497 498 if (!this.useEncryptEverything_ && !this.usePassphrase_) 499 $('basic-encryption-option').checked = true; 500 }, 501 502 /** 503 * Reveals the UI for when the user chooses not to sync any data types. 504 * This happens when the user signs in and selects "Sync nothing" in the 505 * advanced sync settings dialog. 506 * @private 507 */ 508 showSyncNothingPage_: function() { 509 // Reset the selection to 'Sync nothing'. 510 $('sync-select-datatypes').selectedIndex = DataTypeSelection.SYNC_NOTHING; 511 512 // Uncheck and disable the individual data type checkboxes. 513 this.checkAllDataTypeCheckboxes_(false); 514 this.setDataTypeCheckboxesEnabled_(false); 515 516 // Hide the encryption section. 517 $('customize-sync-encryption-new').hidden = true; 518 $('sync-custom-passphrase-container').hidden = true; 519 $('sync-existing-passphrase-container').hidden = true; 520 521 // Hide the "use default settings" link. 522 $('use-default-link').hidden = true; 523 $('use-default-link').disabled = true; 524 $('use-default-link').onclick = null; 525 }, 526 527 /** 528 * Reveals the UI for entering a custom passphrase during initial setup. 529 * This happens if the user has previously enabled a custom passphrase on a 530 * different machine. 531 * @param {Array} args The args that contain the passphrase UI 532 * configuration. 533 * @private 534 */ 535 showPassphraseContainer_: function(args) { 536 // Once we require a passphrase, we prevent the user from returning to 537 // the Sync Everything pane. 538 $('use-default-link').hidden = true; 539 $('use-default-link').disabled = true; 540 $('use-default-link').onclick = null; 541 $('sync-custom-passphrase-container').hidden = true; 542 $('sync-existing-passphrase-container').hidden = false; 543 544 // Hide the selection options within the new encryption section when 545 // prompting for a passphrase. 546 $('sync-new-encryption-section-container').hidden = true; 547 548 $('normal-body').hidden = true; 549 $('google-passphrase-needed-body').hidden = true; 550 // Display the correct prompt to the user depending on what type of 551 // passphrase is needed. 552 if (args.usePassphrase) 553 $('normal-body').hidden = false; 554 else 555 $('google-passphrase-needed-body').hidden = false; 556 557 $('passphrase-learn-more').hidden = false; 558 // Warn the user about their incorrect passphrase if we need a passphrase 559 // and the passphrase field is non-empty (meaning they tried to set it 560 // previously but failed). 561 $('incorrect-passphrase').hidden = 562 !(args.usePassphrase && args.passphraseFailed); 563 564 $('sync-passphrase-warning').hidden = false; 565 }, 566 567 /** 568 * Displays the advanced sync setting dialog, and pre-selects either the 569 * "Sync everything" or the "Choose what to sync" drop-down menu item. 570 * @param {cr.DataTypeSelection} index Index of item to pre-select. 571 * @private 572 */ 573 showCustomizePage_: function(args, index) { 574 $('confirm-sync-preferences').hidden = true; 575 $('customize-sync-preferences').hidden = false; 576 577 $('sync-custom-passphrase-container').hidden = false; 578 $('sync-new-encryption-section-container').hidden = false; 579 $('customize-sync-encryption-new').hidden = false; 580 581 $('sync-existing-passphrase-container').hidden = true; 582 583 $('sync-select-datatypes').selectedIndex = index; 584 this.setDataTypeCheckboxesEnabled_( 585 index == DataTypeSelection.CHOOSE_WHAT_TO_SYNC); 586 587 if (args && args.showPassphrase) { 588 this.showPassphraseContainer_(args); 589 } else { 590 // We only show the 'Use Default' link if we're not prompting for an 591 // existing passphrase. 592 $('use-default-link').hidden = false; 593 $('use-default-link').disabled = false; 594 $('use-default-link').onclick = function() { 595 SyncSetupOverlay.showSyncEverythingPage(); 596 return false; 597 }; 598 } 599 }, 600 601 /** 602 * Shows the appropriate sync setup page. 603 * @param {string} page A page of the sync setup to show. 604 * @param {object} args Data from the C++ to forward on to the right 605 * section. 606 */ 607 showSyncSetupPage_: function(page, args) { 608 this.setThrobbersVisible_(false); 609 610 // Hide an existing visible overlay (ensuring the close button is not 611 // hidden). 612 var children = document.querySelectorAll( 613 '#sync-setup-overlay > *:not(.close-button)'); 614 for (var i = 0; i < children.length; i++) 615 children[i].hidden = true; 616 617 this.setInputElementsDisabledState_(false); 618 619 // If new passphrase bodies are present, overwrite the existing ones. 620 if (args && args.enterPassphraseBody != undefined) 621 $('normal-body').innerHTML = args.enterPassphraseBody; 622 if (args && args.enterGooglePassphraseBody != undefined) { 623 $('google-passphrase-needed-body').innerHTML = 624 args.enterGooglePassphraseBody; 625 } 626 if (args && args.fullEncryptionBody != undefined) 627 $('full-encryption-body').innerHTML = args.fullEncryptionBody; 628 629 // NOTE: Because both showGaiaLogin_() and showConfigure_() change the 630 // focus, we need to ensure that the overlay container and dialog aren't 631 // [hidden] (as trying to focus() nodes inside of a [hidden] DOM section 632 // doesn't work). 633 if (page == 'done') 634 this.closeOverlay_(); 635 else 636 this.showOverlay_(); 637 638 if (page == 'configure' || page == 'passphrase') 639 this.showConfigure_(args); 640 else if (page == 'spinner') 641 this.showSpinner_(); 642 else if (page == 'timeout') 643 this.showTimeoutPage_(); 644 }, 645 646 /** 647 * Changes the visibility of throbbers on this page. 648 * @param {boolean} visible Whether or not to set all throbber nodes 649 * visible. 650 */ 651 setThrobbersVisible_: function(visible) { 652 var throbbers = this.pageDiv.getElementsByClassName('throbber'); 653 for (var i = 0; i < throbbers.length; i++) 654 throbbers[i].style.visibility = visible ? 'visible' : 'hidden'; 655 }, 656 657 /** 658 * Reset the state of all descendant elements of a root element to their 659 * initial state. 660 * The initial state is specified by adding a class to the descendant 661 * element in sync_setup_overlay.html. 662 * @param {HTMLElement} pageElementId The root page element id. 663 * @private 664 */ 665 resetPage_: function(pageElementId) { 666 var page = $(pageElementId); 667 var forEach = function(arr, fn) { 668 var length = arr.length; 669 for (var i = 0; i < length; i++) { 670 fn(arr[i]); 671 } 672 }; 673 674 forEach(page.getElementsByClassName('reset-hidden'), 675 function(elt) { elt.hidden = true; }); 676 forEach(page.getElementsByClassName('reset-shown'), 677 function(elt) { elt.hidden = false; }); 678 forEach(page.getElementsByClassName('reset-disabled'), 679 function(elt) { elt.disabled = true; }); 680 forEach(page.getElementsByClassName('reset-enabled'), 681 function(elt) { elt.disabled = false; }); 682 forEach(page.getElementsByClassName('reset-value'), 683 function(elt) { elt.value = ''; }); 684 forEach(page.getElementsByClassName('reset-opaque'), 685 function(elt) { elt.classList.remove('transparent'); }); 686 }, 687 688 /** 689 * Displays the stop syncing dialog. 690 * @private 691 */ 692 showStopSyncingUI_: function() { 693 // Hide any visible children of the overlay. 694 var overlay = $('sync-setup-overlay'); 695 for (var i = 0; i < overlay.children.length; i++) 696 overlay.children[i].hidden = true; 697 698 // Bypass OptionsPage.navigateToPage because it will call didShowPage 699 // which will set its own visible page, based on the flow state. 700 this.visible = true; 701 702 $('sync-setup-stop-syncing').hidden = false; 703 $('stop-syncing-cancel').focus(); 704 }, 705 706 /** 707 * Determines the appropriate page to show in the Sync Setup UI based on 708 * the state of the Sync backend. Does nothing if the user is not signed in. 709 * @private 710 */ 711 showSetupUI_: function() { 712 chrome.send('SyncSetupShowSetupUI'); 713 }, 714 715 /** 716 * Starts the signin process for the user. Does nothing if the user is 717 * already signed in. 718 * @private 719 */ 720 startSignIn_: function() { 721 chrome.send('SyncSetupStartSignIn'); 722 }, 723 724 /** 725 * Forces user to sign out of Chrome for Chrome OS. 726 * @private 727 */ 728 doSignOutOnAuthError_: function() { 729 chrome.send('SyncSetupDoSignOutOnAuthError'); 730 }, 731 }; 732 733 // These methods are for general consumption. 734 SyncSetupOverlay.closeOverlay = function() { 735 SyncSetupOverlay.getInstance().closeOverlay_(); 736 }; 737 738 SyncSetupOverlay.showSetupUI = function() { 739 SyncSetupOverlay.getInstance().showSetupUI_(); 740 }; 741 742 SyncSetupOverlay.startSignIn = function() { 743 SyncSetupOverlay.getInstance().startSignIn_(); 744 }; 745 746 SyncSetupOverlay.doSignOutOnAuthError = function() { 747 SyncSetupOverlay.getInstance().doSignOutOnAuthError_(); 748 }; 749 750 SyncSetupOverlay.showSyncSetupPage = function(page, args) { 751 SyncSetupOverlay.getInstance().showSyncSetupPage_(page, args); 752 }; 753 754 SyncSetupOverlay.showCustomizePage = function(args, index) { 755 SyncSetupOverlay.getInstance().showCustomizePage_(args, index); 756 }; 757 758 SyncSetupOverlay.showSyncEverythingPage = function() { 759 SyncSetupOverlay.getInstance().showSyncEverythingPage_(); 760 }; 761 762 SyncSetupOverlay.showStopSyncingUI = function() { 763 SyncSetupOverlay.getInstance().showStopSyncingUI_(); 764 }; 765 766 // Export 767 return { 768 SyncSetupOverlay: SyncSetupOverlay 769 }; 770 }); 771