Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: chrome/browser/resources/ntp4/apps_page.js

Issue 7215035: ntp4: add app context menu (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: embolden first item Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 cr.define('ntp4', function() { 5 cr.define('ntp4', function() {
6 'use strict'; 6 'use strict';
7 7
8 var TilePage = ntp4.TilePage; 8 var localStrings = new LocalStrings;
9
10 var APP_LAUNCH = {
11 // The histogram buckets (keep in sync with extension_constants.h).
12 NTP_APPS_MAXIMIZED: 0,
13 NTP_APPS_COLLAPSED: 1,
14 NTP_APPS_MENU: 2,
15 NTP_MOST_VISITED: 3,
16 NTP_RECENTLY_CLOSED: 4,
17 NTP_APP_RE_ENABLE: 16
18 };
19
20 /**
21 * App context menu. The class is designed to be used as a singleton with
22 * the app that is currently showing a context menu stored in this.app_.
23 * @constructor
24 */
25 function AppContextMenu() {
26 this.__proto__ = AppContextMenu.prototype;
27 this.initialize();
28 };
29 cr.addSingletonGetter(AppContextMenu);
30
31 AppContextMenu.prototype = {
32 initialize: function() {
33 var menu = new cr.ui.Menu;
34 cr.ui.decorate(menu, cr.ui.Menu);
35 menu.classList.add('app-context-menu');
36 this.menu = menu;
37
38 this.launch_ = this.appendMenuItem_();
39 menu.appendChild(cr.ui.MenuItem.createSeparator());
40 this.launchRegularTab_ = this.appendMenuItem_('applaunchtyperegular');
41 this.launchPinnedTab_ = this.appendMenuItem_('applaunchtypepinned');
42 this.launchNewWindow_ = this.appendMenuItem_('applaunchtypewindow');
csilv 2011/06/22 21:21:30 launchNewWindow is not supported on Mac. the apps
43 this.launchFullscreen_ = this.appendMenuItem_('applaunchtypefullscreen');
44 menu.appendChild(cr.ui.MenuItem.createSeparator());
45 this.options_ = this.appendMenuItem_('appoptions');
46 this.uninstall_ = this.appendMenuItem_('appuninstall');
47 menu.appendChild(cr.ui.MenuItem.createSeparator());
48 this.createShortcut_ = this.appendMenuItem_('appcreateshortcut');
csilv 2011/06/22 21:21:30 createShortcut is not support on Mac and ChromeOS.
49
50 this.launch_.addEventListener('activate', this.onLaunch_.bind(this));
51
52 var self = this;
53 this.forAllLaunchTypes_(function(launchTypeButton, id) {
54 launchTypeButton.addEventListener('activate',
55 self.onLaunchTypeChanged_.bind(self));
56 });
57
58 this.options_.addEventListener('activate',
59 this.onShowOptions_.bind(this));
60 this.uninstall_.addEventListener('activate',
61 this.onUninstall_.bind(this));
62 this.createShortcut_.addEventListener('activate',
63 this.onCreateShortcut_.bind(this));
64
65 menu.hidden = true;
66 document.body.appendChild(menu);
67 },
68
69 /**
70 * Appends a menu item to |this.menu_|.
71 * @param {?String} textId If non-null, the ID for the localized string
72 * that acts as the item's label.
73 */
csilv 2011/06/22 21:21:30 add @private to comment
74 appendMenuItem_: function(textId) {
75 var button = cr.doc.createElement('button');
76 this.menu.appendChild(button);
77 cr.ui.decorate(button, cr.ui.MenuItem);
78 if (textId)
79 button.textContent = localStrings.getString(textId);
80 return button;
81 },
82
83 /**
84 * Iterates over all the launch type menu items.
85 * @param {function(cr.ui.MenuItem, number)} f The function to call for each
86 * menu item. The parameters to the function include the menu item and
87 * the associated launch ID.
88 */
csilv 2011/06/22 21:21:30 add @private to doc comment
89 forAllLaunchTypes_: function(f) {
90 // Order matters: index matches launchType id.
91 var launchTypes = [ this.launchPinnedTab_,
92 this.launchRegularTab_,
93 this.launchFullscreen_,
94 this.launchNewWindow_ ];
95
96 for (var i = 0; i < launchTypes.length; ++i) {
97 f(launchTypes[i], i);
98 }
99 },
100
101 /**
102 * Does all the necessary setup to show the menu for the give app.
103 * @param {App} app The App object that will be showing a context menu.
104 */
105 setupForApp: function(app) {
106 this.app_ = app;
107
108 this.launch_.textContent = app.appData.name;
109
110 this.forAllLaunchTypes_(function(launchTypeButton, id) {
111 launchTypeButton.disabled = false;
112 launchTypeButton.checked = app.appData.launch_type == id;
113 });
114
115 this.options_.disabled = !app.appData.options_url;
116 },
117
118 /**
119 * Handlers for menu item activation.
120 * @param {Event} e The activation event.
121 * @private
122 */
123 onLaunch_: function(e) {
124 chrome.send('launchApp', [this.app_.appId, APP_LAUNCH.NTP_APPS_MENU]);
125 },
126 onLaunchTypeChanged_: function(e) {
127 var pressed = e.currentTarget;
128 var app = this.app_;
129 this.forAllLaunchTypes_(function(launchTypeButton, id) {
130 if (launchTypeButton == pressed) {
131 chrome.send('setLaunchType', [app.appId, id]);
132 // Manually update the launch type. We will only get
133 // appsPrefChangedCallback calls after changes to other NTP instances.
134 app.appData.launch_type = id;
135 }
136 });
137 },
138 onShowOptions_: function(e) {
139 window.location = this.app_.appData.options_url;
140 },
141 onUninstall_: function(e) {
142 chrome.send('uninstallApp', [this.app_.appData.id]);
143 },
144 onCreateShortcut_: function(e) {
145 chrome.send('createAppShortcut', [this.app_.appData.id]);
146 },
147 };
9 148
10 /** 149 /**
11 * Creates a new App object. 150 * Creates a new App object.
12 * @param {Object} appData The data object that describes the app. 151 * @param {Object} appData The data object that describes the app.
13 * @constructor 152 * @constructor
14 * @extends {HTMLDivElement} 153 * @extends {HTMLDivElement}
15 */ 154 */
16 function App(appData) { 155 function App(appData) {
17 var el = cr.doc.createElement('div'); 156 var el = cr.doc.createElement('div');
18 el.__proto__ = App.prototype; 157 el.__proto__ = App.prototype;
19 el.appData = appData; 158 el.appData = appData;
20 el.initialize(); 159 el.initialize();
21 160
22 return el; 161 return el;
23 } 162 }
24 163
25 App.prototype = { 164 App.prototype = {
26 __proto__: HTMLDivElement.prototype, 165 __proto__: HTMLDivElement.prototype,
27 166
28 initialize: function() { 167 initialize: function() {
29 assert(this.appData.id, 'Got an app without an ID'); 168 assert(this.appData_.id, 'Got an app without an ID');
30 169
31 this.className = 'app'; 170 this.className = 'app';
32 171
33 var appImg = this.ownerDocument.createElement('img'); 172 var appImg = this.ownerDocument.createElement('img');
34 appImg.src = this.appData.icon_big; 173 appImg.src = this.appData_.icon_big;
35 // We use a mask of the same image so CSS rules can highlight just the 174 // We use a mask of the same image so CSS rules can highlight just the
36 // image when it's touched. 175 // image when it's touched.
37 appImg.style.WebkitMaskImage = url(this.appData.icon_big); 176 appImg.style.WebkitMaskImage = url(this.appData_.icon_big);
38 // We put a click handler just on the app image - so clicking on the 177 // We put a click handler just on the app image - so clicking on the
39 // margins between apps doesn't do anything. 178 // margins between apps doesn't do anything.
40 appImg.addEventListener('click', this.onClick_.bind(this)); 179 appImg.addEventListener('click', this.onClick_.bind(this));
41 this.appendChild(appImg); 180 this.appendChild(appImg);
42 this.appImg_ = appImg; 181 this.appImg_ = appImg;
43 182
44 var appSpan = this.ownerDocument.createElement('span'); 183 var appSpan = this.ownerDocument.createElement('span');
45 appSpan.textContent = this.appData.name; 184 appSpan.textContent = this.appData_.name;
46 this.appendChild(appSpan); 185 this.appendChild(appSpan);
47 186
48 /* TODO(estade): grabber */ 187 this.addEventListener('contextmenu', cr.ui.contextMenuHandler);
188 this.addEventListener('keydown', cr.ui.contextMenuHandler);
189 this.addEventListener('keyup', cr.ui.contextMenuHandler);
49 }, 190 },
50 191
51 /** 192 /**
52 * Set the size and position of the app tile. 193 * Set the size and position of the app tile.
53 * @param {number} size The total size of |this|. 194 * @param {number} size The total size of |this|.
54 * @param {number} x The x-position. 195 * @param {number} x The x-position.
55 * @param {number} y The y-position. 196 * @param {number} y The y-position.
56 * animate. 197 * animate.
57 */ 198 */
58 setBounds: function(size, x, y) { 199 setBounds: function(size, x, y) {
59 this.appImg_.style.width = this.appImg_.style.height = 200 this.appImg_.style.width = this.appImg_.style.height =
60 (size * APP_IMG_SIZE_FRACTION) + 'px'; 201 (size * APP_IMG_SIZE_FRACTION) + 'px';
61 this.style.width = this.style.height = size + 'px'; 202 this.style.width = this.style.height = size + 'px';
62 this.style.left = x + 'px'; 203 this.style.left = x + 'px';
63 this.style.top = y + 'px'; 204 this.style.top = y + 'px';
64 }, 205 },
65 206
66 /** 207 /**
67 * Invoked when an app is clicked 208 * Invoked when an app is clicked
68 * @param {Event} e The click event. 209 * @param {Event} e The click event.
69 * @private 210 * @private
70 */ 211 */
71 onClick_: function(e) { 212 onClick_: function(e) {
72 // Tell chrome to launch the app. 213 var args = [this.appId, APP_LAUNCH.NTP_APPS_MAXIMIZED];
73 var NTP_APPS_MAXIMIZED = 0; 214 args.push(e.altKey, e.ctrlKey, e.metaKey, e.shiftKey, e.button);
74 chrome.send('launchApp', [this.appData.id, NTP_APPS_MAXIMIZED]); 215 chrome.send('launchApp', args);
75 216
76 // Don't allow the click to trigger a link or anything 217 // Don't allow the click to trigger a link or anything
77 e.preventDefault(); 218 e.preventDefault();
78 }, 219 },
79 220
221 /**
222 * The data and preferences for this app.
223 * @type {Object}
224 */
225 set appData(data) {
226 this.appData_ = data;
227 },
228 get appData() {
229 return this.appData_;
230 },
231
80 get appId() { 232 get appId() {
81 return this.appData.id; 233 return this.appData_.id;
234 },
235
236 /**
237 * Returns a pointer to the context menu for this app. All apps share the
238 * singleton AppContextMenu. This function is called by the
239 * ContextMenuHandler in response to the 'contextmenu' event.
240 * @type {cr.ui.Menu}
241 */
242 get contextMenu() {
243 var menu = AppContextMenu.getInstance();
244 menu.setupForApp(this);
245 return menu.menu;
82 }, 246 },
83 }; 247 };
84 248
85 /** 249 /**
86 * Creates a new Link object. This is a stub implementation for now. 250 * Creates a new Link object. This is a stub implementation for now.
87 * @param {Object} data The url and title. 251 * @param {Object} data The url and title.
88 * @constructor 252 * @constructor
89 * @extends {HTMLAnchorElement} 253 * @extends {HTMLAnchorElement}
90 */ 254 */
91 function Link(data) { 255 function Link(data) {
(...skipping 25 matching lines...) Expand all
117 * @param {number} y The y-position. 281 * @param {number} y The y-position.
118 * animate. 282 * animate.
119 */ 283 */
120 setBounds: function(size, x, y) { 284 setBounds: function(size, x, y) {
121 this.style.width = this.style.height = size + 'px'; 285 this.style.width = this.style.height = size + 'px';
122 this.style.left = x + 'px'; 286 this.style.left = x + 'px';
123 this.style.top = y + 'px'; 287 this.style.top = y + 'px';
124 }, 288 },
125 }; 289 };
126 290
291 var TilePage = ntp4.TilePage;
292
127 // The fraction of the app tile size that the icon uses. 293 // The fraction of the app tile size that the icon uses.
128 var APP_IMG_SIZE_FRACTION = 4 / 5; 294 var APP_IMG_SIZE_FRACTION = 4 / 5;
129 295
130 var appsPageGridValues = { 296 var appsPageGridValues = {
131 // The fewest tiles we will show in a row. 297 // The fewest tiles we will show in a row.
132 minColCount: 3, 298 minColCount: 3,
133 // The most tiles we will show in a row. 299 // The most tiles we will show in a row.
134 maxColCount: 6, 300 maxColCount: 6,
135 301
136 // The smallest a tile can be. 302 // The smallest a tile can be.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 } 383 }
218 384
219 chrome.send('reorderApps', [draggedTile.firstChild.appId, appIds]); 385 chrome.send('reorderApps', [draggedTile.firstChild.appId, appIds]);
220 }, 386 },
221 }; 387 };
222 388
223 return { 389 return {
224 AppsPage: AppsPage, 390 AppsPage: AppsPage,
225 }; 391 };
226 }); 392 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698