OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 }); |
OLD | NEW |