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