Home | History | Annotate | Download | only in login
      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