• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 The recently closed menu: button, model data, and menu.
7 */
8
9cr.define('ntp', function() {
10  'use strict';
11
12  /**
13   * Returns the text used for a recently closed window.
14   * @param {number} numTabs Number of tabs in the window.
15   * @return {string} The text to use.
16   */
17  function formatTabsText(numTabs) {
18    if (numTabs == 1)
19      return loadTimeData.getString('closedwindowsingle');
20    return loadTimeData.getStringF('closedwindowmultiple', numTabs);
21  }
22
23  var Menu = cr.ui.Menu;
24  var MenuItem = cr.ui.MenuItem;
25  var MenuButton = cr.ui.MenuButton;
26  var RecentMenuButton = cr.ui.define('button');
27
28  RecentMenuButton.prototype = {
29    __proto__: MenuButton.prototype,
30
31    decorate: function() {
32      MenuButton.prototype.decorate.call(this);
33      this.menu = new Menu;
34      cr.ui.decorate(this.menu, Menu);
35      this.menu.classList.add('footer-menu');
36      document.body.appendChild(this.menu);
37
38      this.needsRebuild_ = true;
39      this.anchorType = cr.ui.AnchorType.ABOVE;
40      this.invertLeftRight = true;
41    },
42
43    /**
44     * Shows the menu, first rebuilding it if necessary.
45     * TODO(estade): the right of the menu should align with the right of the
46     * button.
47     * @override
48     */
49    showMenu: function(shouldSetFocus) {
50      if (this.needsRebuild_) {
51        this.menu.textContent = '';
52        this.dataItems_.forEach(this.addItem_, this);
53        this.needsRebuild_ = false;
54      }
55
56      MenuButton.prototype.showMenu.apply(this, arguments);
57    },
58
59    /**
60     * Sets the menu model data.
61     * @param {Array} dataItems Array of objects that describe the apps.
62     */
63    set dataItems(dataItems) {
64      this.dataItems_ = dataItems;
65      this.needsRebuild_ = true;
66      this.hidden = !dataItems.length;
67    },
68
69    /**
70     * Adds an app to the menu.
71     * @param {Object} data An object encapsulating all data about the app.
72     * @private
73     */
74    addItem_: function(data) {
75      var isWindow = data.type == 'window';
76      var a = this.ownerDocument.createElement('a');
77      a.className = 'footer-menu-item';
78      if (isWindow) {
79        a.href = '';
80        a.classList.add('recent-window');
81        a.textContent = formatTabsText(data.tabs.length);
82        a.title = data.tabs.map(function(tab) { return tab.title; }).join('\n');
83      } else {
84        a.href = data.url;
85        a.style.backgroundImage = getFaviconImageSet(data.url);
86        a.textContent = data.title;
87      }
88
89      function onActivated(e) {
90        ntp.logTimeToClick('RecentlyClosed');
91        chrome.send('recordAppLaunchByURL',
92                    [encodeURIComponent(data.url),
93                     ntp.APP_LAUNCH.NTP_RECENTLY_CLOSED]);
94        var index = Array.prototype.indexOf.call(a.parentNode.children, a);
95        var orig = e.originalEvent;
96        var button = 0;
97        if (orig instanceof MouseEvent)
98          button = orig.button;
99        var params = [data.sessionId,
100                      index,
101                      button,
102                      orig.altKey,
103                      orig.ctrlKey,
104                      orig.metaKey,
105                      orig.shiftKey];
106        chrome.send('reopenTab', params);
107
108        e.preventDefault();
109        e.stopPropagation();
110      }
111      a.addEventListener('activate', onActivated);
112      a.addEventListener('click', function(e) { e.preventDefault(); });
113
114      this.menu.appendChild(a);
115      cr.ui.decorate(a, MenuItem);
116    },
117  };
118
119  return {
120    RecentMenuButton: RecentMenuButton,
121  };
122});
123