1 // Copyright 2013 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 Kiosk apps menu implementation. 7 */ 8 9 cr.define('login', function() { 10 'use strict'; 11 12 var Menu = cr.ui.Menu; 13 var MenuButton = cr.ui.MenuButton; 14 15 /** 16 * Creates apps menu button. 17 * @constructor 18 * @extends {cr.ui.MenuButton} 19 */ 20 var AppsMenuButton = cr.ui.define('button'); 21 22 AppsMenuButton.prototype = { 23 __proto__: MenuButton.prototype, 24 25 /** 26 * Flag of whether to rebuild the menu. 27 * @type {boolean} 28 * @private 29 */ 30 needsRebuild_: true, 31 32 /** 33 * Array to hold apps info. 34 * @type {Array} 35 */ 36 data_: null, 37 get data() { 38 return this.data_; 39 }, 40 set data(data) { 41 this.data_ = data; 42 this.needsRebuild_ = true; 43 }, 44 45 /** @override */ 46 decorate: function() { 47 MenuButton.prototype.decorate.call(this); 48 this.menu = new Menu; 49 cr.ui.decorate(this.menu, Menu); 50 document.body.appendChild(this.menu); 51 52 this.anchorType = cr.ui.AnchorType.ABOVE; 53 chrome.send('initializeKioskApps'); 54 }, 55 56 /** @override */ 57 showMenu: function(shouldSetFocus) { 58 if (this.needsRebuild_) { 59 this.menu.textContent = ''; 60 this.data_.forEach(this.addItem_, this); 61 this.needsRebuild_ = false; 62 } 63 64 if (this.data.length > 0) 65 MenuButton.prototype.showMenu.apply(this, arguments); 66 }, 67 68 /** 69 * Invoked when apps menu becomes visible. 70 */ 71 didShow: function() { 72 window.setTimeout(function() { 73 if (!$('apps-header-bar-item').hidden) 74 chrome.send('checkKioskAppLaunchError'); 75 }, 500); 76 }, 77 78 findAndRunAppForTesting: function(id, opt_diagnostic_mode) { 79 this.showMenu(true); 80 for (var i = 0; i < this.menu.menuItems.length; i++) { 81 var menuNode = this.menu.menuItems[i]; 82 if (menuNode.appId == id) { 83 var activationEvent = cr.doc.createEvent('Event'); 84 activationEvent.initEvent('activate', true, true); 85 86 if (opt_diagnostic_mode) { 87 var fakeCtrlEnterEvent = cr.doc.createEvent('KeyboardEvent'); 88 fakeCtrlEnterEvent.initKeyboardEvent('keypress', true, true, null, 89 'Enter', 0, 90 true, false, false, false); 91 activationEvent.originalEvent = fakeCtrlEnterEvent; 92 } 93 94 menuNode.dispatchEvent(activationEvent); 95 break; 96 } 97 } 98 }, 99 100 /** 101 * Launch the app. If |diagnosticMode| is true, ask user to confirm. 102 * @param {Object} app App data. 103 * @param {boolean} diagnosticMode Whether to run the app in diagnostic 104 * mode. 105 */ 106 launchApp_: function(app, diagnosticMode) { 107 if (!diagnosticMode) { 108 chrome.send('launchKioskApp', [app.id, false]); 109 return; 110 } 111 112 if (!this.confirmDiagnosticMode_) { 113 this.confirmDiagnosticMode_ = 114 new cr.ui.dialogs.ConfirmDialog(document.body); 115 this.confirmDiagnosticMode_.setOkLabel( 116 loadTimeData.getString('confirmKioskAppDiagnosticModeYes')); 117 this.confirmDiagnosticMode_.setCancelLabel( 118 loadTimeData.getString('confirmKioskAppDiagnosticModeNo')); 119 } 120 121 this.confirmDiagnosticMode_.show( 122 loadTimeData.getStringF('confirmKioskAppDiagnosticModeFormat', 123 app.label), 124 function() { 125 chrome.send('launchKioskApp', [app.id, true]); 126 }); 127 }, 128 129 /** 130 * Adds an app to the menu. 131 * @param {Object} app An app info object. 132 * @private 133 */ 134 addItem_: function(app) { 135 var menuItem = this.menu.addMenuItem(app); 136 menuItem.classList.add('apps-menu-item'); 137 menuItem.appId = app.id; 138 menuItem.addEventListener('activate', function(e) { 139 var diagnosticMode = e.originalEvent && e.originalEvent.ctrlKey; 140 this.launchApp_(app, diagnosticMode); 141 }.bind(this)); 142 } 143 }; 144 145 /** 146 * Sets apps to be displayed in the apps menu. 147 * @param {!Array.<!Object>} apps An array of app info objects. 148 */ 149 AppsMenuButton.setApps = function(apps) { 150 $('show-apps-button').data = apps; 151 $('login-header-bar').hasApps = 152 apps.length > 0 || loadTimeData.getBoolean('kioskAppHasLaunchError'); 153 chrome.send('kioskAppsLoaded'); 154 }; 155 156 /** 157 * Shows the given error message. 158 * @param {!string} message Error message to show. 159 */ 160 AppsMenuButton.showError = function(message) { 161 /** @const */ var BUBBLE_OFFSET = 25; 162 /** @const */ var BUBBLE_PADDING = 12; 163 $('bubble').showTextForElement($('show-apps-button'), 164 message, 165 cr.ui.Bubble.Attachment.TOP, 166 BUBBLE_OFFSET, 167 BUBBLE_PADDING); 168 }; 169 170 171 /** 172 * Runs app with a given id from the list of loaded apps. 173 * @param {!string} id of an app to run. 174 * @param {boolean=} opt_diagnostic_mode Whether to run the app in diagnostic 175 * mode. Default is false. 176 */ 177 AppsMenuButton.runAppForTesting = function(id, opt_diagnostic_mode) { 178 $('show-apps-button').findAndRunAppForTesting(id, opt_diagnostic_mode); 179 }; 180 181 return { 182 AppsMenuButton: AppsMenuButton 183 }; 184 }); 185