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

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

Issue 158833003: Represent kiosk apps as user pods instead of menu items. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: launch button, added kiosk error bubble Created 6 years, 10 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/user_pod_row.js
diff --git a/chrome/browser/resources/chromeos/login/user_pod_row.js b/chrome/browser/resources/chromeos/login/user_pod_row.js
index b5090e0424bd942789f72461b2c5e805a467315f..47f0d112b93d535d3bc50885d5cdb209a6a66def 100644
--- a/chrome/browser/resources/chromeos/login/user_pod_row.js
+++ b/chrome/browser/resources/chromeos/login/user_pod_row.js
@@ -37,8 +37,8 @@ cr.define('login', function() {
var MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER = 2;
/**
- * Variables used for pod placement processing.
- * Width and height should be synced with computed CSS sizes of pods.
+ * Variables used for pod placement processing. Width and height should be
+ * synced with computed CSS sizes of pods.
*/
var POD_WIDTH = 180;
var POD_HEIGHT = 217;
@@ -82,7 +82,7 @@ cr.define('login', function() {
//
// (1) all user pods have tab index 1 so they are traversed first;
// (2) when a user pod is activated, its tab index is set to -1 and its
- // main input field gets focus and tab index 1;
+ // main input field gets focus and tab index 1;
// (3) buttons on the header bar have tab index 2 so they follow user pods;
// (4) Action box buttons have tab index 3 and follow header bar buttons;
// (5) lastly, focus jumps to the Status Area and back to user pods.
@@ -258,14 +258,22 @@ cr.define('login', function() {
},
/**
- * Gets user signin button.
- * @type {!HTMLInputElement}
+ * Gets user sign in button.
+ * @type {!HTMLButtonElement}
*/
get signinButtonElement() {
return this.querySelector('.signin-button');
},
/**
+ * Gets launch app button.
+ * @type {!HTMLButtonElement}
+ */
+ get launchAppButtonElement() {
+ return this.querySelector('.launch-app-button');
+ },
+
+ /**
* Gets action box area.
* @type {!HTMLInputElement}
*/
@@ -363,8 +371,8 @@ cr.define('login', function() {
},
/**
- * Gets the custom button. This button is normally hidden, but can be
- * shown using the chrome.screenlockPrivate API.
+ * Gets the custom button. This button is normally hidden, but can be shown
+ * using the chrome.screenlockPrivate API.
* @type {!HTMLInputElement}
*/
get customButton() {
@@ -394,7 +402,12 @@ cr.define('login', function() {
},
updateActionBoxArea: function() {
- this.actionBoxAreaElement.hidden = this.user_.publicAccount;
+ if (this.user_.publicAccount || this.user_.isApp) {
+ this.actionBoxAreaElement.hidden = true;
+ return;
+ }
+
+ this.actionBoxAreaElement.hidden = false;
this.actionBoxMenuRemoveElement.hidden = !this.user_.canRemove;
this.actionBoxAreaElement.setAttribute(
@@ -540,8 +553,8 @@ cr.define('login', function() {
* Activates the pod.
* @return {boolean} True if activated successfully.
*/
- activate: function() {
- if (!this.signinButtonElement.hidden) {
+ activate: function(e) {
+ if (this.forceOnlineSignin) {
this.showSigninUI();
} else if (!this.passwordElement.value) {
return false;
@@ -718,7 +731,7 @@ cr.define('login', function() {
if (this.parentNode.disabled)
return;
- if (!this.signinButtonElement.hidden && !this.isActionBoxMenuActive) {
+ if (this.forceOnlineSignin && !this.isActionBoxMenuActive) {
this.showSigninUI();
// Prevent default so that we don't trigger 'focus' event.
e.preventDefault();
@@ -867,7 +880,7 @@ cr.define('login', function() {
},
/** @override */
- activate: function() {
+ activate: function(e) {
this.expanded = true;
this.focusInput();
return true;
@@ -885,9 +898,8 @@ cr.define('login', function() {
},
/**
- * Handle mouse and keyboard events for the learn more button.
- * Triggering the button causes information about public sessions to be
- * shown.
+ * Handle mouse and keyboard events for the learn more button. Triggering
+ * the button causes information about public sessions to be shown.
* @param {Event} event Mouse or keyboard event.
*/
handleLearnMoreEvent: function(event) {
@@ -985,7 +997,7 @@ cr.define('login', function() {
},
/** @override */
- activate: function() {
+ activate: function(e) {
if (this.passwordElement.hidden) {
Oobe.launchUser(this.user.emailAddress, this.user.displayName);
} else if (!this.passwordElement.value) {
@@ -1011,7 +1023,7 @@ cr.define('login', function() {
// If this is an unlocked pod, then open a browser window. Otherwise
// just activate the pod and show the password field.
if (!this.user.needsSignin && !this.isActionBoxMenuActive)
- this.activate();
+ this.activate(e);
},
/** @override */
@@ -1021,6 +1033,110 @@ cr.define('login', function() {
};
/**
+ * Creates a user pod that represents kiosk app.
+ * @constructor
+ * @extends {UserPod}
+ */
+ var AppUserPod = cr.ui.define(function() {
+ var node = UserPod();
+ return node;
+ });
+
+ AppUserPod.prototype = {
+ __proto__: UserPod.prototype,
+
+ /** @override */
+ decorate: function() {
+ UserPod.prototype.decorate.call(this);
+ this.launchAppButtonElement.addEventListener('click',
+ this.activate.bind(this));
+ },
+
+ /** @override */
+ update: function() {
+ this.imageElement.src = this.user.iconUrl;
+ this.imageElement.alt = this.user.label;
+ this.passwordElement.hidden = true;
+ this.signinButtonElement.hidden = true;
+ this.launchAppButtonElement.hidden = false;
+ this.signedInIndicatorElement.hidden = true;
+ this.nameElement.textContent = this.user.label;
+ },
+
+ /** @override */
+ get mainInput() {
+ return this.launchAppButtonElement;
+ },
+
+ /** @override */
+ focusInput: function() {
+ this.signinButtonElement.hidden = true;
+ this.launchAppButtonElement.hidden = false;
+ this.passwordElement.hidden = true;
+
+ // Move tabIndex from the whole pod to the main input.
+ this.tabIndex = -1;
+ this.mainInput.tabIndex = UserPodTabOrder.POD_INPUT;
+ this.mainInput.focus();
+ },
+
+ /** @override */
+ get forceOnlineSignin() {
+ return false;
+ },
+
+ /** @override */
+ activate: function(e) {
+ var diagnosticMode = e.originalEvent && e.originalEvent.ctrlKey;
+ this.launchApp_(this.user, diagnosticMode);
+ return true;
+ },
+
+ /** @override */
+ handleClickOnPod_: function(e) {
+ if (this.parentNode.disabled)
+ return;
+
+ Oobe.clearErrors();
+ this.parentNode.lastFocusedPod_ = this;
+
+ // If this is an unlocked pod, then open a browser window. Otherwise
+ // just activate the pod and show the password field.
+ if (!this.user.needsSignin && !this.isActionBoxMenuActive)
+ this.activate(e);
+ },
+
+ /**
+ * Launch the app. If |diagnosticMode| is true, ask user to confirm.
+ * @param {Object} app App data.
+ * @param {boolean} diagnosticMode Whether to run the app in diagnostic
+ * mode.
+ */
+ launchApp_: function(app, diagnosticMode) {
+ if (!diagnosticMode) {
+ chrome.send('launchKioskApp', [app.id, false]);
+ return;
+ }
+
+ if (!this.confirmDiagnosticMode_) {
+ this.confirmDiagnosticMode_ =
+ new cr.ui.dialogs.ConfirmDialog(document.body);
+ this.confirmDiagnosticMode_.setOkLabel(
+ loadTimeData.getString('confirmKioskAppDiagnosticModeYes'));
+ this.confirmDiagnosticMode_.setCancelLabel(
+ loadTimeData.getString('confirmKioskAppDiagnosticModeNo'));
+ }
+
+ this.confirmDiagnosticMode_.show(
+ loadTimeData.getStringF('confirmKioskAppDiagnosticModeFormat',
+ app.label),
+ function() {
+ chrome.send('launchKioskApp', [app.id, true]);
+ });
+ },
+ };
+
+ /**
* Creates a new pod row element.
* @constructor
* @extends {HTMLDivElement}
@@ -1048,6 +1164,15 @@ cr.define('login', function() {
// Pods whose initial images haven't been loaded yet.
podsWithPendingImages_: [],
+ // Whether pod creation is animated.
+ user_add_is_animated_: false,
+
+ // Array of apps that are shown in addition to other user pods.
+ apps_: [],
+
+ // Array of users that are shown (public/supervised/regular).
+ users_: [],
+
/** @override */
decorate: function() {
// Event listeners that are installed for the time period during which
@@ -1080,7 +1205,7 @@ cr.define('login', function() {
* Returns pod with the given username (null if there is no such pod).
* @param {string} username Username to be matched.
* @return {Object} Pod with the given username. null if pod hasn't been
- * found.
+ * found.
xiyuan 2014/02/10 21:15:56 nit: should 4-space indent from @ at previous line
Nikita (slow) 2014/02/12 17:19:25 Done.
*/
getPodWithUsername_: function(username) {
for (var i = 0, pod; pod = this.pods[i]; ++i) {
@@ -1108,7 +1233,7 @@ cr.define('login', function() {
/**
* Creates a user pod from given email.
- * @param {string} email User's email.
+ * @param {!Object} user User info dictionary.
*/
createUserPod: function(user) {
var userPod;
@@ -1116,6 +1241,8 @@ cr.define('login', function() {
userPod = new DesktopUserPod({user: user});
else if (user.publicAccount)
userPod = new PublicAccountUserPod({user: user});
+ else if (user.isApp)
+ userPod = new AppUserPod({user: user});
else
userPod = new UserPod({user: user});
@@ -1202,6 +1329,17 @@ cr.define('login', function() {
* @param {boolean} animated Whether to use init animation.
*/
loadPods: function(users, animated) {
+ this.users_ = users;
+ this.user_add_is_animated_ = animated;
+
+ this.rebuildPods();
+ },
+
+ /**
+ * Rebuilds pod row using users_ and apps_ that were previously set or
+ * updated.
+ */
+ rebuildPods: function() {
// Clear existing pods.
this.innerHTML = '';
this.focusedPod_ = undefined;
@@ -1212,12 +1350,16 @@ cr.define('login', function() {
Oobe.getInstance().toggleClass('flying-pods', false);
// Populate the pod row.
- for (var i = 0; i < users.length; ++i) {
- this.addUserPod(users[i], animated);
- }
- for (var i = 0, pod; pod = this.pods[i]; ++i) {
+ for (var i = 0; i < this.users_.length; ++i)
+ this.addUserPod(this.users_[i], this.user_add_is_animated_);
+
+ for (var i = 0, pod; pod = this.pods[i]; ++i)
this.podsWithPendingImages_.push(pod);
- }
+
+ // TODO: Edge case handling when kiosk apps are not fitting.
+ for (var i = 0; i < this.apps_.length; ++i)
+ this.addUserPod(this.apps_[i], this.user_add_is_animated_);
+
// Make sure we eventually show the pod row, even if some image is stuck.
setTimeout(function() {
$('pod-row').classList.remove('images-loading');
@@ -1235,6 +1377,21 @@ cr.define('login', function() {
},
/**
+ * Adds given apps to the pod row.
+ * @param {array} apps Array of apps.
+ */
+ setApps: function(apps) {
+ this.apps_ = apps;
+ this.rebuildPods();
+ chrome.send('kioskAppsLoaded');
+
+ // Check whether there's a pending kiosk app error.
+ window.setTimeout(function() {
+ chrome.send('checkKioskAppLaunchError');
+ }, 500);
+ },
+
+ /**
* Shows a button on a user pod with an icon. Clicking on this button
* triggers an event used by the chrome.screenlockPrivate API.
* @param {string} username Username of pod to add button
@@ -1377,7 +1534,7 @@ cr.define('login', function() {
* Focuses a given user pod or clear focus when given null.
* @param {UserPod=} podToFocus User pod to focus (undefined clears focus).
* @param {boolean=} opt_force If true, forces focus update even when
- * podToFocus is already focused.
+ * podToFocus is already focused.
xiyuan 2014/02/10 21:15:56 nit: 4-space indent from @
Nikita (slow) 2014/02/12 17:19:25 Done.
*/
focusPod: function(podToFocus, opt_force) {
if (this.isFocused(podToFocus) && !opt_force) {
@@ -1423,7 +1580,8 @@ cr.define('login', function() {
podToFocus.classList.add('focused');
podToFocus.reset(true); // Reset and give focus.
// focusPod() automatically loads wallpaper
- chrome.send('focusPod', [podToFocus.user.username]);
+ if (!podToFocus.user.isApp)
+ chrome.send('focusPod', [podToFocus.user.username]);
this.firstShown_ = false;
this.lastFocusedPod_ = podToFocus;
}
@@ -1435,7 +1593,7 @@ cr.define('login', function() {
* Focuses a given user pod by index or clear focus when given null.
* @param {int=} podToFocus index of User pod to focus.
* @param {boolean=} opt_force If true, forces focus update even when
- * podToFocus is already focused.
+ * podToFocus is already focused.
xiyuan 2014/02/10 21:15:56 nit: 4-space indent from @
Nikita (slow) 2014/02/12 17:19:25 Done.
*/
focusPodByIndex: function(podToFocus, opt_force) {
if (podToFocus < this.pods.length)

Powered by Google App Engine
This is Rietveld 408576698