Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2112)

Unified Diff: chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js

Issue 2944703004: Run clang-format on .js files in c/b/r/chromeos (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
diff --git a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
index 24304782b426af96e3df56d7a2cb0ab3f05dcc3e..350c1bfd51809429244fb95829b6bdbaf2e1a9fc 100644
--- a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
+++ b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
@@ -6,1586 +6,1566 @@
* @fileoverview Legacy supervised user creation flow screen.
*/
-login.createScreen('SupervisedUserCreationScreen',
- 'supervised-user-creation', function() {
- var MAX_NAME_LENGTH = 50;
- var UserImagesGrid = options.UserImagesGrid;
- var ButtonImages = UserImagesGrid.ButtonImages;
-
- var ManagerPod = cr.ui.define(function() {
- var node = $('supervised-user-creation-manager-template').cloneNode(true);
- node.removeAttribute('id');
- node.removeAttribute('hidden');
- return node;
- });
-
- ManagerPod.userImageSalt_ = {};
-
- /**
- * UI element for displaying single account in list of possible managers for
- * new supervised user.
- * @type {Object}
- */
- ManagerPod.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- /** @override */
- decorate: function() {
- // Mousedown has to be used instead of click to be able to prevent 'focus'
- // event later.
- this.addEventListener('mousedown',
- this.handleMouseDown_.bind(this));
- var screen = $('supervised-user-creation');
- var managerPod = this;
- var managerPodList = screen.managerList_;
- var hideManagerPasswordError = function(element) {
- managerPod.passwordElement.classList.remove('password-error');
- $('bubble').hide();
- };
-
- screen.configureTextInput(
- this.passwordElement,
- screen.updateNextButtonForManager_.bind(screen),
- screen.validIfNotEmpty_.bind(screen),
- function(element) {
- screen.getScreenButton('next').focus();
- },
- hideManagerPasswordError);
-
- this.passwordElement.addEventListener('keydown', function(e) {
- switch (e.key) {
- case 'ArrowUp':
- managerPodList.selectNextPod(-1);
- e.stopPropagation();
- break;
- case 'ArrowDown':
- managerPodList.selectNextPod(+1);
- e.stopPropagation();
- break;
- }
- });
- },
-
- /**
- * Updates UI elements from user data.
- */
- update: function() {
- this.imageElement.src = 'chrome://userimage/' + this.user.username +
- '?id=' + ManagerPod.userImageSalt_[this.user.username];
-
- this.nameElement.textContent = this.user.displayName;
- this.emailElement.textContent = this.user.emailAddress;
- },
-
- showPasswordError: function() {
- this.passwordElement.classList.add('password-error');
- $('bubble').showTextForElement(
- this.passwordElement,
- loadTimeData.getString(
- 'createSupervisedUserWrongManagerPasswordText'),
- cr.ui.Bubble.Attachment.BOTTOM,
- 24, 4);
- },
-
- /**
- * Brings focus to password field.
- */
- focusInput: function() {
- this.passwordElement.focus();
- },
-
- /**
- * Gets image element.
- * @type {!HTMLImageElement}
- */
- get imageElement() {
- return this.querySelector('.supervised-user-creation-manager-image');
- },
-
- /**
- * Gets name element.
- * @type {!HTMLDivElement}
- */
- get nameElement() {
- return this.querySelector('.supervised-user-creation-manager-name');
- },
-
- /**
- * Gets e-mail element.
- * @type {!HTMLDivElement}
- */
- get emailElement() {
- return this.querySelector('.supervised-user-creation-manager-email');
- },
-
- /**
- * Gets password element.
- * @type {!HTMLDivElement}
- */
- get passwordElement() {
- return this.querySelector('.supervised-user-creation-manager-password');
- },
-
- /**
- * Gets password enclosing block.
- * @type {!HTMLDivElement}
- */
- get passwordBlock() {
- return this.querySelector('.password-block');
- },
-
- /** @override */
- handleMouseDown_: function(e) {
- this.parentNode.selectPod(this);
- // Prevent default so that we don't trigger 'focus' event.
- e.preventDefault();
- },
-
- /**
- * The user that this pod represents.
- * @type {!Object}
- */
- user_: undefined,
- get user() {
- return this.user_;
- },
- set user(userDict) {
- this.user_ = userDict;
- this.update();
- },
- };
-
- var ManagerPodList = cr.ui.define('div');
-
- /**
- * UI element for selecting manager account for new supervised user.
- * @type {Object}
- */
- ManagerPodList.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- selectedPod_: null,
-
- /** @override */
- decorate: function() {
- },
-
- /**
- * Returns all the pods in this pod list.
- * @type {NodeList}
- */
- get pods() {
- return this.children;
- },
-
- addPod: function(manager) {
- var managerPod = new ManagerPod({user: manager});
- this.appendChild(managerPod);
- managerPod.update();
- },
-
- clearPods: function() {
- this.innerHTML = '';
- this.selectedPod_ = null;
- },
-
- selectPod: function(podToSelect) {
- if ((this.selectedPod_ == podToSelect) && !!podToSelect) {
- podToSelect.focusInput();
- return;
- }
- this.selectedPod_ = podToSelect;
- for (var i = 0, pod; pod = this.pods[i]; ++i) {
- if (pod != podToSelect) {
- pod.classList.remove('focused');
- pod.passwordElement.value = '';
- pod.passwordBlock.hidden = true;
- }
- }
- if (!podToSelect)
- return;
- podToSelect.classList.add('focused');
- podToSelect.passwordBlock.hidden = false;
- podToSelect.passwordElement.value = '';
- podToSelect.focusInput();
- chrome.send('managerSelectedOnSupervisedUserCreationFlow',
- [podToSelect.user.username]);
- },
-
- /**
- * Select pod next to currently selected one in given |direction|.
- * @param {integer} direction - +1 for selecting pod below current, -1 for
- * selecting pod above current.
- * @type {boolean} returns if selected pod has changed.
- */
- selectNextPod: function(direction) {
- if (!this.selectedPod_)
- return false;
- var index = -1;
- for (var i = 0, pod; pod = this.pods[i]; ++i) {
- if (pod == this.selectedPod_) {
- index = i;
- break;
- }
- }
- if (-1 == index)
- return false;
- index = index + direction;
- if (index < 0 || index >= this.pods.length)
- return false;
- this.selectPod(this.pods[index]);
- return true;
- }
- };
-
- var ImportPod = cr.ui.define(function() {
- var node = $('supervised-user-creation-import-template').cloneNode(true);
- node.removeAttribute('id');
- node.removeAttribute('hidden');
- return node;
- });
-
- /**
- * UI element for displaying single supervised user in list of possible users
- * for importing existing users.
- * @type {Object}
- */
- ImportPod.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- /** @override */
- decorate: function() {
- // Mousedown has to be used instead of click to be able to prevent 'focus'
- // event later.
- this.addEventListener('mousedown', this.handleMouseDown_.bind(this));
- var screen = $('supervised-user-creation');
- var importList = screen.importList_;
- },
-
- /**
- * Updates UI elements from user data.
- */
- update: function() {
- this.imageElement.src = this.user.avatarurl;
- this.nameElement.textContent = this.user.name;
- if (this.user.exists) {
- if (this.user.conflict == 'imported') {
- this.nameElement.textContent =
- loadTimeData.getStringF('importUserExists', this.user.name);
- } else {
- this.nameElement.textContent =
- loadTimeData.getStringF('importUsernameExists', this.user.name);
- }
- }
- this.classList.toggle('imported', this.user.exists);
- },
-
- /**
- * Gets image element.
- * @type {!HTMLImageElement}
- */
- get imageElement() {
- return this.querySelector('.import-pod-image');
- },
-
- /**
- * Gets name element.
- * @type {!HTMLDivElement}
- */
- get nameElement() {
- return this.querySelector('.import-pod-name');
- },
-
- /** @override */
- handleMouseDown_: function(e) {
- this.parentNode.selectPod(this);
- // Prevent default so that we don't trigger 'focus' event.
- e.preventDefault();
- },
-
- /**
- * The user that this pod represents.
- * @type {Object}
- */
- user_: undefined,
-
- get user() {
- return this.user_;
- },
-
- set user(userDict) {
- this.user_ = userDict;
- this.update();
- },
- };
-
- var ImportPodList = cr.ui.define('div');
-
- /**
- * UI element for selecting existing supervised user for import.
- * @type {Object}
- */
- ImportPodList.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- selectedPod_: null,
-
- /** @override */
- decorate: function() {
- this.setAttribute('tabIndex', 0);
- this.classList.add('nofocus');
- var importList = this;
- var screen = $('supervised-user-creation');
-
- this.addEventListener('focus', function(e) {
- if (importList.selectedPod_ == null) {
- if (importList.pods.length > 0)
- importList.selectPod(importList.pods[0]);
- }
+login.createScreen(
+ 'SupervisedUserCreationScreen', 'supervised-user-creation', function() {
+ var MAX_NAME_LENGTH = 50;
+ var UserImagesGrid = options.UserImagesGrid;
+ var ButtonImages = UserImagesGrid.ButtonImages;
+
+ var ManagerPod = cr.ui.define(function() {
+ var node =
+ $('supervised-user-creation-manager-template').cloneNode(true);
+ node.removeAttribute('id');
+ node.removeAttribute('hidden');
+ return node;
});
- this.addEventListener('keydown', function(e) {
- switch (e.key) {
- case 'ArrowUp':
- importList.selectNextPod(-1);
- e.stopPropagation();
- break;
- case 'Enter':
- if (importList.selectedPod_ != null)
- screen.importSupervisedUser_();
- e.stopPropagation();
- break;
- case 'ArrowDown':
- importList.selectNextPod(+1);
- e.stopPropagation();
- break;
- }
- });
- },
-
- /**
- * Returns all the pods in this pod list.
- * @type {NodeList}
- */
- get pods() {
- return this.children;
- },
-
- /**
- * Returns selected pod.
- * @type {Node}
- */
- get selectedPod() {
- return this.selectedPod_;
- },
-
- addPod: function(user) {
- var importPod = new ImportPod({user: user});
- this.appendChild(importPod);
- importPod.update();
- },
-
- clearPods: function() {
- this.innerHTML = '';
- this.selectedPod_ = null;
- },
-
- scrollIntoView: function(pod) {
- scroller = this.parentNode;
- var itemHeight = pod.getBoundingClientRect().height;
- var scrollTop = scroller.scrollTop;
- var top = pod.offsetTop - scroller.offsetTop;
- var clientHeight = scroller.clientHeight;
-
- var self = scroller;
-
- // Function to adjust the tops of viewport and row.
- function scrollToAdjustTop() {
- self.scrollTop = top;
- return true;
- }
- // Function to adjust the bottoms of viewport and row.
- function scrollToAdjustBottom() {
- var cs = getComputedStyle(self);
- var paddingY = parseInt(cs.paddingTop, 10) +
- parseInt(cs.paddingBottom, 10);
-
- if (top + itemHeight > scrollTop + clientHeight - paddingY) {
- self.scrollTop = top + itemHeight - clientHeight + paddingY;
+ ManagerPod.userImageSalt_ = {};
+
+ /**
+ * UI element for displaying single account in list of possible managers
+ * for new supervised user.
+ * @type {Object}
+ */
+ ManagerPod.prototype = {
+ __proto__: HTMLDivElement.prototype,
+
+ /** @override */
+ decorate: function() {
+ // Mousedown has to be used instead of click to be able to prevent
+ // 'focus' event later.
+ this.addEventListener('mousedown', this.handleMouseDown_.bind(this));
+ var screen = $('supervised-user-creation');
+ var managerPod = this;
+ var managerPodList = screen.managerList_;
+ var hideManagerPasswordError = function(element) {
+ managerPod.passwordElement.classList.remove('password-error');
+ $('bubble').hide();
+ };
+
+ screen.configureTextInput(
+ this.passwordElement,
+ screen.updateNextButtonForManager_.bind(screen),
+ screen.validIfNotEmpty_.bind(screen), function(element) {
+ screen.getScreenButton('next').focus();
+ }, hideManagerPasswordError);
+
+ this.passwordElement.addEventListener('keydown', function(e) {
+ switch (e.key) {
+ case 'ArrowUp':
+ managerPodList.selectNextPod(-1);
+ e.stopPropagation();
+ break;
+ case 'ArrowDown':
+ managerPodList.selectNextPod(+1);
+ e.stopPropagation();
+ break;
+ }
+ });
+ },
+
+ /**
+ * Updates UI elements from user data.
+ */
+ update: function() {
+ this.imageElement.src = 'chrome://userimage/' + this.user.username +
+ '?id=' + ManagerPod.userImageSalt_[this.user.username];
+
+ this.nameElement.textContent = this.user.displayName;
+ this.emailElement.textContent = this.user.emailAddress;
+ },
+
+ showPasswordError: function() {
+ this.passwordElement.classList.add('password-error');
+ $('bubble').showTextForElement(
+ this.passwordElement,
+ loadTimeData.getString(
+ 'createSupervisedUserWrongManagerPasswordText'),
+ cr.ui.Bubble.Attachment.BOTTOM, 24, 4);
+ },
+
+ /**
+ * Brings focus to password field.
+ */
+ focusInput: function() {
+ this.passwordElement.focus();
+ },
+
+ /**
+ * Gets image element.
+ * @type {!HTMLImageElement}
+ */
+ get imageElement() {
+ return this.querySelector('.supervised-user-creation-manager-image');
+ },
+
+ /**
+ * Gets name element.
+ * @type {!HTMLDivElement}
+ */
+ get nameElement() {
+ return this.querySelector('.supervised-user-creation-manager-name');
+ },
+
+ /**
+ * Gets e-mail element.
+ * @type {!HTMLDivElement}
+ */
+ get emailElement() {
+ return this.querySelector('.supervised-user-creation-manager-email');
+ },
+
+ /**
+ * Gets password element.
+ * @type {!HTMLDivElement}
+ */
+ get passwordElement() {
+ return this.querySelector(
+ '.supervised-user-creation-manager-password');
+ },
+
+ /**
+ * Gets password enclosing block.
+ * @type {!HTMLDivElement}
+ */
+ get passwordBlock() {
+ return this.querySelector('.password-block');
+ },
+
+ /** @override */
+ handleMouseDown_: function(e) {
+ this.parentNode.selectPod(this);
+ // Prevent default so that we don't trigger 'focus' event.
+ e.preventDefault();
+ },
+
+ /**
+ * The user that this pod represents.
+ * @type {!Object}
+ */
+ user_: undefined,
+ get user() {
+ return this.user_;
+ },
+ set user(userDict) {
+ this.user_ = userDict;
+ this.update();
+ },
+ };
+
+ var ManagerPodList = cr.ui.define('div');
+
+ /**
+ * UI element for selecting manager account for new supervised user.
+ * @type {Object}
+ */
+ ManagerPodList.prototype = {
+ __proto__: HTMLDivElement.prototype,
+
+ selectedPod_: null,
+
+ /** @override */
+ decorate: function() {},
+
+ /**
+ * Returns all the pods in this pod list.
+ * @type {NodeList}
+ */
+ get pods() {
+ return this.children;
+ },
+
+ addPod: function(manager) {
+ var managerPod = new ManagerPod({user: manager});
+ this.appendChild(managerPod);
+ managerPod.update();
+ },
+
+ clearPods: function() {
+ this.innerHTML = '';
+ this.selectedPod_ = null;
+ },
+
+ selectPod: function(podToSelect) {
+ if ((this.selectedPod_ == podToSelect) && !!podToSelect) {
+ podToSelect.focusInput();
+ return;
+ }
+ this.selectedPod_ = podToSelect;
+ for (var i = 0, pod; pod = this.pods[i]; ++i) {
+ if (pod != podToSelect) {
+ pod.classList.remove('focused');
+ pod.passwordElement.value = '';
+ pod.passwordBlock.hidden = true;
+ }
+ }
+ if (!podToSelect)
+ return;
+ podToSelect.classList.add('focused');
+ podToSelect.passwordBlock.hidden = false;
+ podToSelect.passwordElement.value = '';
+ podToSelect.focusInput();
+ chrome.send(
+ 'managerSelectedOnSupervisedUserCreationFlow',
+ [podToSelect.user.username]);
+ },
+
+ /**
+ * Select pod next to currently selected one in given |direction|.
+ * @param {integer} direction - +1 for selecting pod below current, -1 for
+ * selecting pod above current.
+ * @type {boolean} returns if selected pod has changed.
+ */
+ selectNextPod: function(direction) {
+ if (!this.selectedPod_)
+ return false;
+ var index = -1;
+ for (var i = 0, pod; pod = this.pods[i]; ++i) {
+ if (pod == this.selectedPod_) {
+ index = i;
+ break;
+ }
+ }
+ if (-1 == index)
+ return false;
+ index = index + direction;
+ if (index < 0 || index >= this.pods.length)
+ return false;
+ this.selectPod(this.pods[index]);
return true;
}
- return false;
- }
-
- // Check if the entire of given indexed row can be shown in the viewport.
- if (itemHeight <= clientHeight) {
- if (top < scrollTop)
- return scrollToAdjustTop();
- if (scrollTop + clientHeight < top + itemHeight)
- return scrollToAdjustBottom();
- } else {
- if (scrollTop < top)
- return scrollToAdjustTop();
- if (top + itemHeight < scrollTop + clientHeight)
- return scrollToAdjustBottom();
- }
- return false;
- },
-
- /**
- * @param {Element} podToSelect - pod to select, can be null.
- */
- selectPod: function(podToSelect) {
- if ((this.selectedPod_ == podToSelect) && !!podToSelect) {
- return;
- }
- this.selectedPod_ = podToSelect;
- for (var i = 0; i < this.pods.length; i++) {
- var pod = this.pods[i];
- if (pod != podToSelect)
- pod.classList.remove('focused');
- }
- if (!podToSelect)
- return;
- podToSelect.classList.add('focused');
- podToSelect.focus();
- var screen = $('supervised-user-creation');
- if (!this.selectedPod_) {
- screen.getScreenButton('import').disabled = true;
- } else {
- screen.getScreenButton('import').disabled =
- this.selectedPod_.user.exists;
- if (!this.selectedPod_.user.exists) {
- chrome.send('userSelectedForImportInSupervisedUserCreationFlow',
- [podToSelect.user.id]);
- }
- }
- },
-
- selectNextPod: function(direction) {
- if (!this.selectedPod_)
- return false;
- var index = -1;
- for (var i = 0, pod; pod = this.pods[i]; ++i) {
- if (pod == this.selectedPod_) {
- index = i;
- break;
- }
- }
- if (-1 == index)
- return false;
- index = index + direction;
- if (index < 0 || index >= this.pods.length)
- return false;
- this.selectPod(this.pods[index]);
- return true;
- },
-
- selectUser: function(user_id) {
- for (var i = 0, pod; pod = this.pods[i]; ++i) {
- if (pod.user.id == user_id) {
- this.selectPod(pod);
- this.scrollIntoView(pod);
- break;
- }
- }
- },
- };
-
- return {
- EXTERNAL_API: [
- 'loadManagers',
- 'setCameraPresent',
- 'setDefaultImages',
- 'setExistingSupervisedUsers',
- 'showErrorPage',
- 'showIntroPage',
- 'showManagerPage',
- 'showManagerPasswordError',
- 'showPage',
- 'showPasswordError',
- 'showProgress',
- 'showStatusError',
- 'showTutorialPage',
- 'showUsernamePage',
- 'supervisedUserNameError',
- 'supervisedUserNameOk',
- 'supervisedUserSuggestImport',
- ],
-
- lastVerifiedName_: null,
- lastIncorrectUserName_: null,
- managerList_: null,
- importList_: null,
-
- currentPage_: null,
- imagesRequested_: false,
-
- // Contains data that can be auto-shared with handler.
- context_: {},
-
- /** @override */
- decorate: function() {
- this.managerList_ = new ManagerPodList();
- $('supervised-user-creation-managers-pane').appendChild(
- this.managerList_);
-
- this.importList_ = new ImportPodList();
- $('supervised-user-creation-import-pane').appendChild(this.importList_);
-
- var userNameField = $('supervised-user-creation-name');
- var passwordField = $('supervised-user-creation-password');
- var password2Field = $('supervised-user-creation-password-confirm');
-
- var creationScreen = this;
-
- var hideUserPasswordError = function(element) {
- $('bubble').hide();
- $('supervised-user-creation-password').classList.remove(
- 'password-error');
};
- this.configureTextInput(userNameField,
- this.checkUserName_.bind(this),
- this.validIfNotEmpty_.bind(this),
- function(element) {
- passwordField.focus();
- },
- this.clearUserNameError_.bind(this));
- this.configureTextInput(passwordField,
- this.updateNextButtonForUser_.bind(this),
- this.validIfNotEmpty_.bind(this),
- function(element) {
- password2Field.focus();
- },
- hideUserPasswordError);
- this.configureTextInput(password2Field,
- this.updateNextButtonForUser_.bind(this),
- this.validIfNotEmpty_.bind(this),
- function(element) {
- creationScreen.getScreenButton('next').focus();
- },
- hideUserPasswordError);
-
- this.getScreenButton('error').addEventListener('click', function(e) {
- creationScreen.handleErrorButtonPressed_();
- e.stopPropagation();
+ var ImportPod = cr.ui.define(function() {
+ var node =
+ $('supervised-user-creation-import-template').cloneNode(true);
+ node.removeAttribute('id');
+ node.removeAttribute('hidden');
+ return node;
});
- /*
- TODO(antrim) : this is an explicit code duplications with UserImageScreen.
- It should be removed by issue 251179.
- */
- var imageGrid = this.getScreenElement('image-grid');
- UserImagesGrid.decorate(imageGrid);
-
- // Preview image will track the selected item's URL.
- var previewElement = this.getScreenElement('image-preview');
- previewElement.oncontextmenu = function(e) { e.preventDefault(); };
-
- imageGrid.previewElement = previewElement;
- imageGrid.selectionType = 'default';
- imageGrid.flipPhotoElement = this.getScreenElement('flip-photo');
-
- imageGrid.addEventListener('activate',
- this.handleActivate_.bind(this));
- imageGrid.addEventListener('select',
- this.handleSelect_.bind(this));
- imageGrid.addEventListener('phototaken',
- this.handlePhotoTaken_.bind(this));
- imageGrid.addEventListener('photoupdated',
- this.handlePhotoUpdated_.bind(this));
- // Set the title for camera item in the grid.
- imageGrid.setCameraTitles(
- loadTimeData.getString('takePhoto'),
- loadTimeData.getString('photoFromCamera'));
-
- this.getScreenElement('take-photo').addEventListener(
- 'click', this.handleTakePhoto_.bind(this));
- this.getScreenElement('discard-photo').addEventListener(
- 'click', this.handleDiscardPhoto_.bind(this));
-
- // Toggle 'animation' class for the duration of WebKit transition.
- this.getScreenElement('flip-photo').addEventListener(
- 'click', this.handleFlipPhoto_.bind(this));
- this.getScreenElement('image-stream-crop').addEventListener(
- 'transitionend', function(e) {
- previewElement.classList.remove('animation');
+ /**
+ * UI element for displaying single supervised user in list of possible
+ * users for importing existing users.
+ * @type {Object}
+ */
+ ImportPod.prototype = {
+ __proto__: HTMLDivElement.prototype,
+
+ /** @override */
+ decorate: function() {
+ // Mousedown has to be used instead of click to be able to prevent
+ // 'focus' event later.
+ this.addEventListener('mousedown', this.handleMouseDown_.bind(this));
+ var screen = $('supervised-user-creation');
+ var importList = screen.importList_;
+ },
+
+ /**
+ * Updates UI elements from user data.
+ */
+ update: function() {
+ this.imageElement.src = this.user.avatarurl;
+ this.nameElement.textContent = this.user.name;
+ if (this.user.exists) {
+ if (this.user.conflict == 'imported') {
+ this.nameElement.textContent =
+ loadTimeData.getStringF('importUserExists', this.user.name);
+ } else {
+ this.nameElement.textContent = loadTimeData.getStringF(
+ 'importUsernameExists', this.user.name);
+ }
+ }
+ this.classList.toggle('imported', this.user.exists);
+ },
+
+ /**
+ * Gets image element.
+ * @type {!HTMLImageElement}
+ */
+ get imageElement() {
+ return this.querySelector('.import-pod-image');
+ },
+
+ /**
+ * Gets name element.
+ * @type {!HTMLDivElement}
+ */
+ get nameElement() {
+ return this.querySelector('.import-pod-name');
+ },
+
+ /** @override */
+ handleMouseDown_: function(e) {
+ this.parentNode.selectPod(this);
+ // Prevent default so that we don't trigger 'focus' event.
+ e.preventDefault();
+ },
+
+ /**
+ * The user that this pod represents.
+ * @type {Object}
+ */
+ user_: undefined,
+
+ get user() {
+ return this.user_;
+ },
+
+ set user(userDict) {
+ this.user_ = userDict;
+ this.update();
+ },
+ };
+
+ var ImportPodList = cr.ui.define('div');
+
+ /**
+ * UI element for selecting existing supervised user for import.
+ * @type {Object}
+ */
+ ImportPodList.prototype = {
+ __proto__: HTMLDivElement.prototype,
+
+ selectedPod_: null,
+
+ /** @override */
+ decorate: function() {
+ this.setAttribute('tabIndex', 0);
+ this.classList.add('nofocus');
+ var importList = this;
+ var screen = $('supervised-user-creation');
+
+ this.addEventListener('focus', function(e) {
+ if (importList.selectedPod_ == null) {
+ if (importList.pods.length > 0)
+ importList.selectPod(importList.pods[0]);
+ }
});
- this.getScreenElement('image-preview-img').addEventListener(
- 'transitionend', function(e) {
- previewElement.classList.remove('animation');
+
+ this.addEventListener('keydown', function(e) {
+ switch (e.key) {
+ case 'ArrowUp':
+ importList.selectNextPod(-1);
+ e.stopPropagation();
+ break;
+ case 'Enter':
+ if (importList.selectedPod_ != null)
+ screen.importSupervisedUser_();
+ e.stopPropagation();
+ break;
+ case 'ArrowDown':
+ importList.selectNextPod(+1);
+ e.stopPropagation();
+ break;
+ }
});
+ },
+
+ /**
+ * Returns all the pods in this pod list.
+ * @type {NodeList}
+ */
+ get pods() {
+ return this.children;
+ },
+
+ /**
+ * Returns selected pod.
+ * @type {Node}
+ */
+ get selectedPod() {
+ return this.selectedPod_;
+ },
+
+ addPod: function(user) {
+ var importPod = new ImportPod({user: user});
+ this.appendChild(importPod);
+ importPod.update();
+ },
+
+ clearPods: function() {
+ this.innerHTML = '';
+ this.selectedPod_ = null;
+ },
+
+ scrollIntoView: function(pod) {
+ scroller = this.parentNode;
+ var itemHeight = pod.getBoundingClientRect().height;
+ var scrollTop = scroller.scrollTop;
+ var top = pod.offsetTop - scroller.offsetTop;
+ var clientHeight = scroller.clientHeight;
+
+ var self = scroller;
+
+ // Function to adjust the tops of viewport and row.
+ function scrollToAdjustTop() {
+ self.scrollTop = top;
+ return true;
+ }
+ // Function to adjust the bottoms of viewport and row.
+ function scrollToAdjustBottom() {
+ var cs = getComputedStyle(self);
+ var paddingY =
+ parseInt(cs.paddingTop, 10) + parseInt(cs.paddingBottom, 10);
+
+ if (top + itemHeight > scrollTop + clientHeight - paddingY) {
+ self.scrollTop = top + itemHeight - clientHeight + paddingY;
+ return true;
+ }
+ return false;
+ }
- $('supervised-user-creation-navigation').addEventListener('close',
- this.cancel.bind(this));
- },
-
- buttonIds: [],
-
- /**
- * Creates button for adding to controls.
- * @param {string} buttonId -- id for button, have to be unique within
- * screen. Actual id will be prefixed with screen name and appended with
- * '-button'. Use getScreenButton(buttonId) to find it later.
- * @param {string} i18nPrefix -- screen prefix for i18n values.
- * @param {function} callback -- will be called on button press with
- * buttonId parameter.
- * @param {array} pages -- list of pages where this button should be
- * displayed.
- * @param {array} classes -- list of additional CSS classes for button.
- */
- makeButton: function(buttonId, i18nPrefix, callback, pages, classes) {
- var capitalizedId = buttonId.charAt(0).toUpperCase() + buttonId.slice(1);
- this.buttonIds.push(buttonId);
- var result = this.ownerDocument.createElement('button');
- result.id = this.name() + '-' + buttonId + '-button';
- result.classList.add('screen-control-button');
- for (var i = 0; i < classes.length; i++) {
- result.classList.add(classes[i]);
- }
- result.textContent = loadTimeData.
- getString(i18nPrefix + capitalizedId + 'ButtonTitle');
- result.addEventListener('click', function(e) {
- callback(buttonId);
- e.stopPropagation();
- });
- result.pages = pages;
- return result;
- },
-
- /**
- * Simple validator for |configureTextInput|.
- * Element is considered valid if it has any text.
- * @param {Element} element - element to be validated.
- * @return {boolean} - true, if element has any text.
- */
- validIfNotEmpty_: function(element) {
- return (element.value.length > 0);
- },
-
- /**
- * Configure text-input |element|.
- * @param {Element} element - element to be configured.
- * @param {function(element)} inputChangeListener - function that will be
- * called upon any button press/release.
- * @param {function(element)} validator - function that will be called when
- * Enter is pressed. If it returns |true| then advance to next element.
- * @param {function(element)} moveFocus - function that will determine next
- * element and move focus to it.
- * @param {function(element)} errorHider - function that is called upon
- * every button press, so that any associated error can be hidden.
- */
- configureTextInput: function(element,
- inputChangeListener,
- validator,
- moveFocus,
- errorHider) {
- element.addEventListener('keydown', function(e) {
- if (e.key == 'Enter') {
- var dataValid = true;
- if (validator)
- dataValid = validator(element);
- if (!dataValid) {
- element.focus();
+ // Check if the entire of given indexed row can be shown in the
+ // viewport.
+ if (itemHeight <= clientHeight) {
+ if (top < scrollTop)
+ return scrollToAdjustTop();
+ if (scrollTop + clientHeight < top + itemHeight)
+ return scrollToAdjustBottom();
} else {
- if (moveFocus)
- moveFocus(element);
+ if (scrollTop < top)
+ return scrollToAdjustTop();
+ if (top + itemHeight < scrollTop + clientHeight)
+ return scrollToAdjustBottom();
}
- e.stopPropagation();
- return;
- }
- if (errorHider)
- errorHider(element);
- if (inputChangeListener)
- inputChangeListener(element);
- });
- element.addEventListener('keyup', function(e) {
- if (inputChangeListener)
- inputChangeListener(element);
- });
- },
-
- /**
- * Makes element from template.
- * @param {string} templateId -- template will be looked up within screen
- * by class with name "template-<templateId>".
- * @param {string} elementId -- id for result, uinque within screen. Actual
- * id will be prefixed with screen name. Use getScreenElement(id) to find
- * it later.
- */
- makeFromTemplate: function(templateId, elementId) {
- var templateClassName = 'template-' + templateId;
- var templateNode = this.querySelector('.' + templateClassName);
- var screenPrefix = this.name() + '-';
- var result = templateNode.cloneNode(true);
- result.classList.remove(templateClassName);
- result.id = screenPrefix + elementId;
- return result;
- },
-
- /**
- * @param {string} buttonId -- id of button to be found,
- * @return {Element} button created by makeButton with given buttonId.
- */
- getScreenButton: function(buttonId) {
- var fullId = this.name() + '-' + buttonId + '-button';
- return this.getScreenElement(buttonId + '-button');
- },
-
- /**
- * @param {string} elementId -- id of element to be found,
- * @return {Element} button created by makeFromTemplate with elementId.
- */
- getScreenElement: function(elementId) {
- var fullId = this.name() + '-' + elementId;
- return $(fullId);
- },
-
- /**
- * Screen controls.
- * @type {!Array} Array of Buttons.
- */
- get buttons() {
- var links = this.ownerDocument.createElement('div');
- var buttons = this.ownerDocument.createElement('div');
- links.classList.add('controls-links');
- buttons.classList.add('controls-buttons');
-
- var importLink = this.makeFromTemplate('import-supervised-user-link',
- 'import-link');
- importLink.hidden = true;
- links.appendChild(importLink);
-
- var linkElement = importLink.querySelector('.signin-link');
- linkElement.addEventListener('click',
- this.importLinkPressed_.bind(this));
-
- var createLink = this.makeFromTemplate('create-supervised-user-link',
- 'create-link');
- createLink.hidden = true;
- links.appendChild(createLink);
-
- var status = this.makeFromTemplate('status-container', 'status');
- buttons.appendChild(status);
-
- linkElement = createLink.querySelector('.signin-link');
- linkElement.addEventListener('click',
- this.createLinkPressed_.bind(this));
-
- buttons.appendChild(this.makeButton(
- 'start',
- 'supervisedUserCreationFlow',
- this.startButtonPressed_.bind(this),
- ['intro'],
- ['custom-appearance', 'button-fancy', 'button-blue']));
-
- buttons.appendChild(this.makeButton(
- 'prev',
- 'supervisedUserCreationFlow',
- this.prevButtonPressed_.bind(this),
- ['manager'],
- []));
-
- buttons.appendChild(this.makeButton(
- 'next',
- 'supervisedUserCreationFlow',
- this.nextButtonPressed_.bind(this),
- ['manager', 'username'],
- []));
-
- buttons.appendChild(this.makeButton(
- 'import',
- 'supervisedUserCreationFlow',
- this.importButtonPressed_.bind(this),
- ['import', 'import-password'],
- []));
-
- buttons.appendChild(this.makeButton(
- 'gotit',
- 'supervisedUserCreationFlow',
- this.gotItButtonPressed_.bind(this),
- ['created'],
- ['custom-appearance', 'button-fancy', 'button-blue']));
- return [links, buttons];
- },
-
- /**
- * Does sanity check and calls backend with current user name/password pair
- * to authenticate manager. May result in showManagerPasswordError.
- * @private
- */
- validateAndLogInAsManager_: function() {
- var selectedPod = this.managerList_.selectedPod_;
- if (null == selectedPod)
- return;
-
- var managerId = selectedPod.user.username;
- var managerDisplayId = selectedPod.user.emailAddress;
- var managerPassword = selectedPod.passwordElement.value;
- if (managerPassword.length == 0)
- return;
- if (this.disabled)
- return;
- this.disabled = true;
- this.context_.managerId = managerId;
- this.context_.managerDisplayId = managerDisplayId;
- this.context_.managerName = selectedPod.user.displayName;
- chrome.send('authenticateManagerInSupervisedUserCreationFlow',
- [managerId, managerPassword]);
- },
-
- /**
- * Does sanity check and calls backend with user display name/password pair
- * to create a user.
- * @private
- */
- validateAndCreateSupervisedUser_: function() {
- var firstPassword = $('supervised-user-creation-password').value;
- var secondPassword =
- $('supervised-user-creation-password-confirm').value;
- var userName = $('supervised-user-creation-name').value;
- if (firstPassword != secondPassword) {
- this.showPasswordError(loadTimeData.getString(
- 'createSupervisedUserPasswordMismatchError'));
- return;
- }
- if (this.disabled)
- return;
- this.disabled = true;
-
- this.context_.supervisedName = userName;
- chrome.send('specifySupervisedUserCreationFlowUserData',
- [userName, firstPassword]);
- },
-
- /**
- * Does sanity check and calls backend with selected existing supervised
- * user id to import user.
- * @private
- */
- importSupervisedUser_: function() {
- if (this.disabled)
- return;
- if (this.currentPage_ == 'import-password') {
- var firstPassword = this.getScreenElement('password').value;
- var secondPassword = this.getScreenElement('password-confirm').value;
- if (firstPassword != secondPassword) {
- this.showPasswordError(loadTimeData.getString(
- 'createSupervisedUserPasswordMismatchError'));
- return;
- }
- var userId = this.context_.importUserId;
- this.disabled = true;
- chrome.send('importSupervisedUserWithPassword',
- [userId, firstPassword]);
- return;
- } else {
- var selectedPod = this.importList_.selectedPod_;
- if (!selectedPod)
- return;
- var user = selectedPod.user;
- var userId = user.id;
-
- this.context_.importUserId = userId;
- this.context_.supervisedName = user.name;
- this.context_.selectedImageUrl = user.avatarurl;
- if (!user.needPassword) {
- this.disabled = true;
- chrome.send('importSupervisedUser', [userId]);
- } else {
- this.setVisiblePage_('import-password');
- }
- }
- },
-
- /**
- * Calls backend part to check if current user name is valid/not taken.
- * Results in a call to either supervisedUserNameOk or
- * supervisedUserNameError.
- * @private
- */
- checkUserName_: function() {
- var userName = this.getScreenElement('name').value;
-
- // Avoid flickering
- if (userName == this.lastIncorrectUserName_ ||
- userName == this.lastVerifiedName_) {
- return;
- }
- if (userName.length > 0) {
- chrome.send('checkSupervisedUserName', [userName]);
- } else {
- this.nameErrorVisible = false;
- this.lastVerifiedName_ = null;
- this.lastIncorrectUserName_ = null;
- this.updateNextButtonForUser_();
- }
- },
-
- /**
- * Called by backend part in case of successful name validation.
- * @param {string} name - name that was validated.
- */
- supervisedUserNameOk: function(name) {
- this.lastVerifiedName_ = name;
- this.lastIncorrectUserName_ = null;
- if ($('supervised-user-creation-name').value == name)
- this.clearUserNameError_();
- this.updateNextButtonForUser_();
- },
-
- /**
- * Called by backend part in case of name validation failure.
- * @param {string} name - name that was validated.
- * @param {string} errorText - reason why this name is invalid.
- */
- supervisedUserNameError: function(name, errorText) {
- this.disabled = false;
- this.lastIncorrectUserName_ = name;
- this.lastVerifiedName_ = null;
-
- var userNameField = $('supervised-user-creation-name');
- if (userNameField.value == this.lastIncorrectUserName_) {
- this.nameErrorVisible = true;
- $('bubble').showTextForElement(
- $('supervised-user-creation-name'),
- errorText,
- cr.ui.Bubble.Attachment.RIGHT,
- 12, 4);
- this.setButtonDisabledStatus('next', true);
- }
- },
-
- supervisedUserSuggestImport: function(name, user_id) {
- this.disabled = false;
- this.lastIncorrectUserName_ = name;
- this.lastVerifiedName_ = null;
-
- var userNameField = $('supervised-user-creation-name');
- var creationScreen = this;
-
- if (userNameField.value == this.lastIncorrectUserName_) {
- this.nameErrorVisible = true;
- var link = this.ownerDocument.createElement('div');
- link.innerHTML = loadTimeData.getStringF(
- 'importBubbleText',
- '<a class="signin-link" href="#">',
- name,
- '</a>');
- link.querySelector('.signin-link').addEventListener('click',
- function(e) {
- creationScreen.handleSuggestImport_(user_id);
+ return false;
+ },
+
+ /**
+ * @param {Element} podToSelect - pod to select, can be null.
+ */
+ selectPod: function(podToSelect) {
+ if ((this.selectedPod_ == podToSelect) && !!podToSelect) {
+ return;
+ }
+ this.selectedPod_ = podToSelect;
+ for (var i = 0; i < this.pods.length; i++) {
+ var pod = this.pods[i];
+ if (pod != podToSelect)
+ pod.classList.remove('focused');
+ }
+ if (!podToSelect)
+ return;
+ podToSelect.classList.add('focused');
+ podToSelect.focus();
+ var screen = $('supervised-user-creation');
+ if (!this.selectedPod_) {
+ screen.getScreenButton('import').disabled = true;
+ } else {
+ screen.getScreenButton('import').disabled =
+ this.selectedPod_.user.exists;
+ if (!this.selectedPod_.user.exists) {
+ chrome.send(
+ 'userSelectedForImportInSupervisedUserCreationFlow',
+ [podToSelect.user.id]);
+ }
+ }
+ },
+
+ selectNextPod: function(direction) {
+ if (!this.selectedPod_)
+ return false;
+ var index = -1;
+ for (var i = 0, pod; pod = this.pods[i]; ++i) {
+ if (pod == this.selectedPod_) {
+ index = i;
+ break;
+ }
+ }
+ if (-1 == index)
+ return false;
+ index = index + direction;
+ if (index < 0 || index >= this.pods.length)
+ return false;
+ this.selectPod(this.pods[index]);
+ return true;
+ },
+
+ selectUser: function(user_id) {
+ for (var i = 0, pod; pod = this.pods[i]; ++i) {
+ if (pod.user.id == user_id) {
+ this.selectPod(pod);
+ this.scrollIntoView(pod);
+ break;
+ }
+ }
+ },
+ };
+
+ return {
+ EXTERNAL_API: [
+ 'loadManagers',
+ 'setCameraPresent',
+ 'setDefaultImages',
+ 'setExistingSupervisedUsers',
+ 'showErrorPage',
+ 'showIntroPage',
+ 'showManagerPage',
+ 'showManagerPasswordError',
+ 'showPage',
+ 'showPasswordError',
+ 'showProgress',
+ 'showStatusError',
+ 'showTutorialPage',
+ 'showUsernamePage',
+ 'supervisedUserNameError',
+ 'supervisedUserNameOk',
+ 'supervisedUserSuggestImport',
+ ],
+
+ lastVerifiedName_: null,
+ lastIncorrectUserName_: null,
+ managerList_: null,
+ importList_: null,
+
+ currentPage_: null,
+ imagesRequested_: false,
+
+ // Contains data that can be auto-shared with handler.
+ context_: {},
+
+ /** @override */
+ decorate: function() {
+ this.managerList_ = new ManagerPodList();
+ $('supervised-user-creation-managers-pane')
+ .appendChild(this.managerList_);
+
+ this.importList_ = new ImportPodList();
+ $('supervised-user-creation-import-pane')
+ .appendChild(this.importList_);
+
+ var userNameField = $('supervised-user-creation-name');
+ var passwordField = $('supervised-user-creation-password');
+ var password2Field = $('supervised-user-creation-password-confirm');
+
+ var creationScreen = this;
+
+ var hideUserPasswordError = function(element) {
+ $('bubble').hide();
+ $('supervised-user-creation-password')
+ .classList.remove('password-error');
+ };
+
+ this.configureTextInput(
+ userNameField, this.checkUserName_.bind(this),
+ this.validIfNotEmpty_.bind(this), function(element) {
+ passwordField.focus();
+ }, this.clearUserNameError_.bind(this));
+ this.configureTextInput(
+ passwordField, this.updateNextButtonForUser_.bind(this),
+ this.validIfNotEmpty_.bind(this), function(element) {
+ password2Field.focus();
+ }, hideUserPasswordError);
+ this.configureTextInput(
+ password2Field, this.updateNextButtonForUser_.bind(this),
+ this.validIfNotEmpty_.bind(this), function(element) {
+ creationScreen.getScreenButton('next').focus();
+ }, hideUserPasswordError);
+
+ this.getScreenButton('error').addEventListener('click', function(e) {
+ creationScreen.handleErrorButtonPressed_();
+ e.stopPropagation();
+ });
+
+ /*
+ TODO(antrim) : this is an explicit code duplications with
+ UserImageScreen. It should be removed by issue 251179.
+ */
+ var imageGrid = this.getScreenElement('image-grid');
+ UserImagesGrid.decorate(imageGrid);
+
+ // Preview image will track the selected item's URL.
+ var previewElement = this.getScreenElement('image-preview');
+ previewElement.oncontextmenu = function(e) {
+ e.preventDefault();
+ };
+
+ imageGrid.previewElement = previewElement;
+ imageGrid.selectionType = 'default';
+ imageGrid.flipPhotoElement = this.getScreenElement('flip-photo');
+
+ imageGrid.addEventListener(
+ 'activate', this.handleActivate_.bind(this));
+ imageGrid.addEventListener('select', this.handleSelect_.bind(this));
+ imageGrid.addEventListener(
+ 'phototaken', this.handlePhotoTaken_.bind(this));
+ imageGrid.addEventListener(
+ 'photoupdated', this.handlePhotoUpdated_.bind(this));
+ // Set the title for camera item in the grid.
+ imageGrid.setCameraTitles(
+ loadTimeData.getString('takePhoto'),
+ loadTimeData.getString('photoFromCamera'));
+
+ this.getScreenElement('take-photo')
+ .addEventListener('click', this.handleTakePhoto_.bind(this));
+ this.getScreenElement('discard-photo')
+ .addEventListener('click', this.handleDiscardPhoto_.bind(this));
+
+ // Toggle 'animation' class for the duration of WebKit transition.
+ this.getScreenElement('flip-photo')
+ .addEventListener('click', this.handleFlipPhoto_.bind(this));
+ this.getScreenElement('image-stream-crop')
+ .addEventListener('transitionend', function(e) {
+ previewElement.classList.remove('animation');
+ });
+ this.getScreenElement('image-preview-img')
+ .addEventListener('transitionend', function(e) {
+ previewElement.classList.remove('animation');
+ });
+
+ $('supervised-user-creation-navigation')
+ .addEventListener('close', this.cancel.bind(this));
+ },
+
+ buttonIds: [],
+
+ /**
+ * Creates button for adding to controls.
+ * @param {string} buttonId -- id for button, have to be unique within
+ * screen. Actual id will be prefixed with screen name and appended
+ * with
+ * '-button'. Use getScreenButton(buttonId) to find it later.
+ * @param {string} i18nPrefix -- screen prefix for i18n values.
+ * @param {function} callback -- will be called on button press with
+ * buttonId parameter.
+ * @param {array} pages -- list of pages where this button should be
+ * displayed.
+ * @param {array} classes -- list of additional CSS classes for button.
+ */
+ makeButton: function(buttonId, i18nPrefix, callback, pages, classes) {
+ var capitalizedId =
+ buttonId.charAt(0).toUpperCase() + buttonId.slice(1);
+ this.buttonIds.push(buttonId);
+ var result = this.ownerDocument.createElement('button');
+ result.id = this.name() + '-' + buttonId + '-button';
+ result.classList.add('screen-control-button');
+ for (var i = 0; i < classes.length; i++) {
+ result.classList.add(classes[i]);
+ }
+ result.textContent = loadTimeData.getString(
+ i18nPrefix + capitalizedId + 'ButtonTitle');
+ result.addEventListener('click', function(e) {
+ callback(buttonId);
+ e.stopPropagation();
+ });
+ result.pages = pages;
+ return result;
+ },
+
+ /**
+ * Simple validator for |configureTextInput|.
+ * Element is considered valid if it has any text.
+ * @param {Element} element - element to be validated.
+ * @return {boolean} - true, if element has any text.
+ */
+ validIfNotEmpty_: function(element) {
+ return (element.value.length > 0);
+ },
+
+ /**
+ * Configure text-input |element|.
+ * @param {Element} element - element to be configured.
+ * @param {function(element)} inputChangeListener - function that will be
+ * called upon any button press/release.
+ * @param {function(element)} validator - function that will be called when
+ * Enter is pressed. If it returns |true| then advance to next
+ * element.
+ * @param {function(element)} moveFocus - function that will determine next
+ * element and move focus to it.
+ * @param {function(element)} errorHider - function that is called upon
+ * every button press, so that any associated error can be hidden.
+ */
+ configureTextInput: function(
+ element, inputChangeListener, validator, moveFocus, errorHider) {
+ element.addEventListener('keydown', function(e) {
+ if (e.key == 'Enter') {
+ var dataValid = true;
+ if (validator)
+ dataValid = validator(element);
+ if (!dataValid) {
+ element.focus();
+ } else {
+ if (moveFocus)
+ moveFocus(element);
+ }
e.stopPropagation();
- });
- $('bubble').showContentForElement(
- $('supervised-user-creation-name'),
- cr.ui.Bubble.Attachment.RIGHT,
- link,
- 12, 4);
- this.setButtonDisabledStatus('next', true);
- }
- },
-
- /**
- * Clears user name error, if name is no more guaranteed to be invalid.
- * @private
- */
- clearUserNameError_: function() {
- // Avoid flickering
- if ($('supervised-user-creation-name').value ==
+ return;
+ }
+ if (errorHider)
+ errorHider(element);
+ if (inputChangeListener)
+ inputChangeListener(element);
+ });
+ element.addEventListener('keyup', function(e) {
+ if (inputChangeListener)
+ inputChangeListener(element);
+ });
+ },
+
+ /**
+ * Makes element from template.
+ * @param {string} templateId -- template will be looked up within screen
+ * by class with name "template-<templateId>".
+ * @param {string} elementId -- id for result, uinque within screen. Actual
+ * id will be prefixed with screen name. Use getScreenElement(id) to
+ * find it later.
+ */
+ makeFromTemplate: function(templateId, elementId) {
+ var templateClassName = 'template-' + templateId;
+ var templateNode = this.querySelector('.' + templateClassName);
+ var screenPrefix = this.name() + '-';
+ var result = templateNode.cloneNode(true);
+ result.classList.remove(templateClassName);
+ result.id = screenPrefix + elementId;
+ return result;
+ },
+
+ /**
+ * @param {string} buttonId -- id of button to be found,
+ * @return {Element} button created by makeButton with given buttonId.
+ */
+ getScreenButton: function(buttonId) {
+ var fullId = this.name() + '-' + buttonId + '-button';
+ return this.getScreenElement(buttonId + '-button');
+ },
+
+ /**
+ * @param {string} elementId -- id of element to be found,
+ * @return {Element} button created by makeFromTemplate with elementId.
+ */
+ getScreenElement: function(elementId) {
+ var fullId = this.name() + '-' + elementId;
+ return $(fullId);
+ },
+
+ /**
+ * Screen controls.
+ * @type {!Array} Array of Buttons.
+ */
+ get buttons() {
+ var links = this.ownerDocument.createElement('div');
+ var buttons = this.ownerDocument.createElement('div');
+ links.classList.add('controls-links');
+ buttons.classList.add('controls-buttons');
+
+ var importLink = this.makeFromTemplate(
+ 'import-supervised-user-link', 'import-link');
+ importLink.hidden = true;
+ links.appendChild(importLink);
+
+ var linkElement = importLink.querySelector('.signin-link');
+ linkElement.addEventListener(
+ 'click', this.importLinkPressed_.bind(this));
+
+ var createLink = this.makeFromTemplate(
+ 'create-supervised-user-link', 'create-link');
+ createLink.hidden = true;
+ links.appendChild(createLink);
+
+ var status = this.makeFromTemplate('status-container', 'status');
+ buttons.appendChild(status);
+
+ linkElement = createLink.querySelector('.signin-link');
+ linkElement.addEventListener(
+ 'click', this.createLinkPressed_.bind(this));
+
+ buttons.appendChild(this.makeButton(
+ 'start', 'supervisedUserCreationFlow',
+ this.startButtonPressed_.bind(this), ['intro'],
+ ['custom-appearance', 'button-fancy', 'button-blue']));
+
+ buttons.appendChild(this.makeButton(
+ 'prev', 'supervisedUserCreationFlow',
+ this.prevButtonPressed_.bind(this), ['manager'], []));
+
+ buttons.appendChild(this.makeButton(
+ 'next', 'supervisedUserCreationFlow',
+ this.nextButtonPressed_.bind(this), ['manager', 'username'], []));
+
+ buttons.appendChild(this.makeButton(
+ 'import', 'supervisedUserCreationFlow',
+ this.importButtonPressed_.bind(this),
+ ['import', 'import-password'], []));
+
+ buttons.appendChild(this.makeButton(
+ 'gotit', 'supervisedUserCreationFlow',
+ this.gotItButtonPressed_.bind(this), ['created'],
+ ['custom-appearance', 'button-fancy', 'button-blue']));
+ return [links, buttons];
+ },
+
+ /**
+ * Does sanity check and calls backend with current user name/password
+ * pair to authenticate manager. May result in showManagerPasswordError.
+ * @private
+ */
+ validateAndLogInAsManager_: function() {
+ var selectedPod = this.managerList_.selectedPod_;
+ if (null == selectedPod)
+ return;
+
+ var managerId = selectedPod.user.username;
+ var managerDisplayId = selectedPod.user.emailAddress;
+ var managerPassword = selectedPod.passwordElement.value;
+ if (managerPassword.length == 0)
+ return;
+ if (this.disabled)
+ return;
+ this.disabled = true;
+ this.context_.managerId = managerId;
+ this.context_.managerDisplayId = managerDisplayId;
+ this.context_.managerName = selectedPod.user.displayName;
+ chrome.send(
+ 'authenticateManagerInSupervisedUserCreationFlow',
+ [managerId, managerPassword]);
+ },
+
+ /**
+ * Does sanity check and calls backend with user display name/password
+ * pair to create a user.
+ * @private
+ */
+ validateAndCreateSupervisedUser_: function() {
+ var firstPassword = $('supervised-user-creation-password').value;
+ var secondPassword =
+ $('supervised-user-creation-password-confirm').value;
+ var userName = $('supervised-user-creation-name').value;
+ if (firstPassword != secondPassword) {
+ this.showPasswordError(loadTimeData.getString(
+ 'createSupervisedUserPasswordMismatchError'));
+ return;
+ }
+ if (this.disabled)
+ return;
+ this.disabled = true;
+
+ this.context_.supervisedName = userName;
+ chrome.send(
+ 'specifySupervisedUserCreationFlowUserData',
+ [userName, firstPassword]);
+ },
+
+ /**
+ * Does sanity check and calls backend with selected existing supervised
+ * user id to import user.
+ * @private
+ */
+ importSupervisedUser_: function() {
+ if (this.disabled)
+ return;
+ if (this.currentPage_ == 'import-password') {
+ var firstPassword = this.getScreenElement('password').value;
+ var secondPassword =
+ this.getScreenElement('password-confirm').value;
+ if (firstPassword != secondPassword) {
+ this.showPasswordError(loadTimeData.getString(
+ 'createSupervisedUserPasswordMismatchError'));
+ return;
+ }
+ var userId = this.context_.importUserId;
+ this.disabled = true;
+ chrome.send(
+ 'importSupervisedUserWithPassword', [userId, firstPassword]);
+ return;
+ } else {
+ var selectedPod = this.importList_.selectedPod_;
+ if (!selectedPod)
+ return;
+ var user = selectedPod.user;
+ var userId = user.id;
+
+ this.context_.importUserId = userId;
+ this.context_.supervisedName = user.name;
+ this.context_.selectedImageUrl = user.avatarurl;
+ if (!user.needPassword) {
+ this.disabled = true;
+ chrome.send('importSupervisedUser', [userId]);
+ } else {
+ this.setVisiblePage_('import-password');
+ }
+ }
+ },
+
+ /**
+ * Calls backend part to check if current user name is valid/not taken.
+ * Results in a call to either supervisedUserNameOk or
+ * supervisedUserNameError.
+ * @private
+ */
+ checkUserName_: function() {
+ var userName = this.getScreenElement('name').value;
+
+ // Avoid flickering
+ if (userName == this.lastIncorrectUserName_ ||
+ userName == this.lastVerifiedName_) {
+ return;
+ }
+ if (userName.length > 0) {
+ chrome.send('checkSupervisedUserName', [userName]);
+ } else {
+ this.nameErrorVisible = false;
+ this.lastVerifiedName_ = null;
+ this.lastIncorrectUserName_ = null;
+ this.updateNextButtonForUser_();
+ }
+ },
+
+ /**
+ * Called by backend part in case of successful name validation.
+ * @param {string} name - name that was validated.
+ */
+ supervisedUserNameOk: function(name) {
+ this.lastVerifiedName_ = name;
+ this.lastIncorrectUserName_ = null;
+ if ($('supervised-user-creation-name').value == name)
+ this.clearUserNameError_();
+ this.updateNextButtonForUser_();
+ },
+
+ /**
+ * Called by backend part in case of name validation failure.
+ * @param {string} name - name that was validated.
+ * @param {string} errorText - reason why this name is invalid.
+ */
+ supervisedUserNameError: function(name, errorText) {
+ this.disabled = false;
+ this.lastIncorrectUserName_ = name;
+ this.lastVerifiedName_ = null;
+
+ var userNameField = $('supervised-user-creation-name');
+ if (userNameField.value == this.lastIncorrectUserName_) {
+ this.nameErrorVisible = true;
+ $('bubble').showTextForElement(
+ $('supervised-user-creation-name'), errorText,
+ cr.ui.Bubble.Attachment.RIGHT, 12, 4);
+ this.setButtonDisabledStatus('next', true);
+ }
+ },
+
+ supervisedUserSuggestImport: function(name, user_id) {
+ this.disabled = false;
+ this.lastIncorrectUserName_ = name;
+ this.lastVerifiedName_ = null;
+
+ var userNameField = $('supervised-user-creation-name');
+ var creationScreen = this;
+
+ if (userNameField.value == this.lastIncorrectUserName_) {
+ this.nameErrorVisible = true;
+ var link = this.ownerDocument.createElement('div');
+ link.innerHTML = loadTimeData.getStringF(
+ 'importBubbleText', '<a class="signin-link" href="#">', name,
+ '</a>');
+ link.querySelector('.signin-link')
+ .addEventListener('click', function(e) {
+ creationScreen.handleSuggestImport_(user_id);
+ e.stopPropagation();
+ });
+ $('bubble').showContentForElement(
+ $('supervised-user-creation-name'),
+ cr.ui.Bubble.Attachment.RIGHT, link, 12, 4);
+ this.setButtonDisabledStatus('next', true);
+ }
+ },
+
+ /**
+ * Clears user name error, if name is no more guaranteed to be invalid.
+ * @private
+ */
+ clearUserNameError_: function() {
+ // Avoid flickering
+ if ($('supervised-user-creation-name').value ==
this.lastIncorrectUserName_) {
- return;
- }
- this.nameErrorVisible = false;
- },
-
- /**
- * Called by backend part in case of password validation failure.
- * @param {string} errorText - reason why this password is invalid.
- */
- showPasswordError: function(errorText) {
- $('bubble').showTextForElement(
- $('supervised-user-creation-password'),
- errorText,
- cr.ui.Bubble.Attachment.RIGHT,
- 12, 4);
- $('supervised-user-creation-password').classList.add('password-error');
- $('supervised-user-creation-password').focus();
- this.disabled = false;
- this.setButtonDisabledStatus('next', true);
- },
-
- /**
- * True if user name error should be displayed.
- * @type {boolean}
- */
- set nameErrorVisible(value) {
- $('supervised-user-creation-name').
- classList.toggle('duplicate-name', value);
- if (!value)
- $('bubble').hide();
- },
-
- /**
- * Updates state of Continue button after minimal checks.
- * @return {boolean} true, if form seems to be valid.
- * @private
- */
- updateNextButtonForManager_: function() {
- var selectedPod = this.managerList_.selectedPod_;
- canProceed = null != selectedPod &&
- selectedPod.passwordElement.value.length > 0;
-
- this.setButtonDisabledStatus('next', !canProceed);
- return canProceed;
- },
-
- /**
- * Updates state of Continue button after minimal checks.
- * @return {boolean} true, if form seems to be valid.
- * @private
- */
- updateNextButtonForUser_: function() {
- var firstPassword = this.getScreenElement('password').value;
- var secondPassword = this.getScreenElement('password-confirm').value;
- var userName = this.getScreenElement('name').value;
-
- var passwordOk = (firstPassword.length > 0) &&
- (firstPassword.length == secondPassword.length);
-
- if (this.currentPage_ == 'import-password') {
- this.setButtonDisabledStatus('import', !passwordOk);
- return passwordOk;
- }
- var imageGrid = this.getScreenElement('image-grid');
- var imageChosen = !(imageGrid.selectionType == 'camera' &&
- imageGrid.cameraLive);
- var canProceed =
- passwordOk &&
- (userName.length > 0) &&
- this.lastVerifiedName_ &&
- (userName == this.lastVerifiedName_) &&
- imageChosen;
-
- this.setButtonDisabledStatus('next', !canProceed);
- return canProceed;
- },
-
- showSelectedManagerPasswordError_: function() {
- var selectedPod = this.managerList_.selectedPod_;
- selectedPod.showPasswordError();
- selectedPod.passwordElement.value = '';
- selectedPod.focusInput();
- this.updateNextButtonForManager_();
- },
-
- /**
- * Enables one particular subpage and hides the rest.
- * @param {string} visiblePage - name of subpage.
- * @private
- */
- setVisiblePage_: function(visiblePage) {
- this.disabled = false;
- this.updateText_();
- $('bubble').hide();
- if (!this.imagesRequested_) {
- chrome.send('supervisedUserGetImages');
- this.imagesRequested_ = true;
- }
- var pageNames = ['intro',
- 'manager',
- 'username',
- 'import',
- 'created',
- 'error'];
- var pageButtons = {'intro' : 'start',
- 'error' : 'error',
- 'import' : 'import',
- 'import-password' : 'import',
- 'created' : 'gotit'};
- this.hideStatus_();
- var pageToDisplay = visiblePage;
- if (visiblePage == 'import-password')
- pageToDisplay = 'username';
-
- for (i in pageNames) {
- var pageName = pageNames[i];
- var page = $('supervised-user-creation-' + pageName);
- page.hidden = (pageName != pageToDisplay);
- if (pageName == pageToDisplay)
- $('step-logo').hidden = page.classList.contains('step-no-logo');
- }
-
- for (i in this.buttonIds) {
- var button = this.getScreenButton(this.buttonIds[i]);
- button.hidden = button.pages.indexOf(visiblePage) < 0;
- button.disabled = false;
- }
-
- this.getScreenElement('import-link').hidden = true;
- this.getScreenElement('create-link').hidden = true;
-
- if (pageButtons[visiblePage])
- this.getScreenButton(pageButtons[visiblePage]).focus();
-
- this.currentPage_ = visiblePage;
-
- if (visiblePage == 'manager' || visiblePage == 'intro') {
- $('supervised-user-creation-password').classList.remove(
- 'password-error');
- if (this.managerList_.pods.length > 0)
- this.managerList_.selectPod(this.managerList_.pods[0]);
- $('login-header-bar').updateUI_();
- }
-
- if (visiblePage == 'username' || visiblePage == 'import-password') {
- var elements = this.getScreenElement(pageToDisplay).
- querySelectorAll('.hide-on-import');
- for (var i = 0; i < elements.length; i++) {
- elements[i].classList.toggle('hidden-on-import',
- visiblePage == 'import-password');
- }
- }
- if (visiblePage == 'username') {
- var imageGrid = this.getScreenElement('image-grid');
- // select some image.
- var selected = this.imagesData_[
- Math.floor(Math.random() * this.imagesData_.length)];
- this.context_.selectedImageUrl = selected.url;
- imageGrid.selectedItemUrl = selected.url;
- chrome.send('supervisedUserSelectImage',
- [selected.url, 'default']);
- this.getScreenElement('image-grid').redraw();
- this.checkUserName_();
- this.updateNextButtonForUser_();
- this.getScreenElement('name').focus();
- this.getScreenElement('import-link').hidden =
- this.importList_.pods.length == 0;
- } else if (visiblePage == 'import-password') {
- var imageGrid = this.getScreenElement('image-grid');
- var selected;
- if ('selectedImageUrl' in this.context_) {
- selected = this.context_.selectedImageUrl;
- } else {
- // select some image.
- selected = this.imagesData_[
- Math.floor(Math.random() * this.imagesData_.length)].url;
- chrome.send('supervisedUserSelectImage',
- [selected, 'default']);
- }
- imageGrid.selectedItemUrl = selected;
- this.getScreenElement('image-grid').redraw();
-
- this.updateNextButtonForUser_();
-
- this.getScreenElement('password').focus();
- this.getScreenElement('import-link').hidden = true;
- } else {
- this.getScreenElement('image-grid').stopCamera();
- }
- if (visiblePage == 'import') {
- this.getScreenElement('create-link').hidden = false;
- this.getScreenButton('import').disabled =
- !this.importList_.selectedPod_ ||
- this.importList_.selectedPod_.user.exists;
- }
- $('supervised-user-creation-navigation').closeVisible =
- (visiblePage != 'created');
-
- chrome.send('currentSupervisedUserPage', [this.currentPage_]);
- },
-
- setButtonDisabledStatus: function(buttonName, status) {
- var button = $('supervised-user-creation-' + buttonName + '-button');
- button.disabled = status;
- },
-
- gotItButtonPressed_: function() {
- chrome.send('finishLocalSupervisedUserCreation');
- },
-
- handleErrorButtonPressed_: function() {
- chrome.send('abortLocalSupervisedUserCreation');
- },
-
- startButtonPressed_: function() {
- this.setVisiblePage_('manager');
- this.setButtonDisabledStatus('next', true);
- },
-
- nextButtonPressed_: function() {
- if (this.currentPage_ == 'manager') {
- this.validateAndLogInAsManager_();
- return;
- }
- if (this.currentPage_ == 'username') {
- this.validateAndCreateSupervisedUser_();
- }
- },
-
- importButtonPressed_: function() {
- this.importSupervisedUser_();
- },
-
- importLinkPressed_: function() {
- this.setVisiblePage_('import');
- },
-
- handleSuggestImport_: function(user_id) {
- this.setVisiblePage_('import');
- this.importList_.selectUser(user_id);
- },
-
- createLinkPressed_: function() {
- this.setVisiblePage_('username');
- this.lastIncorrectUserName_ = null;
- this.lastVerifiedName_ = null;
- this.checkUserName_();
- },
-
- prevButtonPressed_: function() {
- this.setVisiblePage_('intro');
- },
-
- showProgress: function(text) {
- var status = this.getScreenElement('status');
- var statusText = status.querySelector('.id-text');
- statusText.textContent = text;
- statusText.classList.remove('error');
- status.querySelector('.id-spinner').hidden = false;
- status.hidden = false;
- this.getScreenElement('import-link').hidden = true;
- this.getScreenElement('create-link').hidden = true;
- },
-
- showStatusError: function(text) {
- var status = this.getScreenElement('status');
- var statusText = status.querySelector('.id-text');
- statusText.textContent = text;
- statusText.classList.add('error');
- status.querySelector('.id-spinner').hidden = true;
- status.hidden = false;
- this.getScreenElement('import-link').hidden = true;
- this.getScreenElement('create-link').hidden = true;
- },
-
- hideStatus_: function() {
- var status = this.getScreenElement('status');
- status.hidden = true;
- },
-
- /**
- * Updates state of login header so that necessary buttons are displayed.
- */
- onBeforeShow: function(data) {
- $('login-header-bar').signinUIState =
- SIGNIN_UI_STATE.SUPERVISED_USER_CREATION_FLOW;
- if (data['managers']) {
- this.loadManagers(data['managers']);
- }
- var imageGrid = this.getScreenElement('image-grid');
- imageGrid.updateAndFocus();
- },
-
- /**
- * Update state of login header so that necessary buttons are displayed.
- */
- onBeforeHide: function() {
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN;
- this.getScreenElement('image-grid').stopCamera();
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- return $('supervised-user-creation-name');
- },
-
- /**
- * True if the the screen is disabled (handles no user interaction).
- * @type {boolean}
- */
- disabled_: false,
-
- get disabled() {
- return this.disabled_;
- },
-
- set disabled(value) {
- this.disabled_ = value;
- var controls = this.querySelectorAll('button,input');
- for (var i = 0, control; control = controls[i]; ++i) {
- control.disabled = value;
- }
- $('login-header-bar').disabled = value;
- },
-
- /**
- * Called by backend part to propagate list of possible managers.
- * @param {Array} userList - list of users that can be managers.
- */
- loadManagers: function(userList) {
- $('supervised-user-creation-managers-block').hidden = false;
- this.managerList_.clearPods();
- for (var i = 0; i < userList.length; ++i)
- this.managerList_.addPod(userList[i]);
- if (userList.length > 0)
- this.managerList_.selectPod(this.managerList_.pods[0]);
- },
-
- /**
- * Cancels user creation and drops to user screen (either sign).
- */
- cancel: function() {
- var notSignedInPages = ['intro', 'manager'];
- var postCreationPages = ['created'];
- if (notSignedInPages.indexOf(this.currentPage_) >= 0) {
- chrome.send('hideLocalSupervisedUserCreation');
-
- // Make sure no manager password is kept:
- this.managerList_.clearPods();
-
- Oobe.showUserPods();
- return;
- }
- if (postCreationPages.indexOf(this.currentPage_) >= 0) {
- chrome.send('finishLocalSupervisedUserCreation');
- return;
- }
- chrome.send('abortLocalSupervisedUserCreation');
- },
-
- updateText_: function() {
- var managerDisplayId = this.context_.managerDisplayId;
- this.updateElementText_('intro-alternate-text',
- 'createSupervisedUserIntroAlternateText');
- this.updateElementText_('created-text-1',
- 'createSupervisedUserCreatedText1',
- this.context_.supervisedName);
- // TODO(antrim): Move wrapping with strong in grd file, and eliminate this
- //call.
- this.updateElementText_('created-text-2',
- 'createSupervisedUserCreatedText2',
- this.wrapStrong(
- loadTimeData.getString('managementURL')),
- this.context_.supervisedName);
- this.updateElementText_('created-text-3',
- 'createSupervisedUserCreatedText3',
- managerDisplayId);
- this.updateElementText_('name-explanation',
- 'createSupervisedUserNameExplanation',
- managerDisplayId);
- },
-
- wrapStrong: function(original) {
- if (original == undefined)
- return original;
- return '<strong>' + original + '</strong>';
- },
-
- updateElementText_: function(localId, templateName) {
- var args = Array.prototype.slice.call(arguments);
- args.shift();
- this.getScreenElement(localId).innerHTML =
- loadTimeData.getStringF.apply(loadTimeData, args);
- },
-
- showIntroPage: function() {
- $('supervised-user-creation-password').value = '';
- $('supervised-user-creation-password-confirm').value = '';
- $('supervised-user-creation-name').value = '';
-
- this.lastVerifiedName_ = null;
- this.lastIncorrectUserName_ = null;
- this.passwordErrorVisible = false;
- $('supervised-user-creation-password').classList.remove('password-error');
- this.nameErrorVisible = false;
-
- this.setVisiblePage_('intro');
- },
-
- showManagerPage: function() {
- this.setVisiblePage_('manager');
- },
-
- showUsernamePage: function() {
- this.setVisiblePage_('username');
- },
-
- showTutorialPage: function() {
- this.setVisiblePage_('created');
- },
-
- showPage: function(page) {
- this.setVisiblePage_(page);
- },
-
- showErrorPage: function(errorTitle, errorText, errorButtonText) {
- this.disabled = false;
- $('supervised-user-creation-error-title').innerHTML = errorTitle;
- $('supervised-user-creation-error-text').innerHTML = errorText;
- $('supervised-user-creation-error-button').textContent = errorButtonText;
- this.setVisiblePage_('error');
- },
-
- showManagerPasswordError: function() {
- this.disabled = false;
- this.showSelectedManagerPasswordError_();
- },
-
- /*
- TODO(antrim) : this is an explicit code duplications with UserImageScreen.
- It should be removed by issue 251179.
- */
- /**
- * Currently selected user image index (take photo button is with zero
- * index).
- * @type {number}
- */
- selectedUserImage_: -1,
- imagesData: [],
-
- setDefaultImages: function(imagesData) {
- var imageGrid = this.getScreenElement('image-grid');
- imageGrid.setDefaultImages(imagesData);
- this.imagesData_ = imagesData;
- },
-
-
- handleActivate_: function() {
- var imageGrid = this.getScreenElement('image-grid');
- if (imageGrid.selectedItemUrl == ButtonImages.TAKE_PHOTO) {
- this.handleTakePhoto_();
- return;
- }
- this.nextButtonPressed_();
- },
-
- /**
- * Handles selection change.
- * @param {Event} e Selection change event.
- * @private
- */
- handleSelect_: function(e) {
- var imageGrid = this.getScreenElement('image-grid');
- this.updateNextButtonForUser_();
-
- $('supervised-user-creation-flip-photo').tabIndex =
- (imageGrid.selectionType == 'camera') ? 0 : -1;
- if (imageGrid.cameraLive || imageGrid.selectionType != 'camera')
- imageGrid.previewElement.classList.remove('phototaken');
- else
- imageGrid.previewElement.classList.add('phototaken');
-
- if (!imageGrid.cameraLive || imageGrid.selectionType != 'camera') {
- this.context_.selectedImageUrl = imageGrid.selectedItemUrl;
- chrome.send('supervisedUserSelectImage',
- [imageGrid.selectedItemUrl, imageGrid.selectionType]);
- }
- // Start/stop camera on (de)selection.
- if (!imageGrid.inProgramSelection &&
- imageGrid.selectionType != e.oldSelectionType) {
- if (imageGrid.selectionType == 'camera') {
- // Programmatic selection of camera item is done in
- // startCamera callback where streaming is started by itself.
- imageGrid.startCamera(
- function() {
+ return;
+ }
+ this.nameErrorVisible = false;
+ },
+
+ /**
+ * Called by backend part in case of password validation failure.
+ * @param {string} errorText - reason why this password is invalid.
+ */
+ showPasswordError: function(errorText) {
+ $('bubble').showTextForElement(
+ $('supervised-user-creation-password'), errorText,
+ cr.ui.Bubble.Attachment.RIGHT, 12, 4);
+ $('supervised-user-creation-password')
+ .classList.add('password-error');
+ $('supervised-user-creation-password').focus();
+ this.disabled = false;
+ this.setButtonDisabledStatus('next', true);
+ },
+
+ /**
+ * True if user name error should be displayed.
+ * @type {boolean}
+ */
+ set nameErrorVisible(value) {
+ $('supervised-user-creation-name')
+ .classList.toggle('duplicate-name', value);
+ if (!value)
+ $('bubble').hide();
+ },
+
+ /**
+ * Updates state of Continue button after minimal checks.
+ * @return {boolean} true, if form seems to be valid.
+ * @private
+ */
+ updateNextButtonForManager_: function() {
+ var selectedPod = this.managerList_.selectedPod_;
+ canProceed = null != selectedPod &&
+ selectedPod.passwordElement.value.length > 0;
+
+ this.setButtonDisabledStatus('next', !canProceed);
+ return canProceed;
+ },
+
+ /**
+ * Updates state of Continue button after minimal checks.
+ * @return {boolean} true, if form seems to be valid.
+ * @private
+ */
+ updateNextButtonForUser_: function() {
+ var firstPassword = this.getScreenElement('password').value;
+ var secondPassword = this.getScreenElement('password-confirm').value;
+ var userName = this.getScreenElement('name').value;
+
+ var passwordOk = (firstPassword.length > 0) &&
+ (firstPassword.length == secondPassword.length);
+
+ if (this.currentPage_ == 'import-password') {
+ this.setButtonDisabledStatus('import', !passwordOk);
+ return passwordOk;
+ }
+ var imageGrid = this.getScreenElement('image-grid');
+ var imageChosen =
+ !(imageGrid.selectionType == 'camera' && imageGrid.cameraLive);
+ var canProceed = passwordOk && (userName.length > 0) &&
+ this.lastVerifiedName_ && (userName == this.lastVerifiedName_) &&
+ imageChosen;
+
+ this.setButtonDisabledStatus('next', !canProceed);
+ return canProceed;
+ },
+
+ showSelectedManagerPasswordError_: function() {
+ var selectedPod = this.managerList_.selectedPod_;
+ selectedPod.showPasswordError();
+ selectedPod.passwordElement.value = '';
+ selectedPod.focusInput();
+ this.updateNextButtonForManager_();
+ },
+
+ /**
+ * Enables one particular subpage and hides the rest.
+ * @param {string} visiblePage - name of subpage.
+ * @private
+ */
+ setVisiblePage_: function(visiblePage) {
+ this.disabled = false;
+ this.updateText_();
+ $('bubble').hide();
+ if (!this.imagesRequested_) {
+ chrome.send('supervisedUserGetImages');
+ this.imagesRequested_ = true;
+ }
+ var pageNames =
+ ['intro', 'manager', 'username', 'import', 'created', 'error'];
+ var pageButtons = {
+ 'intro': 'start',
+ 'error': 'error',
+ 'import': 'import',
+ 'import-password': 'import',
+ 'created': 'gotit'
+ };
+ this.hideStatus_();
+ var pageToDisplay = visiblePage;
+ if (visiblePage == 'import-password')
+ pageToDisplay = 'username';
+
+ for (i in pageNames) {
+ var pageName = pageNames[i];
+ var page = $('supervised-user-creation-' + pageName);
+ page.hidden = (pageName != pageToDisplay);
+ if (pageName == pageToDisplay)
+ $('step-logo').hidden = page.classList.contains('step-no-logo');
+ }
+
+ for (i in this.buttonIds) {
+ var button = this.getScreenButton(this.buttonIds[i]);
+ button.hidden = button.pages.indexOf(visiblePage) < 0;
+ button.disabled = false;
+ }
+
+ this.getScreenElement('import-link').hidden = true;
+ this.getScreenElement('create-link').hidden = true;
+
+ if (pageButtons[visiblePage])
+ this.getScreenButton(pageButtons[visiblePage]).focus();
+
+ this.currentPage_ = visiblePage;
+
+ if (visiblePage == 'manager' || visiblePage == 'intro') {
+ $('supervised-user-creation-password')
+ .classList.remove('password-error');
+ if (this.managerList_.pods.length > 0)
+ this.managerList_.selectPod(this.managerList_.pods[0]);
+ $('login-header-bar').updateUI_();
+ }
+
+ if (visiblePage == 'username' || visiblePage == 'import-password') {
+ var elements = this.getScreenElement(pageToDisplay)
+ .querySelectorAll('.hide-on-import');
+ for (var i = 0; i < elements.length; i++) {
+ elements[i].classList.toggle(
+ 'hidden-on-import', visiblePage == 'import-password');
+ }
+ }
+ if (visiblePage == 'username') {
+ var imageGrid = this.getScreenElement('image-grid');
+ // select some image.
+ var selected = this.imagesData_[Math.floor(
+ Math.random() * this.imagesData_.length)];
+ this.context_.selectedImageUrl = selected.url;
+ imageGrid.selectedItemUrl = selected.url;
+ chrome.send('supervisedUserSelectImage', [selected.url, 'default']);
+ this.getScreenElement('image-grid').redraw();
+ this.checkUserName_();
+ this.updateNextButtonForUser_();
+ this.getScreenElement('name').focus();
+ this.getScreenElement('import-link').hidden =
+ this.importList_.pods.length == 0;
+ } else if (visiblePage == 'import-password') {
+ var imageGrid = this.getScreenElement('image-grid');
+ var selected;
+ if ('selectedImageUrl' in this.context_) {
+ selected = this.context_.selectedImageUrl;
+ } else {
+ // select some image.
+ selected =
+ this.imagesData_[Math.floor(
+ Math.random() * this.imagesData_.length)]
+ .url;
+ chrome.send('supervisedUserSelectImage', [selected, 'default']);
+ }
+ imageGrid.selectedItemUrl = selected;
+ this.getScreenElement('image-grid').redraw();
+
+ this.updateNextButtonForUser_();
+
+ this.getScreenElement('password').focus();
+ this.getScreenElement('import-link').hidden = true;
+ } else {
+ this.getScreenElement('image-grid').stopCamera();
+ }
+ if (visiblePage == 'import') {
+ this.getScreenElement('create-link').hidden = false;
+ this.getScreenButton('import').disabled =
+ !this.importList_.selectedPod_ ||
+ this.importList_.selectedPod_.user.exists;
+ }
+ $('supervised-user-creation-navigation').closeVisible =
+ (visiblePage != 'created');
+
+ chrome.send('currentSupervisedUserPage', [this.currentPage_]);
+ },
+
+ setButtonDisabledStatus: function(buttonName, status) {
+ var button = $('supervised-user-creation-' + buttonName + '-button');
+ button.disabled = status;
+ },
+
+ gotItButtonPressed_: function() {
+ chrome.send('finishLocalSupervisedUserCreation');
+ },
+
+ handleErrorButtonPressed_: function() {
+ chrome.send('abortLocalSupervisedUserCreation');
+ },
+
+ startButtonPressed_: function() {
+ this.setVisiblePage_('manager');
+ this.setButtonDisabledStatus('next', true);
+ },
+
+ nextButtonPressed_: function() {
+ if (this.currentPage_ == 'manager') {
+ this.validateAndLogInAsManager_();
+ return;
+ }
+ if (this.currentPage_ == 'username') {
+ this.validateAndCreateSupervisedUser_();
+ }
+ },
+
+ importButtonPressed_: function() {
+ this.importSupervisedUser_();
+ },
+
+ importLinkPressed_: function() {
+ this.setVisiblePage_('import');
+ },
+
+ handleSuggestImport_: function(user_id) {
+ this.setVisiblePage_('import');
+ this.importList_.selectUser(user_id);
+ },
+
+ createLinkPressed_: function() {
+ this.setVisiblePage_('username');
+ this.lastIncorrectUserName_ = null;
+ this.lastVerifiedName_ = null;
+ this.checkUserName_();
+ },
+
+ prevButtonPressed_: function() {
+ this.setVisiblePage_('intro');
+ },
+
+ showProgress: function(text) {
+ var status = this.getScreenElement('status');
+ var statusText = status.querySelector('.id-text');
+ statusText.textContent = text;
+ statusText.classList.remove('error');
+ status.querySelector('.id-spinner').hidden = false;
+ status.hidden = false;
+ this.getScreenElement('import-link').hidden = true;
+ this.getScreenElement('create-link').hidden = true;
+ },
+
+ showStatusError: function(text) {
+ var status = this.getScreenElement('status');
+ var statusText = status.querySelector('.id-text');
+ statusText.textContent = text;
+ statusText.classList.add('error');
+ status.querySelector('.id-spinner').hidden = true;
+ status.hidden = false;
+ this.getScreenElement('import-link').hidden = true;
+ this.getScreenElement('create-link').hidden = true;
+ },
+
+ hideStatus_: function() {
+ var status = this.getScreenElement('status');
+ status.hidden = true;
+ },
+
+ /**
+ * Updates state of login header so that necessary buttons are
+ * displayed.
+ */
+ onBeforeShow: function(data) {
+ $('login-header-bar').signinUIState =
+ SIGNIN_UI_STATE.SUPERVISED_USER_CREATION_FLOW;
+ if (data['managers']) {
+ this.loadManagers(data['managers']);
+ }
+ var imageGrid = this.getScreenElement('image-grid');
+ imageGrid.updateAndFocus();
+ },
+
+ /**
+ * Update state of login header so that necessary buttons are displayed.
+ */
+ onBeforeHide: function() {
+ $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN;
+ this.getScreenElement('image-grid').stopCamera();
+ },
+
+ /**
+ * Returns a control which should receive an initial focus.
+ */
+ get defaultControl() {
+ return $('supervised-user-creation-name');
+ },
+
+ /**
+ * True if the the screen is disabled (handles no user interaction).
+ * @type {boolean}
+ */
+ disabled_: false,
+
+ get disabled() {
+ return this.disabled_;
+ },
+
+ set disabled(value) {
+ this.disabled_ = value;
+ var controls = this.querySelectorAll('button,input');
+ for (var i = 0, control; control = controls[i]; ++i) {
+ control.disabled = value;
+ }
+ $('login-header-bar').disabled = value;
+ },
+
+ /**
+ * Called by backend part to propagate list of possible managers.
+ * @param {Array} userList - list of users that can be managers.
+ */
+ loadManagers: function(userList) {
+ $('supervised-user-creation-managers-block').hidden = false;
+ this.managerList_.clearPods();
+ for (var i = 0; i < userList.length; ++i)
+ this.managerList_.addPod(userList[i]);
+ if (userList.length > 0)
+ this.managerList_.selectPod(this.managerList_.pods[0]);
+ },
+
+ /**
+ * Cancels user creation and drops to user screen (either sign).
+ */
+ cancel: function() {
+ var notSignedInPages = ['intro', 'manager'];
+ var postCreationPages = ['created'];
+ if (notSignedInPages.indexOf(this.currentPage_) >= 0) {
+ chrome.send('hideLocalSupervisedUserCreation');
+
+ // Make sure no manager password is kept:
+ this.managerList_.clearPods();
+
+ Oobe.showUserPods();
+ return;
+ }
+ if (postCreationPages.indexOf(this.currentPage_) >= 0) {
+ chrome.send('finishLocalSupervisedUserCreation');
+ return;
+ }
+ chrome.send('abortLocalSupervisedUserCreation');
+ },
+
+ updateText_: function() {
+ var managerDisplayId = this.context_.managerDisplayId;
+ this.updateElementText_(
+ 'intro-alternate-text', 'createSupervisedUserIntroAlternateText');
+ this.updateElementText_(
+ 'created-text-1', 'createSupervisedUserCreatedText1',
+ this.context_.supervisedName);
+ // TODO(antrim): Move wrapping with strong in grd file, and eliminate
+ // this
+ // call.
+ this.updateElementText_(
+ 'created-text-2', 'createSupervisedUserCreatedText2',
+ this.wrapStrong(loadTimeData.getString('managementURL')),
+ this.context_.supervisedName);
+ this.updateElementText_(
+ 'created-text-3', 'createSupervisedUserCreatedText3',
+ managerDisplayId);
+ this.updateElementText_(
+ 'name-explanation', 'createSupervisedUserNameExplanation',
+ managerDisplayId);
+ },
+
+ wrapStrong: function(original) {
+ if (original == undefined)
+ return original;
+ return '<strong>' + original + '</strong>';
+ },
+
+ updateElementText_: function(localId, templateName) {
+ var args = Array.prototype.slice.call(arguments);
+ args.shift();
+ this.getScreenElement(localId).innerHTML =
+ loadTimeData.getStringF.apply(loadTimeData, args);
+ },
+
+ showIntroPage: function() {
+ $('supervised-user-creation-password').value = '';
+ $('supervised-user-creation-password-confirm').value = '';
+ $('supervised-user-creation-name').value = '';
+
+ this.lastVerifiedName_ = null;
+ this.lastIncorrectUserName_ = null;
+ this.passwordErrorVisible = false;
+ $('supervised-user-creation-password')
+ .classList.remove('password-error');
+ this.nameErrorVisible = false;
+
+ this.setVisiblePage_('intro');
+ },
+
+ showManagerPage: function() {
+ this.setVisiblePage_('manager');
+ },
+
+ showUsernamePage: function() {
+ this.setVisiblePage_('username');
+ },
+
+ showTutorialPage: function() {
+ this.setVisiblePage_('created');
+ },
+
+ showPage: function(page) {
+ this.setVisiblePage_(page);
+ },
+
+ showErrorPage: function(errorTitle, errorText, errorButtonText) {
+ this.disabled = false;
+ $('supervised-user-creation-error-title').innerHTML = errorTitle;
+ $('supervised-user-creation-error-text').innerHTML = errorText;
+ $('supervised-user-creation-error-button').textContent =
+ errorButtonText;
+ this.setVisiblePage_('error');
+ },
+
+ showManagerPasswordError: function() {
+ this.disabled = false;
+ this.showSelectedManagerPasswordError_();
+ },
+
+ /*
+ TODO(antrim) : this is an explicit code duplications with
+ UserImageScreen. It should be removed by issue 251179.
+ */
+ /**
+ * Currently selected user image index (take photo button is with zero
+ * index).
+ * @type {number}
+ */
+ selectedUserImage_: -1,
+ imagesData: [],
+
+ setDefaultImages: function(imagesData) {
+ var imageGrid = this.getScreenElement('image-grid');
+ imageGrid.setDefaultImages(imagesData);
+ this.imagesData_ = imagesData;
+ },
+
+
+ handleActivate_: function() {
+ var imageGrid = this.getScreenElement('image-grid');
+ if (imageGrid.selectedItemUrl == ButtonImages.TAKE_PHOTO) {
+ this.handleTakePhoto_();
+ return;
+ }
+ this.nextButtonPressed_();
+ },
+
+ /**
+ * Handles selection change.
+ * @param {Event} e Selection change event.
+ * @private
+ */
+ handleSelect_: function(e) {
+ var imageGrid = this.getScreenElement('image-grid');
+ this.updateNextButtonForUser_();
+
+ $('supervised-user-creation-flip-photo').tabIndex =
+ (imageGrid.selectionType == 'camera') ? 0 : -1;
+ if (imageGrid.cameraLive || imageGrid.selectionType != 'camera')
+ imageGrid.previewElement.classList.remove('phototaken');
+ else
+ imageGrid.previewElement.classList.add('phototaken');
+
+ if (!imageGrid.cameraLive || imageGrid.selectionType != 'camera') {
+ this.context_.selectedImageUrl = imageGrid.selectedItemUrl;
+ chrome.send(
+ 'supervisedUserSelectImage',
+ [imageGrid.selectedItemUrl, imageGrid.selectionType]);
+ }
+ // Start/stop camera on (de)selection.
+ if (!imageGrid.inProgramSelection &&
+ imageGrid.selectionType != e.oldSelectionType) {
+ if (imageGrid.selectionType == 'camera') {
+ // Programmatic selection of camera item is done in
+ // startCamera callback where streaming is started by itself.
+ imageGrid.startCamera(function() {
// Start capture if camera is still the selected item.
- $('supervised-user-creation-image-preview-img').classList.
- toggle('animated-transform', true);
+ $('supervised-user-creation-image-preview-img')
+ .classList.toggle('animated-transform', true);
return imageGrid.selectedItem == imageGrid.cameraImage;
});
- } else {
- $('supervised-user-creation-image-preview-img').classList.toggle(
- 'animated-transform', false);
- imageGrid.stopCamera();
- }
- }
- },
-
- /**
- * Handle camera-photo flip.
- */
- handleFlipPhoto_: function() {
- var imageGrid = this.getScreenElement('image-grid');
- imageGrid.previewElement.classList.add('animation');
- imageGrid.flipPhoto = !imageGrid.flipPhoto;
- var flipMessageId = imageGrid.flipPhoto ?
- 'photoFlippedAccessibleText' : 'photoFlippedBackAccessibleText';
- announceAccessibleMessage(loadTimeData.getString(flipMessageId));
- },
-
- /**
- * Handle photo capture from the live camera stream.
- */
- handleTakePhoto_: function(e) {
- this.getScreenElement('image-grid').takePhoto();
- chrome.send('supervisedUserTakePhoto');
- },
-
- handlePhotoTaken_: function(e) {
- chrome.send('supervisedUserPhotoTaken', [e.dataURL]);
- announceAccessibleMessage(
- loadTimeData.getString('photoCaptureAccessibleText'));
- },
-
- /**
- * Handle photo updated event.
- * @param {Event} e Event with 'dataURL' property containing a data URL.
- */
- handlePhotoUpdated_: function(e) {
- chrome.send('supervisedUserPhotoTaken', [e.dataURL]);
- },
-
- /**
- * Handle discarding the captured photo.
- */
- handleDiscardPhoto_: function(e) {
- var imageGrid = this.getScreenElement('image-grid');
- imageGrid.discardPhoto();
- chrome.send('supervisedUserDiscardPhoto');
- announceAccessibleMessage(
- loadTimeData.getString('photoDiscardAccessibleText'));
- },
-
- setCameraPresent: function(present) {
- this.getScreenElement('image-grid').cameraPresent = present;
- },
-
- setExistingSupervisedUsers: function(users) {
- var selectedUser = null;
- // Store selected user
- if (this.importList_.selectedPod)
- selectedUser = this.importList_.selectedPod.user.id;
-
- var userList = users;
- userList.sort(function(a, b) {
- // Put existing users last.
- if (a.exists != b.exists)
- return a.exists ? 1 : -1;
- // Sort rest by name.
- return a.name.localeCompare(b.name, [], {sensitivity: 'base'});
- });
-
- this.importList_.clearPods();
- var selectedIndex = -1;
- for (var i = 0; i < userList.length; ++i) {
- this.importList_.addPod(userList[i]);
- if (selectedUser == userList[i].id)
- selectedIndex = i;
- }
+ } else {
+ $('supervised-user-creation-image-preview-img')
+ .classList.toggle('animated-transform', false);
+ imageGrid.stopCamera();
+ }
+ }
+ },
+
+ /**
+ * Handle camera-photo flip.
+ */
+ handleFlipPhoto_: function() {
+ var imageGrid = this.getScreenElement('image-grid');
+ imageGrid.previewElement.classList.add('animation');
+ imageGrid.flipPhoto = !imageGrid.flipPhoto;
+ var flipMessageId = imageGrid.flipPhoto ?
+ 'photoFlippedAccessibleText' :
+ 'photoFlippedBackAccessibleText';
+ announceAccessibleMessage(loadTimeData.getString(flipMessageId));
+ },
+
+ /**
+ * Handle photo capture from the live camera stream.
+ */
+ handleTakePhoto_: function(e) {
+ this.getScreenElement('image-grid').takePhoto();
+ chrome.send('supervisedUserTakePhoto');
+ },
+
+ handlePhotoTaken_: function(e) {
+ chrome.send('supervisedUserPhotoTaken', [e.dataURL]);
+ announceAccessibleMessage(
+ loadTimeData.getString('photoCaptureAccessibleText'));
+ },
+
+ /**
+ * Handle photo updated event.
+ * @param {Event} e Event with 'dataURL' property containing a data URL.
+ */
+ handlePhotoUpdated_: function(e) {
+ chrome.send('supervisedUserPhotoTaken', [e.dataURL]);
+ },
+
+ /**
+ * Handle discarding the captured photo.
+ */
+ handleDiscardPhoto_: function(e) {
+ var imageGrid = this.getScreenElement('image-grid');
+ imageGrid.discardPhoto();
+ chrome.send('supervisedUserDiscardPhoto');
+ announceAccessibleMessage(
+ loadTimeData.getString('photoDiscardAccessibleText'));
+ },
+
+ setCameraPresent: function(present) {
+ this.getScreenElement('image-grid').cameraPresent = present;
+ },
+
+ setExistingSupervisedUsers: function(users) {
+ var selectedUser = null;
+ // Store selected user
+ if (this.importList_.selectedPod)
+ selectedUser = this.importList_.selectedPod.user.id;
+
+ var userList = users;
+ userList.sort(function(a, b) {
+ // Put existing users last.
+ if (a.exists != b.exists)
+ return a.exists ? 1 : -1;
+ // Sort rest by name.
+ return a.name.localeCompare(b.name, [], {sensitivity: 'base'});
+ });
- if (userList.length == 1)
- this.importList_.selectPod(this.importList_.pods[0]);
+ this.importList_.clearPods();
+ var selectedIndex = -1;
+ for (var i = 0; i < userList.length; ++i) {
+ this.importList_.addPod(userList[i]);
+ if (selectedUser == userList[i].id)
+ selectedIndex = i;
+ }
- if (selectedIndex >= 0)
- this.importList_.selectPod(this.importList_.pods[selectedIndex]);
+ if (userList.length == 1)
+ this.importList_.selectPod(this.importList_.pods[0]);
- if (this.currentPage_ == 'username')
- this.getScreenElement('import-link').hidden = (userList.length == 0);
- },
- };
-});
+ if (selectedIndex >= 0)
+ this.importList_.selectPod(this.importList_.pods[selectedIndex]);
+ if (this.currentPage_ == 'username')
+ this.getScreenElement('import-link').hidden =
+ (userList.length == 0);
+ },
+ };
+ });

Powered by Google App Engine
This is Rietveld 408576698