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

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: response to review comments 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
« no previous file with comments | « chrome/browser/resources/ntp4/apps_page.css ('k') | chrome/browser/resources/ntp4/new_tab.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
Rick Byers 2011/06/23 17:03:36 Did you intend this to be public? this.menu_ inst
Evan Stade 2011/06/23 20:32:08 will do
37
38 this.launch_ = this.appendMenuItem_();
Rick Byers 2011/06/23 17:03:36 personally I like seeing the list somewhere of the
Evan Stade 2011/06/23 20:32:08 We don't really do it in chrome's webui code in ge
39 this.launch_.addEventListener('activate', this.onLaunch_.bind(this));
40
41 menu.appendChild(cr.ui.MenuItem.createSeparator());
42 this.launchRegularTab_ = this.appendMenuItem_('applaunchtyperegular');
43 this.launchPinnedTab_ = this.appendMenuItem_('applaunchtypepinned');
44 if (!cr.isMac)
45 this.launchNewWindow_ = this.appendMenuItem_('applaunchtypewindow');
46 this.launchFullscreen_ = this.appendMenuItem_('applaunchtypefullscreen');
47
48 var self = this;
49 this.forAllLaunchTypes_(function(launchTypeButton, id) {
50 launchTypeButton.addEventListener('activate',
51 self.onLaunchTypeChanged_.bind(self));
52 });
53
54 menu.appendChild(cr.ui.MenuItem.createSeparator());
55 this.options_ = this.appendMenuItem_('appoptions');
56 this.uninstall_ = this.appendMenuItem_('appuninstall');
57 this.options_.addEventListener('activate',
58 this.onShowOptions_.bind(this));
59 this.uninstall_.addEventListener('activate',
60 this.onUninstall_.bind(this));
61
62 if (!cr.isMac && !cr.isChromeOs) {
63 menu.appendChild(cr.ui.MenuItem.createSeparator());
64 this.createShortcut_ = this.appendMenuItem_('appcreateshortcut');
65 this.createShortcut_.addEventListener(
66 'activate', this.onCreateShortcut_.bind(this));
67 }
68
69 menu.hidden = true;
70 document.body.appendChild(menu);
71 },
72
73 /**
74 * Appends a menu item to |this.menu_|.
75 * @param {?String} textId If non-null, the ID for the localized string
76 * that acts as the item's label.
77 */
78 appendMenuItem_: function(textId) {
79 var button = cr.doc.createElement('button');
80 this.menu.appendChild(button);
81 cr.ui.decorate(button, cr.ui.MenuItem);
82 if (textId)
83 button.textContent = localStrings.getString(textId);
84 return button;
85 },
86
87 /**
88 * Iterates over all the launch type menu items.
89 * @param {function(cr.ui.MenuItem, number)} f The function to call for each
90 * menu item. The parameters to the function include the menu item and
91 * the associated launch ID.
92 */
93 forAllLaunchTypes_: function(f) {
94 // Order matters: index matches launchType id.
95 var launchTypes = [ this.launchPinnedTab_,
96 this.launchRegularTab_,
97 this.launchFullscreen_,
98 this.launchNewWindow_ ];
99
100 for (var i = 0; i < launchTypes.length; ++i) {
101 if (!launchTypes[i])
102 continue;
103
104 f(launchTypes[i], i);
105 }
106 },
107
108 /**
109 * Does all the necessary setup to show the menu for the give app.
110 * @param {App} app The App object that will be showing a context menu.
111 */
112 setupForApp: function(app) {
113 this.app_ = app;
114
115 this.launch_.textContent = app.appData.name;
116
117 this.forAllLaunchTypes_(function(launchTypeButton, id) {
118 launchTypeButton.disabled = false;
119 launchTypeButton.checked = app.appData.launch_type == id;
120 });
121
122 this.options_.disabled = !app.appData.options_url;
123 },
124
125 /**
126 * Handlers for menu item activation.
127 * @param {Event} e The activation event.
128 * @private
129 */
130 onLaunch_: function(e) {
131 chrome.send('launchApp', [this.app_.appId, APP_LAUNCH.NTP_APPS_MENU]);
132 },
133 onLaunchTypeChanged_: function(e) {
134 var pressed = e.currentTarget;
135 var app = this.app_;
136 this.forAllLaunchTypes_(function(launchTypeButton, id) {
137 if (launchTypeButton == pressed) {
138 chrome.send('setLaunchType', [app.appId, id]);
139 // Manually update the launch type. We will only get
140 // appsPrefChangedCallback calls after changes to other NTP instances.
141 app.appData.launch_type = id;
142 }
143 });
144 },
145 onShowOptions_: function(e) {
146 window.location = this.app_.appData.options_url;
147 },
148 onUninstall_: function(e) {
149 chrome.send('uninstallApp', [this.app_.appData.id]);
150 },
151 onCreateShortcut_: function(e) {
152 chrome.send('createAppShortcut', [this.app_.appData.id]);
153 },
154 };
9 155
10 /** 156 /**
11 * Creates a new App object. 157 * Creates a new App object.
12 * @param {Object} appData The data object that describes the app. 158 * @param {Object} appData The data object that describes the app.
13 * @constructor 159 * @constructor
14 * @extends {HTMLDivElement} 160 * @extends {HTMLDivElement}
15 */ 161 */
16 function App(appData) { 162 function App(appData) {
17 var el = cr.doc.createElement('div'); 163 var el = cr.doc.createElement('div');
18 el.__proto__ = App.prototype; 164 el.__proto__ = App.prototype;
19 el.appData = appData; 165 el.appData = appData;
20 el.initialize(); 166 el.initialize();
21 167
22 return el; 168 return el;
23 } 169 }
24 170
25 App.prototype = { 171 App.prototype = {
26 __proto__: HTMLDivElement.prototype, 172 __proto__: HTMLDivElement.prototype,
27 173
28 initialize: function() { 174 initialize: function() {
29 assert(this.appData.id, 'Got an app without an ID'); 175 assert(this.appData_.id, 'Got an app without an ID');
30 176
31 this.className = 'app'; 177 this.className = 'app';
32 178
33 var appImg = this.ownerDocument.createElement('img'); 179 var appImg = this.ownerDocument.createElement('img');
34 appImg.src = this.appData.icon_big; 180 appImg.src = this.appData_.icon_big;
35 // We use a mask of the same image so CSS rules can highlight just the 181 // We use a mask of the same image so CSS rules can highlight just the
36 // image when it's touched. 182 // image when it's touched.
37 appImg.style.WebkitMaskImage = url(this.appData.icon_big); 183 appImg.style.WebkitMaskImage = url(this.appData_.icon_big);
38 // We put a click handler just on the app image - so clicking on the 184 // We put a click handler just on the app image - so clicking on the
39 // margins between apps doesn't do anything. 185 // margins between apps doesn't do anything.
40 appImg.addEventListener('click', this.onClick_.bind(this)); 186 appImg.addEventListener('click', this.onClick_.bind(this));
41 this.appendChild(appImg); 187 this.appendChild(appImg);
42 this.appImg_ = appImg; 188 this.appImg_ = appImg;
43 189
44 var appSpan = this.ownerDocument.createElement('span'); 190 var appSpan = this.ownerDocument.createElement('span');
45 appSpan.textContent = this.appData.name; 191 appSpan.textContent = this.appData_.name;
46 this.appendChild(appSpan); 192 this.appendChild(appSpan);
47 193
48 /* TODO(estade): grabber */ 194 this.addEventListener('contextmenu', cr.ui.contextMenuHandler);
195 this.addEventListener('keydown', cr.ui.contextMenuHandler);
196 this.addEventListener('keyup', cr.ui.contextMenuHandler);
49 }, 197 },
50 198
51 /** 199 /**
52 * Set the size and position of the app tile. 200 * Set the size and position of the app tile.
53 * @param {number} size The total size of |this|. 201 * @param {number} size The total size of |this|.
54 * @param {number} x The x-position. 202 * @param {number} x The x-position.
55 * @param {number} y The y-position. 203 * @param {number} y The y-position.
56 * animate. 204 * animate.
57 */ 205 */
58 setBounds: function(size, x, y) { 206 setBounds: function(size, x, y) {
59 this.appImg_.style.width = this.appImg_.style.height = 207 this.appImg_.style.width = this.appImg_.style.height =
60 (size * APP_IMG_SIZE_FRACTION) + 'px'; 208 (size * APP_IMG_SIZE_FRACTION) + 'px';
61 this.style.width = this.style.height = size + 'px'; 209 this.style.width = this.style.height = size + 'px';
62 this.style.left = x + 'px'; 210 this.style.left = x + 'px';
63 this.style.top = y + 'px'; 211 this.style.top = y + 'px';
64 }, 212 },
65 213
66 /** 214 /**
67 * Invoked when an app is clicked 215 * Invoked when an app is clicked
68 * @param {Event} e The click event. 216 * @param {Event} e The click event.
69 * @private 217 * @private
70 */ 218 */
71 onClick_: function(e) { 219 onClick_: function(e) {
72 // Tell chrome to launch the app. 220 var args = [this.appId, APP_LAUNCH.NTP_APPS_MAXIMIZED];
73 var NTP_APPS_MAXIMIZED = 0; 221 args.push(e.altKey, e.ctrlKey, e.metaKey, e.shiftKey, e.button);
Rick Byers 2011/06/23 17:03:36 why initialize the array with some and push the ot
Evan Stade 2011/06/23 20:32:08 you are right. I copied this code from ntp3, and s
74 chrome.send('launchApp', [this.appData.id, NTP_APPS_MAXIMIZED]); 222 chrome.send('launchApp', args);
75 223
76 // Don't allow the click to trigger a link or anything 224 // Don't allow the click to trigger a link or anything
77 e.preventDefault(); 225 e.preventDefault();
78 }, 226 },
79 227
228 /**
229 * The data and preferences for this app.
230 * @type {Object}
231 */
232 set appData(data) {
233 this.appData_ = data;
234 },
235 get appData() {
236 return this.appData_;
237 },
238
80 get appId() { 239 get appId() {
81 return this.appData.id; 240 return this.appData_.id;
241 },
242
243 /**
244 * Returns a pointer to the context menu for this app. All apps share the
245 * singleton AppContextMenu. This function is called by the
246 * ContextMenuHandler in response to the 'contextmenu' event.
247 * @type {cr.ui.Menu}
248 */
249 get contextMenu() {
250 var menu = AppContextMenu.getInstance();
251 menu.setupForApp(this);
252 return menu.menu;
82 }, 253 },
83 }; 254 };
84 255
85 /** 256 /**
86 * Creates a new Link object. This is a stub implementation for now. 257 * Creates a new Link object. This is a stub implementation for now.
87 * @param {Object} data The url and title. 258 * @param {Object} data The url and title.
88 * @constructor 259 * @constructor
89 * @extends {HTMLAnchorElement} 260 * @extends {HTMLAnchorElement}
90 */ 261 */
91 function Link(data) { 262 function Link(data) {
(...skipping 25 matching lines...) Expand all
117 * @param {number} y The y-position. 288 * @param {number} y The y-position.
118 * animate. 289 * animate.
119 */ 290 */
120 setBounds: function(size, x, y) { 291 setBounds: function(size, x, y) {
121 this.style.width = this.style.height = size + 'px'; 292 this.style.width = this.style.height = size + 'px';
122 this.style.left = x + 'px'; 293 this.style.left = x + 'px';
123 this.style.top = y + 'px'; 294 this.style.top = y + 'px';
124 }, 295 },
125 }; 296 };
126 297
298 var TilePage = ntp4.TilePage;
299
127 // The fraction of the app tile size that the icon uses. 300 // The fraction of the app tile size that the icon uses.
128 var APP_IMG_SIZE_FRACTION = 4 / 5; 301 var APP_IMG_SIZE_FRACTION = 4 / 5;
129 302
130 var appsPageGridValues = { 303 var appsPageGridValues = {
131 // The fewest tiles we will show in a row. 304 // The fewest tiles we will show in a row.
132 minColCount: 3, 305 minColCount: 3,
133 // The most tiles we will show in a row. 306 // The most tiles we will show in a row.
134 maxColCount: 6, 307 maxColCount: 6,
135 308
136 // The smallest a tile can be. 309 // The smallest a tile can be.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 } 390 }
218 391
219 chrome.send('reorderApps', [draggedTile.firstChild.appId, appIds]); 392 chrome.send('reorderApps', [draggedTile.firstChild.appId, appIds]);
220 }, 393 },
221 }; 394 };
222 395
223 return { 396 return {
224 AppsPage: AppsPage, 397 AppsPage: AppsPage,
225 }; 398 };
226 }); 399 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/ntp4/apps_page.css ('k') | chrome/browser/resources/ntp4/new_tab.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698