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 var OptionsPage = options.OptionsPage; 7 var ArrayDataModel = cr.ui.ArrayDataModel; 8 9 /** 10 * ManageProfileOverlay class 11 * Encapsulated handling of the 'Manage profile...' overlay page. 12 * @constructor 13 * @class 14 */ 15 function ManageProfileOverlay() { 16 OptionsPage.call(this, 'manageProfile', 17 loadTimeData.getString('manageProfileTabTitle'), 18 'manage-profile-overlay'); 19 }; 20 21 cr.addSingletonGetter(ManageProfileOverlay); 22 23 ManageProfileOverlay.prototype = { 24 // Inherit from OptionsPage. 25 __proto__: OptionsPage.prototype, 26 27 // Info about the currently managed/deleted profile. 28 profileInfo_: null, 29 30 // An object containing all known profile names. 31 profileNames_: {}, 32 33 // The currently selected icon in the icon grid. 34 iconGridSelectedURL_: null, 35 36 /** 37 * Initialize the page. 38 */ 39 initializePage: function() { 40 // Call base class implementation to start preference initialization. 41 OptionsPage.prototype.initializePage.call(this); 42 43 var self = this; 44 options.ProfilesIconGrid.decorate($('manage-profile-icon-grid')); 45 options.ProfilesIconGrid.decorate($('create-profile-icon-grid')); 46 self.registerCommonEventHandlers_('create', 47 self.submitCreateProfile_.bind(self)); 48 self.registerCommonEventHandlers_('manage', 49 self.submitManageChanges_.bind(self)); 50 51 // Override the create-profile-ok and create-* keydown handlers, to avoid 52 // closing the overlay until we finish creating the profile. 53 $('create-profile-ok').onclick = function(event) { 54 self.submitCreateProfile_(); 55 }; 56 57 $('create-profile-cancel').onclick = function(event) { 58 CreateProfileOverlay.cancelCreateProfile(); 59 }; 60 61 $('import-existing-managed-user-link').hidden = 62 !loadTimeData.getBoolean('allowCreateExistingManagedUsers'); 63 64 $('manage-profile-cancel').onclick = 65 $('delete-profile-cancel').onclick = function(event) { 66 OptionsPage.closeOverlay(); 67 }; 68 $('delete-profile-ok').onclick = function(event) { 69 OptionsPage.closeOverlay(); 70 if (BrowserOptions.getCurrentProfile().isManaged) 71 return; 72 chrome.send('deleteProfile', [self.profileInfo_.filePath]); 73 }; 74 $('add-shortcut-button').onclick = function(event) { 75 chrome.send('addProfileShortcut', [self.profileInfo_.filePath]); 76 }; 77 $('remove-shortcut-button').onclick = function(event) { 78 chrome.send('removeProfileShortcut', [self.profileInfo_.filePath]); 79 }; 80 81 $('create-profile-managed-signed-in-learn-more-link').onclick = 82 function(event) { 83 OptionsPage.navigateToPage('managedUserLearnMore'); 84 return false; 85 }; 86 87 $('create-profile-managed-not-signed-in-link').onclick = function(event) { 88 // The signin process will open an overlay to configure sync, which 89 // would replace this overlay. It's smoother to close this one now. 90 // TODO(pamg): Move the sync-setup overlay to a higher layer so this one 91 // can stay open under it, after making sure that doesn't break anything 92 // else. 93 OptionsPage.closeOverlay(); 94 SyncSetupOverlay.startSignIn(); 95 }; 96 97 $('create-profile-managed-sign-in-again-link').onclick = function(event) { 98 OptionsPage.closeOverlay(); 99 SyncSetupOverlay.showSetupUI(); 100 }; 101 102 $('import-existing-managed-user-link').onclick = function(event) { 103 OptionsPage.closeOverlay(); 104 OptionsPage.navigateToPage('managedUserImport'); 105 }; 106 }, 107 108 /** @override */ 109 didShowPage: function() { 110 chrome.send('requestDefaultProfileIcons'); 111 112 // Just ignore the manage profile dialog on Chrome OS, they use /accounts. 113 if (!cr.isChromeOS && window.location.pathname == '/manageProfile') 114 ManageProfileOverlay.getInstance().prepareForManageDialog_(); 115 116 // When editing a profile, initially hide the "add shortcut" and 117 // "remove shortcut" buttons and ask the handler which to show. It will 118 // call |receiveHasProfileShortcuts|, which will show the appropriate one. 119 $('remove-shortcut-button').hidden = true; 120 $('add-shortcut-button').hidden = true; 121 122 if (loadTimeData.getBoolean('profileShortcutsEnabled')) { 123 var profileInfo = ManageProfileOverlay.getInstance().profileInfo_; 124 chrome.send('requestHasProfileShortcuts', [profileInfo.filePath]); 125 } 126 127 var manageNameField = $('manage-profile-name'); 128 // Supervised users cannot edit their names. 129 if (manageNameField.disabled) 130 $('manage-profile-ok').focus(); 131 else 132 manageNameField.focus(); 133 }, 134 135 /** 136 * Registers event handlers that are common between create and manage modes. 137 * @param {string} mode A label that specifies the type of dialog 138 * box which is currently being viewed (i.e. 'create' or 139 * 'manage'). 140 * @param {function()} submitFunction The function that should be called 141 * when the user chooses to submit (e.g. by clicking the OK button). 142 * @private 143 */ 144 registerCommonEventHandlers_: function(mode, submitFunction) { 145 var self = this; 146 $(mode + '-profile-icon-grid').addEventListener('change', function(e) { 147 self.onIconGridSelectionChanged_(mode); 148 }); 149 $(mode + '-profile-name').oninput = function(event) { 150 self.onNameChanged_(event, mode); 151 }; 152 $(mode + '-profile-ok').onclick = function(event) { 153 OptionsPage.closeOverlay(); 154 submitFunction(); 155 }; 156 }, 157 158 /** 159 * Set the profile info used in the dialog. 160 * @param {Object} profileInfo An object of the form: 161 * profileInfo = { 162 * name: "Profile Name", 163 * iconURL: "chrome://path/to/icon/image", 164 * filePath: "/path/to/profile/data/on/disk", 165 * isCurrentProfile: false, 166 * isManaged: false 167 * }; 168 * @param {string} mode A label that specifies the type of dialog 169 * box which is currently being viewed (i.e. 'create' or 170 * 'manage'). 171 * @private 172 */ 173 setProfileInfo_: function(profileInfo, mode) { 174 this.iconGridSelectedURL_ = profileInfo.iconURL; 175 this.profileInfo_ = profileInfo; 176 $(mode + '-profile-name').value = profileInfo.name; 177 $(mode + '-profile-icon-grid').selectedItem = profileInfo.iconURL; 178 }, 179 180 /** 181 * Sets the name of the currently edited profile. 182 * @private 183 */ 184 setProfileName_: function(name) { 185 if (this.profileInfo_) 186 this.profileInfo_.name = name; 187 $('manage-profile-name').value = name; 188 }, 189 190 /** 191 * Set an array of default icon URLs. These will be added to the grid that 192 * the user will use to choose their profile icon. 193 * @param {Array.<string>} iconURLs An array of icon URLs. 194 * @private 195 */ 196 receiveDefaultProfileIcons_: function(iconGrid, iconURLs) { 197 $(iconGrid).dataModel = new ArrayDataModel(iconURLs); 198 199 if (this.profileInfo_) 200 $(iconGrid).selectedItem = this.profileInfo_.iconURL; 201 202 var grid = $(iconGrid); 203 // Recalculate the measured item size. 204 grid.measured_ = null; 205 grid.columns = 0; 206 grid.redraw(); 207 }, 208 209 /** 210 * Callback to set the initial values when creating a new profile. 211 * @param {Object} profileInfo An object of the form: 212 * profileInfo = { 213 * name: "Profile Name", 214 * iconURL: "chrome://path/to/icon/image", 215 * }; 216 * @private 217 */ 218 receiveNewProfileDefaults_: function(profileInfo) { 219 ManageProfileOverlay.setProfileInfo(profileInfo, 'create'); 220 $('create-profile-name-label').hidden = false; 221 $('create-profile-name').hidden = false; 222 // Trying to change the focus if this isn't the topmost overlay can 223 // instead cause the FocusManager to override another overlay's focus, 224 // e.g. if an overlay above this one is in the process of being reloaded. 225 // But the C++ handler calls this method directly on ManageProfileOverlay, 226 // so check the pageDiv to also include its subclasses (in particular 227 // CreateProfileOverlay, which has higher sub-overlays). 228 if (OptionsPage.getTopmostVisiblePage().pageDiv == this.pageDiv) { 229 // This will only have an effect if the 'create-profile-name' element 230 // is visible, i.e. if the overlay is in create mode. 231 $('create-profile-name').focus(); 232 } 233 $('create-profile-ok').disabled = false; 234 }, 235 236 /** 237 * Set a dictionary of all profile names. These are used to prevent the 238 * user from naming two profiles the same. 239 * @param {Object} profileNames A dictionary of profile names. 240 * @private 241 */ 242 receiveProfileNames_: function(profileNames) { 243 this.profileNames_ = profileNames; 244 }, 245 246 /** 247 * Callback to show the add/remove shortcut buttons when in edit mode, 248 * called by the handler as a result of the 'requestHasProfileShortcuts_' 249 * message. 250 * @param {boolean} hasShortcuts Whether profile has any existing shortcuts. 251 * @private 252 */ 253 receiveHasProfileShortcuts_: function(hasShortcuts) { 254 $('add-shortcut-button').hidden = hasShortcuts; 255 $('remove-shortcut-button').hidden = !hasShortcuts; 256 }, 257 258 /** 259 * Display the error bubble, with |errorText| in the bubble. 260 * @param {string} errorText The string to display as an error. 261 * @param {string} mode A label that specifies the type of dialog 262 * box which is currently being viewed (i.e. 'create' or 263 * 'manage'). 264 * @param {boolean} disableOKButton True if the dialog's OK button should be 265 * disabled when the error bubble is shown. It will be (re-)enabled when 266 * the error bubble is hidden. 267 * @private 268 */ 269 showErrorBubble_: function(errorText, mode, disableOKButton) { 270 var nameErrorEl = $(mode + '-profile-error-bubble'); 271 nameErrorEl.hidden = false; 272 nameErrorEl.textContent = errorText; 273 274 if (disableOKButton) 275 $(mode + '-profile-ok').disabled = true; 276 }, 277 278 /** 279 * Hide the error bubble. 280 * @param {string} mode A label that specifies the type of dialog 281 * box which is currently being viewed (i.e. 'create' or 282 * 'manage'). 283 * @private 284 */ 285 hideErrorBubble_: function(mode) { 286 $(mode + '-profile-error-bubble').hidden = true; 287 $(mode + '-profile-ok').disabled = false; 288 }, 289 290 /** 291 * oninput callback for <input> field. 292 * @param {Event} event The event object. 293 * @param {string} mode A label that specifies the type of dialog 294 * box which is currently being viewed (i.e. 'create' or 295 * 'manage'). 296 * @private 297 */ 298 onNameChanged_: function(event, mode) { 299 var newName = event.target.value; 300 var oldName = this.profileInfo_.name; 301 302 if (newName == oldName) { 303 this.hideErrorBubble_(mode); 304 } else if (this.profileNames_[newName] != undefined) { 305 var errorText = 306 loadTimeData.getString('manageProfilesDuplicateNameError'); 307 this.showErrorBubble_(errorText, mode, true); 308 } else { 309 this.hideErrorBubble_(mode); 310 311 var nameIsValid = $(mode + '-profile-name').validity.valid; 312 $(mode + '-profile-ok').disabled = !nameIsValid; 313 } 314 }, 315 316 /** 317 * Called when the user clicks "OK" or hits enter. Saves the newly changed 318 * profile info. 319 * @private 320 */ 321 submitManageChanges_: function() { 322 var name = $('manage-profile-name').value; 323 var iconURL = $('manage-profile-icon-grid').selectedItem; 324 325 chrome.send('setProfileIconAndName', 326 [this.profileInfo_.filePath, iconURL, name]); 327 }, 328 329 /** 330 * Called when the user clicks "OK" or hits enter. Creates the profile 331 * using the information in the dialog. 332 * @private 333 */ 334 submitCreateProfile_: function() { 335 // This is visual polish: the UI to access this should be disabled for 336 // managed users, and the back end will prevent user creation anyway. 337 if (this.profileInfo_ && this.profileInfo_.isManaged) 338 return; 339 340 this.hideErrorBubble_('create'); 341 CreateProfileOverlay.updateCreateInProgress(true); 342 343 // Get the user's chosen name and icon, or default if they do not 344 // wish to customize their profile. 345 var name = $('create-profile-name').value; 346 var iconUrl = $('create-profile-icon-grid').selectedItem; 347 var createShortcut = $('create-shortcut').checked; 348 var isManaged = $('create-profile-managed').checked; 349 var existingManagedUserId = ''; 350 351 // 'createProfile' is handled by the CreateProfileHandler. 352 chrome.send('createProfile', 353 [name, iconUrl, createShortcut, 354 isManaged, existingManagedUserId]); 355 }, 356 357 /** 358 * Called when the selected icon in the icon grid changes. 359 * @param {string} mode A label that specifies the type of dialog 360 * box which is currently being viewed (i.e. 'create' or 361 * 'manage'). 362 * @private 363 */ 364 onIconGridSelectionChanged_: function(mode) { 365 var iconURL = $(mode + '-profile-icon-grid').selectedItem; 366 if (!iconURL || iconURL == this.iconGridSelectedURL_) 367 return; 368 this.iconGridSelectedURL_ = iconURL; 369 if (this.profileInfo_ && this.profileInfo_.filePath) { 370 chrome.send('profileIconSelectionChanged', 371 [this.profileInfo_.filePath, iconURL]); 372 } 373 }, 374 375 /** 376 * Updates the contents of the "Manage Profile" section of the dialog, 377 * and shows that section. 378 * @private 379 */ 380 prepareForManageDialog_: function() { 381 var profileInfo = BrowserOptions.getCurrentProfile(); 382 ManageProfileOverlay.setProfileInfo(profileInfo, 'manage'); 383 $('manage-profile-overlay-create').hidden = true; 384 $('manage-profile-overlay-manage').hidden = false; 385 $('manage-profile-overlay-delete').hidden = true; 386 $('manage-profile-name').disabled = profileInfo.isManaged; 387 this.hideErrorBubble_('manage'); 388 }, 389 390 /** 391 * Display the "Manage Profile" dialog. 392 * @private 393 */ 394 showManageDialog_: function() { 395 this.prepareForManageDialog_(); 396 OptionsPage.navigateToPage('manageProfile'); 397 }, 398 399 /** 400 * Display the "Delete Profile" dialog. 401 * @param {Object} profileInfo The profile object of the profile to delete. 402 * @private 403 */ 404 showDeleteDialog_: function(profileInfo) { 405 if (BrowserOptions.getCurrentProfile().isManaged) 406 return; 407 408 ManageProfileOverlay.setProfileInfo(profileInfo, 'manage'); 409 $('manage-profile-overlay-create').hidden = true; 410 $('manage-profile-overlay-manage').hidden = true; 411 $('manage-profile-overlay-delete').hidden = false; 412 $('delete-profile-icon').style.content = 413 imageset(profileInfo.iconURL + '@scalefactorx'); 414 $('delete-profile-text').textContent = 415 loadTimeData.getStringF('deleteProfileMessage', profileInfo.name); 416 $('delete-managed-profile-addendum').hidden = !profileInfo.isManaged; 417 418 // Because this dialog isn't useful when refreshing or as part of the 419 // history, don't create a history entry for it when showing. 420 OptionsPage.showPageByName('manageProfile', false); 421 }, 422 423 /** 424 * Display the "Create Profile" dialog. 425 * @private 426 */ 427 showCreateDialog_: function() { 428 OptionsPage.navigateToPage('createProfile'); 429 }, 430 }; 431 432 // Forward public APIs to private implementations. 433 [ 434 'receiveDefaultProfileIcons', 435 'receiveNewProfileDefaults', 436 'receiveProfileNames', 437 'receiveHasProfileShortcuts', 438 'setProfileInfo', 439 'setProfileName', 440 'showManageDialog', 441 'showDeleteDialog', 442 'showCreateDialog', 443 ].forEach(function(name) { 444 ManageProfileOverlay[name] = function() { 445 var instance = ManageProfileOverlay.getInstance(); 446 return instance[name + '_'].apply(instance, arguments); 447 }; 448 }); 449 450 function CreateProfileOverlay() { 451 OptionsPage.call(this, 'createProfile', 452 loadTimeData.getString('createProfileTabTitle'), 453 'manage-profile-overlay'); 454 }; 455 456 cr.addSingletonGetter(CreateProfileOverlay); 457 458 CreateProfileOverlay.prototype = { 459 // Inherit from ManageProfileOverlay. 460 __proto__: ManageProfileOverlay.prototype, 461 462 // The signed-in email address of the current profile, or empty if they're 463 // not signed in. 464 signedInEmail_: '', 465 466 /** @override */ 467 canShowPage: function() { 468 return !BrowserOptions.getCurrentProfile().isManaged; 469 }, 470 471 /** 472 * Configures the overlay to the "create user" mode. 473 * @override 474 */ 475 didShowPage: function() { 476 chrome.send('requestCreateProfileUpdate'); 477 chrome.send('requestDefaultProfileIcons'); 478 chrome.send('requestNewProfileDefaults'); 479 480 $('manage-profile-overlay-create').hidden = false; 481 $('manage-profile-overlay-manage').hidden = true; 482 $('manage-profile-overlay-delete').hidden = true; 483 $('create-profile-instructions').textContent = 484 loadTimeData.getStringF('createProfileInstructions'); 485 this.hideErrorBubble_(); 486 this.updateCreateInProgress_(false); 487 488 var shortcutsEnabled = loadTimeData.getBoolean('profileShortcutsEnabled'); 489 $('create-shortcut-container').hidden = !shortcutsEnabled; 490 $('create-shortcut').checked = shortcutsEnabled; 491 492 $('create-profile-name-label').hidden = true; 493 $('create-profile-name').hidden = true; 494 $('create-profile-ok').disabled = true; 495 496 $('create-profile-managed').checked = false; 497 $('create-profile-managed-signed-in').disabled = true; 498 $('create-profile-managed-signed-in').hidden = true; 499 $('create-profile-managed-not-signed-in').hidden = true; 500 }, 501 502 /** @override */ 503 handleCancel: function() { 504 this.cancelCreateProfile_(); 505 }, 506 507 /** @override */ 508 showErrorBubble_: function(errorText) { 509 ManageProfileOverlay.getInstance().showErrorBubble_(errorText, 510 'create', 511 false); 512 }, 513 514 /** @override */ 515 hideErrorBubble_: function() { 516 ManageProfileOverlay.getInstance().hideErrorBubble_('create'); 517 }, 518 519 /** 520 * Updates the UI when a profile create step begins or ends. 521 * Note that hideErrorBubble_() also enables the "OK" button, so it 522 * must be called before this function if both are used. 523 * @param {boolean} inProgress True if the UI should be updated to show that 524 * profile creation is now in progress. 525 * @private 526 */ 527 updateCreateInProgress_: function(inProgress) { 528 this.createInProgress_ = inProgress; 529 this.updateCreateManagedUserCheckbox_(); 530 531 $('create-profile-icon-grid').disabled = inProgress; 532 $('create-profile-name').disabled = inProgress; 533 $('create-shortcut').disabled = inProgress; 534 $('create-profile-ok').disabled = inProgress; 535 536 $('create-profile-throbber').hidden = !inProgress; 537 }, 538 539 /** 540 * Cancels the creation of the a profile. It is safe to call this even 541 * when no profile is in the process of being created. 542 * @private 543 */ 544 cancelCreateProfile_: function() { 545 OptionsPage.closeOverlay(); 546 chrome.send('cancelCreateProfile'); 547 this.hideErrorBubble_(); 548 this.updateCreateInProgress_(false); 549 }, 550 551 /** 552 * Shows an error message describing an error that occurred while creating 553 * a new profile. 554 * Called by BrowserOptions via the BrowserOptionsHandler. 555 * @param {string} error The error message to display. 556 * @private 557 */ 558 onError_: function(error) { 559 this.updateCreateInProgress_(false); 560 this.showErrorBubble_(error); 561 }, 562 563 /** 564 * Shows a warning message giving information while creating a new profile. 565 * Called by BrowserOptions via the BrowserOptionsHandler. 566 * @param {string} warning The warning message to display. 567 * @private 568 */ 569 onWarning_: function(warning) { 570 this.showErrorBubble_(warning); 571 }, 572 573 /** 574 * For new supervised users, shows a confirmation page after successfully 575 * creating a new profile; otherwise, the handler will open a new window. 576 * @param {Object} profileInfo An object of the form: 577 * profileInfo = { 578 * name: "Profile Name", 579 * filePath: "/path/to/profile/data/on/disk" 580 * isManaged: (true|false), 581 * }; 582 * @private 583 */ 584 onSuccess_: function(profileInfo) { 585 this.updateCreateInProgress_(false); 586 OptionsPage.closeOverlay(); 587 if (profileInfo.isManaged) { 588 profileInfo.custodianEmail = this.signedInEmail_; 589 ManagedUserCreateConfirmOverlay.setProfileInfo(profileInfo); 590 OptionsPage.showPageByName('managedUserCreateConfirm', false); 591 BrowserOptions.updateManagesSupervisedUsers(true); 592 } 593 }, 594 595 /** 596 * Updates the signed-in or not-signed-in UI when in create mode. Called by 597 * the handler in response to the 'requestCreateProfileUpdate' message. 598 * updateManagedUsersAllowed_ is expected to be called after this is, and 599 * will update additional UI elements. 600 * @param {string} email The email address of the currently signed-in user. 601 * An empty string indicates that the user is not signed in. 602 * @param {boolean} hasError Whether the user's sign-in credentials are 603 * still valid. 604 * @private 605 */ 606 updateSignedInStatus_: function(email, hasError) { 607 this.signedInEmail_ = email; 608 this.hasError_ = hasError; 609 var isSignedIn = email !== ''; 610 $('create-profile-managed-signed-in').hidden = !isSignedIn; 611 $('create-profile-managed-not-signed-in').hidden = isSignedIn; 612 613 if (isSignedIn) { 614 var accountDetailsOutOfDate = 615 $('create-profile-managed-account-details-out-of-date-label'); 616 accountDetailsOutOfDate.textContent = loadTimeData.getStringF( 617 'manageProfilesManagedAccountDetailsOutOfDate', email); 618 accountDetailsOutOfDate.hidden = !hasError; 619 620 $('create-profile-managed-signed-in-label').textContent = 621 loadTimeData.getStringF( 622 'manageProfilesManagedSignedInLabel', email); 623 $('create-profile-managed-signed-in-label').hidden = hasError; 624 625 $('create-profile-managed-sign-in-again-link').hidden = !hasError; 626 $('create-profile-managed-signed-in-learn-more-link').hidden = hasError; 627 } 628 629 this.updateImportExistingManagedUserLink_(isSignedIn && !hasError); 630 }, 631 632 /** 633 * Enables/disables the 'import existing managed users' link button. 634 * It also updates the button text. 635 * @param {boolean} enable True to enable the link button and 636 * false otherwise. 637 * @private 638 */ 639 updateImportExistingManagedUserLink_: function(enable) { 640 var importManagedUserElement = $('import-existing-managed-user-link'); 641 importManagedUserElement.disabled = !enable; 642 importManagedUserElement.textContent = enable ? 643 loadTimeData.getString('importExistingManagedUserLink') : 644 loadTimeData.getString('signInToImportManagedUsers'); 645 }, 646 647 /** 648 * Sets whether creating managed users is allowed or not. Called by the 649 * handler in response to the 'requestCreateProfileUpdate' message or a 650 * change in the (policy-controlled) pref that prohibits creating managed 651 * users, after the signed-in status has been updated. 652 * @param {boolean} allowed True if creating managed users should be 653 * allowed. 654 * @private 655 */ 656 updateManagedUsersAllowed_: function(allowed) { 657 this.managedUsersAllowed_ = allowed; 658 this.updateCreateManagedUserCheckbox_(); 659 660 $('create-profile-managed-not-signed-in-link').hidden = !allowed; 661 if (!allowed) { 662 $('create-profile-managed-indicator').setAttribute('controlled-by', 663 'policy'); 664 } else { 665 $('create-profile-managed-indicator').removeAttribute('controlled-by'); 666 } 667 }, 668 669 /** 670 * Updates the status of the "create managed user" checkbox. Called from 671 * updateManagedUsersAllowed_() or updateCreateInProgress_(). 672 * updateSignedInStatus_() does not call this method directly, because it 673 * will be followed by a call to updateManagedUsersAllowed_(). 674 * @private 675 */ 676 updateCreateManagedUserCheckbox_: function() { 677 $('create-profile-managed').disabled = 678 !this.managedUsersAllowed_ || this.createInProgress_ || 679 this.signedInEmail_ == '' || this.hasError_; 680 }, 681 }; 682 683 // Forward public APIs to private implementations. 684 [ 685 'cancelCreateProfile', 686 'onError', 687 'onSuccess', 688 'onWarning', 689 'updateCreateInProgress', 690 'updateManagedUsersAllowed', 691 'updateSignedInStatus', 692 ].forEach(function(name) { 693 CreateProfileOverlay[name] = function() { 694 var instance = CreateProfileOverlay.getInstance(); 695 return instance[name + '_'].apply(instance, arguments); 696 }; 697 }); 698 699 // Export 700 return { 701 ManageProfileOverlay: ManageProfileOverlay, 702 CreateProfileOverlay: CreateProfileOverlay, 703 }; 704}); 705