Chromium Code Reviews
[email protected] (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(818)

Side by Side Diff: chrome/browser/resources/chromeos/login/display_manager.js

Issue 7980012: [ChromeOS] Reland - Make WebUI login use only needed resources. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6 * @fileoverview Display manager for WebUI OOBE and login.
7 */
8
9 // TODO(xiyuan): Find a better to share those constants.
10 const SCREEN_SIGNIN = 'signin';
11 const SCREEN_GAIA_SIGNIN = 'gaia-signin';
12 const SCREEN_ACCOUNT_PICKER = 'account-picker';
13
14 /* Accelerator identifiers. Must be kept in sync with webui_login_view.cc. */
15 const ACCELERATOR_ACCESSIBILITY = 'accessibility';
16 const ACCELERATOR_CANCEL = 'cancel';
17 const ACCELERATOR_ENROLLMENT = 'enrollment';
18
19 cr.define('cr.ui.login', function() {
20 /**
21 * Constructor a display manager that manages initialization of screens,
22 * transitions, error messages display.
23 *
24 * @constructor
25 */
26 function DisplayManager() {
27 }
28
29 DisplayManager.prototype = {
30 /**
31 * Registered screens.
32 */
33 screens_: [],
34
35 /**
36 * Current OOBE step, index in the screens array.
37 * @type {number}
38 */
39 currentStep_: 0,
40
41 /**
42 * Gets current screen element.
43 * @type {HTMLElement}
44 */
45 get currentScreen() {
46 return $(this.screens_[this.currentStep_]);
47 },
48
49 /**
50 * Hides/shows header (Shutdown/Add User/Cancel buttons).
51 * @param {bool} hidden Whether header is hidden.
52 */
53 set headerHidden(hidden) {
54 $('login-header-bar').hidden = hidden;
55 },
56
57 /**
58 * Handle accelerators.
59 * @param {string} name Accelerator name.
60 */
61 handleAccelerator: function(name) {
62 if (name == ACCELERATOR_ACCESSIBILITY) {
63 chrome.send('toggleAccessibility', []);
64 } else if (name == ACCELERATOR_CANCEL) {
65 if (this.currentScreen.cancel) {
66 this.currentScreen.cancel();
67 }
68 } else if (ACCELERATOR_ENROLLMENT) {
69 var currentStepId = this.screens_[this.currentStep_];
70 if (currentStepId == SCREEN_SIGNIN ||
71 currentStepId == SCREEN_GAIA_SIGNIN) {
72 chrome.send('toggleEnrollmentScreen', []);
73 }
74 }
75 },
76
77 /**
78 * Appends buttons to the button strip.
79 * @param {Array} buttons Array with the buttons to append.
80 */
81 appendButtons_ : function(buttons) {
82 if (buttons) {
83 var buttonStrip = $('button-strip');
84 for (var i = 0; i < buttons.length; ++i) {
85 var button = buttons[i];
86 buttonStrip.appendChild(button);
87 }
88 }
89 },
90
91 /**
92 * Updates a step's css classes to reflect left, current, or right position.
93 * @param {number} stepIndex step index.
94 * @param {string} state one of 'left', 'current', 'right'.
95 */
96 updateStep_: function(stepIndex, state) {
97 var stepId = this.screens_[stepIndex];
98 var step = $(stepId);
99 var header = $('header-' + stepId);
100 var states = [ 'left', 'right', 'current' ];
101 for (var i = 0; i < states.length; ++i) {
102 if (states[i] != state) {
103 step.classList.remove(states[i]);
104 header.classList.remove(states[i]);
105 }
106 }
107 step.classList.add(state);
108 header.classList.add(state);
109 },
110
111 /**
112 * Switches to the next OOBE step.
113 * @param {number} nextStepIndex Index of the next step.
114 */
115 toggleStep_: function(nextStepIndex, screenData) {
116 var currentStepId = this.screens_[this.currentStep_];
117 var nextStepId = this.screens_[nextStepIndex];
118 var oldStep = $(currentStepId);
119 var newStep = $(nextStepId);
120 var newHeader = $('header-' + nextStepId);
121
122 if (oldStep.onBeforeHide)
123 oldStep.onBeforeHide();
124
125 if (newStep.onBeforeShow)
126 newStep.onBeforeShow(screenData);
127
128 newStep.classList.remove('hidden');
129
130 if (this.isOobeUI()) {
131 // Start gliding animation for OOBE steps.
132 if (nextStepIndex > this.currentStep_) {
133 for (var i = this.currentStep_; i < nextStepIndex; ++i)
134 this.updateStep_(i, 'left');
135 this.updateStep_(nextStepIndex, 'current');
136 } else if (nextStepIndex < this.currentStep_) {
137 for (var i = this.currentStep_; i > nextStepIndex; --i)
138 this.updateStep_(i, 'right');
139 this.updateStep_(nextStepIndex, 'current');
140 }
141 } else {
142 // Start fading animation for login display.
143 oldStep.classList.add('faded');
144 newStep.classList.remove('faded');
145 }
146
147 // Adjust inner container height based on new step's height.
148 $('inner-container').style.height = newStep.offsetHeight + 'px';
149
150 if (this.currentStep_ != nextStepIndex &&
151 !oldStep.classList.contains('hidden')) {
152 oldStep.addEventListener('webkitTransitionEnd', function f(e) {
153 oldStep.removeEventListener('webkitTransitionEnd', f);
154 oldStep.classList.add('hidden');
155 });
156 } else {
157 // First screen on OOBE launch.
158 newHeader.classList.remove('right');
159 }
160 this.currentStep_ = nextStepIndex;
161 $('oobe').className = nextStepId;
162 },
163
164 /**
165 * Show screen of given screen id.
166 * @param {Object} screen Screen params dict,
167 * e.g. {id: screenId, data: data}
168 */
169 showScreen: function(screen) {
170 var screenId = screen.id;
171
172 // Show sign-in screen instead of account picker if pod row is empty.
173 if (screenId == SCREEN_ACCOUNT_PICKER && $('pod-row').pods.length == 0) {
174 Oobe.showSigninUI();
175 return;
176 }
177
178 var data = screen.data;
179 var index = this.getScreenIndex_(screenId);
180 if (index >= 0)
181 this.toggleStep_(index, data);
182 $('offline-message').update();
183 },
184
185 /**
186 * Gets index of given screen id in screens_.
187 * @param {string} screenId Id of the screen to look up.
188 * @private
189 */
190 getScreenIndex_: function(screenId) {
191 for (var i = 0; i < this.screens_.length; ++i) {
192 if (this.screens_[i] == screenId)
193 return i;
194 }
195 return -1;
196 },
197
198 /**
199 * Register an oobe screen.
200 * @param {Element} el Decorated screen element.
201 */
202 registerScreen: function(el) {
203 var screenId = el.id;
204 this.screens_.push(screenId);
205
206 var header = document.createElement('span');
207 header.id = 'header-' + screenId;
208 header.className = 'header-section right';
209 header.textContent = el.header ? el.header : '';
210 $('header-sections').appendChild(header);
211
212 var dot = document.createElement('div');
213 dot.id = screenId + '-dot';
214 dot.className = 'progdot';
215 $('progress').appendChild(dot);
216
217 this.appendButtons_(el.buttons);
218 },
219
220 /**
221 * Updates headers and buttons of the screens.
222 * Should be executed on language change.
223 */
224 updateHeadersAndButtons_: function() {
225 $('button-strip').innerHTML = '';
226 for (var i = 0, screenId; screenId = this.screens_[i]; ++i) {
227 var screen = $(screenId);
228 $('header-' + screenId).textContent = screen.header;
229 this.appendButtons_(screen.buttons);
230 }
231 },
232
233 /**
234 * Prepares screens to use in login display.
235 */
236 prepareForLoginDisplay_ : function() {
237 for (var i = 0, screenId; screenId = this.screens_[i]; ++i) {
238 var screen = $(screenId);
239 screen.classList.add('faded');
240 screen.classList.remove('right');
241 screen.classList.remove('left');
242 }
243 },
244
245 /**
246 * Returns true if Oobe UI is shown.
247 */
248 isOobeUI: function() {
249 return !document.body.classList.contains('login-display');
250 }
251 };
252
253 /**
254 * Returns offset (top, left) of the element.
255 * @param {!Element} element HTML element
256 * @return {!Object} The offset (top, left).
257 */
258 DisplayManager.getOffset = function(element) {
259 var x = 0;
260 var y = 0;
261 while(element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) {
262 x += element.offsetLeft - element.scrollLeft;
263 y += element.offsetTop - element.scrollTop;
264 element = element.offsetParent;
265 }
266 return { top: y, left: x };
267 };
268
269 /**
270 * Shows signin UI.
271 * @param {string} opt_email An optional email for signin UI.
272 */
273 DisplayManager.showSigninUI = function(opt_email) {
274 $('add-user-button').hidden = true;
275 $('cancel-add-user-button').hidden = false;
276 $('add-user-header-bar-item').hidden = $('pod-row').pods.length == 0;
277 chrome.send('showAddUser', [opt_email]);
278 };
279
280 /**
281 * Resets sign-in input fields.
282 */
283 DisplayManager.resetSigninUI = function() {
284 var currentScreenId = Oobe.getInstance().currentScreen.id;
285
286 if (localStrings.getString('authType') == 'webui')
287 $(SCREEN_SIGNIN).reset(currentScreenId == SCREEN_SIGNIN);
288 else
289 $(SCREEN_GAIA_SIGNIN).reset(currentScreenId == SCREEN_GAIA_SIGNIN);
290
291 $('pod-row').reset(currentScreenId == SCREEN_ACCOUNT_PICKER);
292 };
293
294 /**
295 * Shows sign-in error bubble.
296 * @param {number} loginAttempts Number of login attemps tried.
297 * @param {string} message Error message to show.
298 * @param {string} link Text to use for help link.
299 * @param {number} helpId Help topic Id associated with help link.
300 */
301 DisplayManager.showSignInError = function(loginAttempts, message, link,
302 helpId) {
303 var currentScreenId = Oobe.getInstance().currentScreen.id;
304 var anchor = undefined;
305 var anchorPos = undefined;
306 if (currentScreenId == SCREEN_SIGNIN) {
307 anchor = $('email');
308
309 // Show email field so that bubble shows up at the right location.
310 $(SCREEN_SIGNIN).reset(true);
311 } else if (currentScreenId == SCREEN_GAIA_SIGNIN) {
312 // Use anchorPos since we won't be able to get the input fields of Gaia.
313 anchorPos = DisplayManager.getOffset(Oobe.getInstance().currentScreen);
314
315 // Ideally, we should just use
316 // anchorPos = DisplayManager.getOffset($('signin-frame'));
317 // to get a good anchor point. However, this always gives (0,0) on
318 // the device.
319 // TODO(xiyuan): Figure out why the above fails and get rid of this.
320 anchorPos.left += 150; // (640 - 340) / 2
321
322 // TODO(xiyuan): Find a reliable way to align with Gaia UI.
323 anchorPos.left += 60;
324 anchorPos.top += 105;
325 } else if (currentScreenId == SCREEN_ACCOUNT_PICKER &&
326 $('pod-row').activated) {
327 const MAX_LOGIN_ATTEMMPTS_IN_POD = 3;
328 if (loginAttempts > MAX_LOGIN_ATTEMMPTS_IN_POD) {
329 Oobe.showSigninUI($('pod-row').activated.user.emailAddress);
330 return;
331 }
332
333 anchor = $('pod-row').activated.mainInput;
334 }
335 if (!anchor && !anchorPos) {
336 console.log('Warning: Failed to find anchor for error :' +
337 message);
338 return;
339 }
340
341 var error = document.createElement('div');
342
343 var messageDiv = document.createElement('div');
344 messageDiv.className = 'error-message';
345 messageDiv.textContent = message;
346 error.appendChild(messageDiv);
347
348 if (link) {
349 messageDiv.classList.add('error-message-padding');
350
351 var helpLink = document.createElement('a');
352 helpLink.href = '#';
353 helpLink.textContent = link;
354 helpLink.onclick = function(e) {
355 chrome.send('launchHelpApp', [helpId]);
356 }
357 error.appendChild(helpLink);
358 }
359
360 if (anchor)
361 $('bubble').showContentForElement(anchor, error);
362 else if (anchorPos)
363 $('bubble').showContentAt(anchorPos.left, anchorPos.top, error);
364 };
365
366 /**
367 * Clears error bubble.
368 */
369 DisplayManager.clearErrors = function() {
370 $('bubble').hide();
371 };
372
373 /**
374 * Sets text content for a div with |labelId|.
375 * @param {string} labelId Id of the label div.
376 * @param {string} labelText Text for the label.
377 */
378 DisplayManager.setLabelText = function(labelId, labelText) {
379 $(labelId).textContent = labelText;
380 };
381
382 // Export
383 return {
384 DisplayManager: DisplayManager
385 };
386 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/chromeos/login/bubble.js ('k') | chrome/browser/resources/chromeos/login/header_bar.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698