1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/** 6 * @fileoverview Out of the box experience flow (OOBE). 7 * This is the main code for the OOBE WebUI implementation. 8 */ 9 10<include src="login_common.js"></include> 11<include src="oobe_screen_eula.js"></include> 12<include src="oobe_screen_network.js"></include> 13<include src="oobe_screen_hid_detection.js"></include> 14<include src="oobe_screen_update.js"></include> 15<include src="oobe_screen_auto_enrollment_check.js"></include> 16 17cr.define('cr.ui.Oobe', function() { 18 return { 19 /** 20 * Setups given "select" element using the list and adds callback. 21 * Creates option groups if needed. 22 * @param {!Element} select Select object to be updated. 23 * @param {!Object} list List of the options to be added. 24 * Elements with optionGroupName are considered option group. 25 * @param {string} callback Callback name which should be send to Chrome or 26 * an empty string if the event listener shouldn't be added. 27 */ 28 setupSelect: function(select, list, callback) { 29 select.innerHTML = ''; 30 var optgroup = select; 31 for (var i = 0; i < list.length; ++i) { 32 var item = list[i]; 33 if (item.optionGroupName) { 34 optgroup = document.createElement('optgroup'); 35 optgroup.label = item.optionGroupName; 36 select.appendChild(optgroup); 37 } else { 38 var option = 39 new Option(item.title, item.value, item.selected, item.selected); 40 optgroup.appendChild(option); 41 } 42 } 43 if (callback) { 44 var sendCallback = function() { 45 chrome.send(callback, [select.options[select.selectedIndex].value]); 46 }; 47 select.addEventListener('blur', sendCallback); 48 select.addEventListener('click', sendCallback); 49 select.addEventListener('keyup', function(event) { 50 var keycodeInterested = [ 51 9, // Tab 52 13, // Enter 53 27, // Escape 54 ]; 55 if (keycodeInterested.indexOf(event.keyCode) >= 0) 56 sendCallback(); 57 }); 58 } 59 }, 60 61 /** 62 * Initializes the OOBE flow. This will cause all C++ handlers to 63 * be invoked to do final setup. 64 */ 65 initialize: function() { 66 cr.ui.login.DisplayManager.initialize(); 67 login.HIDDetectionScreen.register(); 68 login.WrongHWIDScreen.register(); 69 login.NetworkScreen.register(); 70 login.EulaScreen.register(); 71 login.UpdateScreen.register(); 72 login.AutoEnrollmentCheckScreen.register(); 73 login.ResetScreen.register(); 74 login.AutolaunchScreen.register(); 75 login.KioskEnableScreen.register(); 76 login.AccountPickerScreen.register(); 77 login.GaiaSigninScreen.register(); 78 login.UserImageScreen.register(/* lazyInit= */ false); 79 login.ErrorMessageScreen.register(); 80 login.TPMErrorMessageScreen.register(); 81 login.PasswordChangedScreen.register(); 82 login.LocallyManagedUserCreationScreen.register(); 83 login.TermsOfServiceScreen.register(); 84 login.AppLaunchSplashScreen.register(); 85 login.ConfirmPasswordScreen.register(); 86 login.FatalErrorScreen.register(); 87 88 cr.ui.Bubble.decorate($('bubble')); 89 login.HeaderBar.decorate($('login-header-bar')); 90 91 Oobe.initializeA11yMenu(); 92 93 chrome.send('screenStateInitialize'); 94 }, 95 96 /** 97 * Initializes OOBE accessibility menu. 98 */ 99 initializeA11yMenu: function() { 100 cr.ui.Bubble.decorate($('accessibility-menu')); 101 $('connect-accessibility-link').addEventListener( 102 'click', Oobe.handleAccessibilityLinkClick); 103 $('eula-accessibility-link').addEventListener( 104 'click', Oobe.handleAccessibilityLinkClick); 105 $('update-accessibility-link').addEventListener( 106 'click', Oobe.handleAccessibilityLinkClick); 107 // Same behaviour on hitting spacebar. See crbug.com/342991. 108 function reactOnSpace(event) { 109 if (event.keyCode == 32) 110 Oobe.handleAccessibilityLinkClick(event); 111 } 112 $('connect-accessibility-link').addEventListener( 113 'keyup', reactOnSpace); 114 $('eula-accessibility-link').addEventListener( 115 'keyup', reactOnSpace); 116 $('update-accessibility-link').addEventListener( 117 'keyup', reactOnSpace); 118 119 $('high-contrast').addEventListener('click', 120 Oobe.handleHighContrastClick); 121 $('large-cursor').addEventListener('click', 122 Oobe.handleLargeCursorClick); 123 $('spoken-feedback').addEventListener('click', 124 Oobe.handleSpokenFeedbackClick); 125 $('screen-magnifier').addEventListener('click', 126 Oobe.handleScreenMagnifierClick); 127 $('virtual-keyboard').addEventListener('click', 128 Oobe.handleVirtualKeyboardClick); 129 130 // A11y menu should be accessible i.e. disable autohide on any 131 // keydown or click inside menu. 132 $('accessibility-menu').hideOnKeyPress = false; 133 $('accessibility-menu').hideOnSelfClick = false; 134 }, 135 136 /** 137 * Accessibility link handler. 138 */ 139 handleAccessibilityLinkClick: function(e) { 140 /** @const */ var BUBBLE_OFFSET = 5; 141 /** @const */ var BUBBLE_PADDING = 10; 142 $('accessibility-menu').showForElement(e.target, 143 cr.ui.Bubble.Attachment.BOTTOM, 144 BUBBLE_OFFSET, BUBBLE_PADDING); 145 $('accessibility-menu').firstBubbleElement = $('spoken-feedback'); 146 $('accessibility-menu').lastBubbleElement = $('close-accessibility-menu'); 147 if (Oobe.getInstance().currentScreen && 148 Oobe.getInstance().currentScreen.defaultControl) { 149 $('accessibility-menu').elementToFocusOnHide = 150 Oobe.getInstance().currentScreen.defaultControl; 151 } else { 152 // Update screen falls into this category. Since it doesn't have any 153 // controls other than a11y link we don't want that link to receive 154 // focus when screen is shown i.e. defaultControl is not defined. 155 // Focus a11y link instead. 156 $('accessibility-menu').elementToFocusOnHide = e.target; 157 } 158 e.stopPropagation(); 159 }, 160 161 /** 162 * Spoken feedback checkbox handler. 163 */ 164 handleSpokenFeedbackClick: function(e) { 165 chrome.send('enableSpokenFeedback', [$('spoken-feedback').checked]); 166 e.stopPropagation(); 167 }, 168 169 /** 170 * Large cursor checkbox handler. 171 */ 172 handleLargeCursorClick: function(e) { 173 chrome.send('enableLargeCursor', [$('large-cursor').checked]); 174 e.stopPropagation(); 175 }, 176 177 /** 178 * High contrast mode checkbox handler. 179 */ 180 handleHighContrastClick: function(e) { 181 chrome.send('enableHighContrast', [$('high-contrast').checked]); 182 e.stopPropagation(); 183 }, 184 185 /** 186 * Screen magnifier checkbox handler. 187 */ 188 handleScreenMagnifierClick: function(e) { 189 chrome.send('enableScreenMagnifier', [$('screen-magnifier').checked]); 190 e.stopPropagation(); 191 }, 192 193 /** 194 * On-screen keyboard checkbox handler. 195 */ 196 handleVirtualKeyboardClick: function(e) { 197 chrome.send('enableVirtualKeyboard', [$('virtual-keyboard').checked]); 198 e.stopPropagation(); 199 }, 200 201 /** 202 * Sets usage statistics checkbox. 203 * @param {boolean} checked Is the checkbox checked? 204 */ 205 setUsageStats: function(checked) { 206 $('usage-stats').checked = checked; 207 }, 208 209 /** 210 * Set OEM EULA URL. 211 * @param {text} oemEulaUrl OEM EULA URL. 212 */ 213 setOemEulaUrl: function(oemEulaUrl) { 214 if (oemEulaUrl) { 215 $('oem-eula-frame').src = oemEulaUrl; 216 $('eulas').classList.remove('one-column'); 217 } else { 218 $('eulas').classList.add('one-column'); 219 } 220 }, 221 222 /** 223 * Sets TPM password. 224 * @param {text} password TPM password to be shown. 225 */ 226 setTpmPassword: function(password) { 227 $('tpm-busy').hidden = true; 228 229 if (password.length) { 230 $('tpm-password').textContent = password; 231 $('tpm-password').hidden = false; 232 } else { 233 $('tpm-desc').hidden = true; 234 $('tpm-desc-powerwash').hidden = false; 235 } 236 }, 237 238 /** 239 * Refreshes a11y menu state. 240 * @param {!Object} data New dictionary with a11y features state. 241 */ 242 refreshA11yInfo: function(data) { 243 $('high-contrast').checked = data.highContrastEnabled; 244 $('spoken-feedback').checked = data.spokenFeedbackEnabled; 245 $('screen-magnifier').checked = data.screenMagnifierEnabled; 246 $('large-cursor').checked = data.largeCursorEnabled; 247 $('virtual-keyboard').checked = data.virtualKeyboardEnabled; 248 }, 249 250 /** 251 * Reloads content of the page (localized strings, options of the select 252 * controls). 253 * @param {!Object} data New dictionary with i18n values. 254 */ 255 reloadContent: function(data) { 256 // Reload global local strings, process DOM tree again. 257 loadTimeData.overrideValues(data); 258 i18nTemplate.process(document, loadTimeData); 259 260 // Update language and input method menu lists. 261 Oobe.setupSelect($('language-select'), data.languageList, ''); 262 Oobe.setupSelect($('keyboard-select'), data.inputMethodsList, ''); 263 Oobe.setupSelect($('timezone-select'), data.timezoneList, ''); 264 265 // Update localized content of the screens. 266 Oobe.updateLocalizedContent(); 267 }, 268 269 /** 270 * Updates localized content of the screens. 271 * Should be executed on language change. 272 */ 273 updateLocalizedContent: function() { 274 // Buttons, headers and links. 275 Oobe.getInstance().updateLocalizedContent_(); 276 } 277 }; 278}); 279