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