• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
9cr.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