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