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

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

Issue 11438009: NTP5: Refactoring appData to use Tile's data implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressing Dan's comments Created 8 years 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) 2012 The Chromium Authors. All rights reserved. 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 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('ntp', function() { 5 cr.define('ntp', function() {
6 'use strict'; 6 'use strict';
7 7
8 var Tile = ntp.Tile; 8 var Tile = ntp.Tile;
9 var TilePage = ntp.TilePage; 9 var TilePage = ntp.TilePage;
10 var APP_LAUNCH = ntp.APP_LAUNCH; 10 var APP_LAUNCH = ntp.APP_LAUNCH;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 } 113 }
114 }, 114 },
115 115
116 /** 116 /**
117 * Does all the necessary setup to show the menu for the given app. 117 * Does all the necessary setup to show the menu for the given app.
118 * @param {App} app The App object that will be showing a context menu. 118 * @param {App} app The App object that will be showing a context menu.
119 */ 119 */
120 setupForApp: function(app) { 120 setupForApp: function(app) {
121 this.app_ = app; 121 this.app_ = app;
122 122
123 this.launch_.textContent = app.appData.title; 123 this.launch_.textContent = app.data.title;
124 124
125 this.forAllLaunchTypes_(function(launchTypeButton, id) { 125 this.forAllLaunchTypes_(function(launchTypeButton, id) {
126 launchTypeButton.disabled = false; 126 launchTypeButton.disabled = false;
127 launchTypeButton.checked = app.appData.launch_type == id; 127 launchTypeButton.checked = app.data.launch_type == id;
128 }); 128 });
129 129
130 this.options_.disabled = !app.appData.optionsUrl || !app.appData.enabled; 130 this.options_.disabled = !app.data.optionsUrl || !app.data.enabled;
131 this.details_.disabled = !app.appData.detailsUrl; 131 this.details_.disabled = !app.data.detailsUrl;
132 this.uninstall_.disabled = !app.appData.mayDisable; 132 this.uninstall_.disabled = !app.data.mayDisable;
133 133
134 this.disableNotifications_.hidden = true; 134 this.disableNotifications_.hidden = true;
135 var notificationsDisabled = app.appData.notifications_disabled; 135 var notificationsDisabled = app.data.notifications_disabled;
136 if (typeof notificationsDisabled != 'undefined') { 136 if (typeof notificationsDisabled != 'undefined') {
137 this.disableNotifications_.hidden = false; 137 this.disableNotifications_.hidden = false;
138 this.disableNotifications_.checked = notificationsDisabled; 138 this.disableNotifications_.checked = notificationsDisabled;
139 } 139 }
140 }, 140 },
141 141
142 /** 142 /**
143 * Handlers for menu item activation. 143 * Handlers for menu item activation.
144 * @param {Event} e The activation event. 144 * @param {Event} e The activation event.
145 * @private 145 * @private
146 */ 146 */
147 onLaunch_: function(e) { 147 onLaunch_: function(e) {
148 chrome.send('launchApp', [this.app_.appId, APP_LAUNCH.NTP_APPS_MENU]); 148 chrome.send('launchApp', [this.app_.appId, APP_LAUNCH.NTP_APPS_MENU]);
149 }, 149 },
150 onLaunchTypeChanged_: function(e) { 150 onLaunchTypeChanged_: function(e) {
151 var pressed = e.currentTarget; 151 var pressed = e.currentTarget;
152 var app = this.app_; 152 var app = this.app_;
153 this.forAllLaunchTypes_(function(launchTypeButton, id) { 153 this.forAllLaunchTypes_(function(launchTypeButton, id) {
154 if (launchTypeButton == pressed) { 154 if (launchTypeButton == pressed) {
155 chrome.send('setLaunchType', [app.appId, id]); 155 chrome.send('setLaunchType', [app.appId, id]);
156 // Manually update the launch type. We will only get 156 // Manually update the launch type. We will only get
157 // appsPrefChangeCallback calls after changes to other NTP instances. 157 // appsPrefChangeCallback calls after changes to other NTP instances.
158 app.appData.launch_type = id; 158 app.data.launch_type = id;
159 } 159 }
160 }); 160 });
161 }, 161 },
162 onShowOptions_: function(e) { 162 onShowOptions_: function(e) {
163 window.location = this.app_.appData.optionsUrl; 163 window.location = this.app_.data.optionsUrl;
164 }, 164 },
165 onShowDetails_: function(e) { 165 onShowDetails_: function(e) {
166 var url = this.app_.appData.detailsUrl; 166 var url = this.app_.data.detailsUrl;
167 url = appendParam(url, 'utm_source', 'chrome-ntp-launcher'); 167 url = appendParam(url, 'utm_source', 'chrome-ntp-launcher');
168 window.location = url; 168 window.location = url;
169 }, 169 },
170 onDisableNotifications_: function(e) { 170 onDisableNotifications_: function(e) {
171 var app = this.app_; 171 var app = this.app_;
172 app.removeBubble(); 172 app.removeBubble();
173 // Toggle the current disable setting. 173 // Toggle the current disable setting.
174 var newSetting = !this.disableNotifications_.checked; 174 var newSetting = !this.disableNotifications_.checked;
175 app.appData.notifications_disabled = newSetting; 175 app.data.notifications_disabled = newSetting;
176 chrome.send('setNotificationsDisabled', [app.appData.id, newSetting]); 176 chrome.send('setNotificationsDisabled', [app.data.id, newSetting]);
177 }, 177 },
178 onUninstall_: function(e) { 178 onUninstall_: function(e) {
179 var tileCell = this.app_.tileCell; 179 chrome.send('uninstallApp', [this.app_.data.id]);
180 tileCell.tilePage.setTileRepositioningState(tileCell.index, true);
181 chrome.send('uninstallApp', [this.app_.appData.id]);
182 }, 180 },
183 onCreateShortcut_: function(e) { 181 onCreateShortcut_: function(e) {
184 chrome.send('createAppShortcut', [this.app_.appData.id]); 182 chrome.send('createAppShortcut', [this.app_.data.id]);
185 }, 183 },
186 }; 184 };
187 185
188 /** 186 /**
189 * Creates a new App object. 187 * Creates a new App object.
190 * @param {Object} appData The data object that describes the app.
191 * @constructor 188 * @constructor
192 * @extends {HTMLDivElement} 189 * @extends {HTMLDivElement}
193 */ 190 */
194 function App(appData) { 191 function App() {
195 var el = cr.doc.createElement('div'); 192 var el = cr.doc.createElement('div');
196 el.__proto__ = App.prototype; 193 el.__proto__ = App.prototype;
197 el.initialize(appData); 194 el.initialize_();
198 195
199 return el; 196 return el;
200 } 197 }
201 198
202 App.prototype = Tile.subclass({ 199 App.prototype = Tile.subclass({
203 __proto__: HTMLDivElement.prototype, 200 __proto__: HTMLDivElement.prototype,
204 201
205 /** 202 /**
206 * Initialize the app object. 203 * Initialize the app object.
207 * @param {Object} appData The data object that describes the app. 204 * @param {Object} data The data object that describes the app.
205 * @private
208 */ 206 */
209 initialize: function(appData) { 207 initialize_: function(data) {
210 this.className = 'app focusable';
211
212 Tile.prototype.initialize.apply(this, arguments); 208 Tile.prototype.initialize.apply(this, arguments);
213 209
214 this.appData = appData; 210 this.classList.add('app');
215 assert(this.appData_.id, 'Got an app without an ID'); 211 this.classList.add('focusable');
216 this.id = this.appData_.id; 212 },
213
214 /**
215 * Initialize the app object.
Dan Beam 2012/12/11 01:49:24 give a new description highlighting how it's diffe
pedro (no code reviews) 2012/12/11 07:20:53 Done.
216 * @param {Object} data The data object that describes the app.
217 * @private
218 */
219 formatApp_: function(data) {
220 assert(this.data_.id, 'Got an app without an ID');
221 this.id = this.data_.id;
217 this.setAttribute('role', 'menuitem'); 222 this.setAttribute('role', 'menuitem');
218 223
219 if (!this.appData_.icon_big_exists && this.appData_.icon_small_exists) 224 if (!this.data_.icon_big_exists && this.data_.icon_small_exists)
220 this.useSmallIcon_ = true; 225 this.useSmallIcon_ = true;
221 226
222 this.appContents_ = this.useSmallIcon_ ? 227 if (!this.appContents_) {
Dan Beam 2012/12/11 01:49:24 what happens if you want to re-use apps - does thi
pedro (no code reviews) 2012/12/11 07:20:53 This change does not break the ability to do that.
Dan Beam 2012/12/11 22:47:23 this.useSmallIcon_ is based on this.data, so if yo
pedro (no code reviews) 2012/12/11 23:23:15 No, that's not entirely correct. If an already 'pa
223 $('app-small-icon-template').cloneNode(true) : 228 this.appContents_ = this.useSmallIcon_ ?
224 $('app-large-icon-template').cloneNode(true); 229 $('app-small-icon-template').cloneNode(true) :
225 this.appContents_.id = ''; 230 $('app-large-icon-template').cloneNode(true);
226 this.appendChild(this.appContents_); 231 this.appContents_.id = '';
232 this.appendChild(this.appContents_);
233 }
227 234
228 this.appImgContainer_ = this.querySelector('.app-img-container'); 235 this.appImgContainer_ = this.querySelector('.app-img-container');
229 this.appImg_ = this.appImgContainer_.querySelector('img'); 236 this.appImg_ = this.appImgContainer_.querySelector('img');
230 this.setIcon(); 237 this.setIcon();
231 238
232 if (this.useSmallIcon_) { 239 if (this.useSmallIcon_) {
233 this.imgDiv_ = this.querySelector('.app-icon-div'); 240 this.imgDiv_ = this.querySelector('.app-icon-div');
234 this.addLaunchClickTarget_(this.imgDiv_); 241 this.addLaunchClickTarget_(this.imgDiv_);
235 this.imgDiv_.title = this.appData_.title; 242 this.imgDiv_.title = this.data_.title;
236 chrome.send('getAppIconDominantColor', [this.id]); 243 chrome.send('getAppIconDominantColor', [this.id]);
237 } else { 244 } else {
238 this.addLaunchClickTarget_(this.appImgContainer_); 245 this.addLaunchClickTarget_(this.appImgContainer_);
239 this.appImgContainer_.title = this.appData_.title; 246 this.appImgContainer_.title = this.data_.title;
240 } 247 }
241 248
242 var appSpan = this.appContents_.querySelector('.title'); 249 var appSpan = this.appContents_.querySelector('.title');
243 appSpan.textContent = appSpan.title = this.appData_.title; 250 appSpan.textContent = appSpan.title = this.data_.title;
244 this.addLaunchClickTarget_(appSpan); 251 this.addLaunchClickTarget_(appSpan);
245 252
246 var notification = this.appData_.notification; 253 var notification = this.data_.notification;
247 var hasNotification = typeof notification != 'undefined' && 254 var hasNotification = typeof notification != 'undefined' &&
248 typeof notification['title'] != 'undefined' && 255 typeof notification['title'] != 'undefined' &&
249 typeof notification['body'] != 'undefined' && 256 typeof notification['body'] != 'undefined' &&
250 !this.appData_.notifications_disabled; 257 !this.data_.notifications_disabled;
251 if (hasNotification) 258 if (hasNotification)
252 this.setupNotification_(notification); 259 this.setupNotification_(notification);
253 260
254 this.addEventListener('keydown', cr.ui.contextMenuHandler); 261 this.addEventListener('keydown', cr.ui.contextMenuHandler);
255 this.addEventListener('keyup', cr.ui.contextMenuHandler); 262 this.addEventListener('keyup', cr.ui.contextMenuHandler);
256 263
257 // This hack is here so that appContents.contextMenu will be the same as 264 // This hack is here so that appContents.contextMenu will be the same as
258 // this.contextMenu. 265 // this.contextMenu.
259 var self = this; 266 var self = this;
260 this.appContents_.__defineGetter__('contextMenu', function() { 267 this.appContents_.__defineGetter__('contextMenu', function() {
(...skipping 20 matching lines...) Expand all
281 * been uninstalled. 288 * been uninstalled.
282 */ 289 */
283 remove: function(opt_animate) { 290 remove: function(opt_animate) {
284 // Unset the ID immediately, because the app is already gone. But leave 291 // Unset the ID immediately, because the app is already gone. But leave
285 // the tile on the page as it animates out. 292 // the tile on the page as it animates out.
286 this.id = ''; 293 this.id = '';
287 this.tileCell.doRemove(opt_animate); 294 this.tileCell.doRemove(opt_animate);
288 }, 295 },
289 296
290 /** 297 /**
291 * Set the URL of the icon from |appData_|. This won't actually show the 298 * Set the URL of the icon from |this.data_|. This won't actually show the
292 * icon until loadIcon() is called (for performance reasons; we don't want 299 * icon until loadIcon() is called (for performance reasons; we don't want
293 * to load icons until we have to). 300 * to load icons until we have to).
294 */ 301 */
295 setIcon: function() { 302 setIcon: function() {
296 var src = this.useSmallIcon_ ? this.appData_.icon_small : 303 var src = this.useSmallIcon_ ? this.data_.icon_small :
297 this.appData_.icon_big; 304 this.data_.icon_big;
298 if (!this.appData_.enabled || 305 if (!this.data_.enabled ||
299 (!this.appData_.offlineEnabled && !navigator.onLine)) { 306 (!this.data_.offlineEnabled && !navigator.onLine)) {
300 src += '?grayscale=true'; 307 src += '?grayscale=true';
301 } 308 }
302 309
303 this.appImgSrc_ = src; 310 this.appImgSrc_ = src;
304 this.classList.add('icon-loading'); 311 this.classList.add('icon-loading');
305 }, 312 },
306 313
307 /** 314 /**
308 * Shows the icon for the app. That is, it causes chrome to load the app 315 * Shows the icon for the app. That is, it causes chrome to load the app
309 * icon resource. 316 * icon resource.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 * @param {Object} notification The notification to show in the bubble. 359 * @param {Object} notification The notification to show in the bubble.
353 * @private 360 * @private
354 */ 361 */
355 setupNotification_: function(notification) { 362 setupNotification_: function(notification) {
356 if (notification) { 363 if (notification) {
357 var infoBubble; 364 var infoBubble;
358 if (!this.currentBubbleShowing_) { 365 if (!this.currentBubbleShowing_) {
359 // Create a new bubble. 366 // Create a new bubble.
360 infoBubble = new cr.ui.ExpandableBubble; 367 infoBubble = new cr.ui.ExpandableBubble;
361 infoBubble.anchorNode = this; 368 infoBubble.anchorNode = this;
362 infoBubble.appId = this.appData_.id; 369 infoBubble.appId = this.data_.id;
363 infoBubble.handleCloseEvent = function() { 370 infoBubble.handleCloseEvent = function() {
364 chrome.send('closeNotification', [this.appId]); 371 chrome.send('closeNotification', [this.appId]);
365 infoBubble.hide(); 372 infoBubble.hide();
366 }; 373 };
367 } else { 374 } else {
368 // Reuse the old bubble instead of popping up a new bubble over 375 // Reuse the old bubble instead of popping up a new bubble over
369 // the old one. 376 // the old one.
370 infoBubble = this.currentBubbleShowing_; 377 infoBubble = this.currentBubbleShowing_;
371 infoBubble.collapseBubble_(); 378 infoBubble.collapseBubble_();
372 } 379 }
(...skipping 15 matching lines...) Expand all
388 this.currentBubbleShowing_ = null; 395 this.currentBubbleShowing_ = null;
389 } 396 }
390 }, 397 },
391 398
392 /** 399 /**
393 * Invoked when an app is clicked. 400 * Invoked when an app is clicked.
394 * @param {Event} e The click event. 401 * @param {Event} e The click event.
395 * @private 402 * @private
396 */ 403 */
397 onClick_: function(e) { 404 onClick_: function(e) {
398 var url = !this.appData_.is_webstore ? '' : 405 var url = !this.data_.is_webstore ? '' :
399 appendParam(this.appData_.url, 406 appendParam(this.data_.url,
400 'utm_source', 407 'utm_source',
401 'chrome-ntp-icon'); 408 'chrome-ntp-icon');
402 409
403 chrome.send('launchApp', 410 chrome.send('launchApp',
404 [this.appId, APP_LAUNCH.NTP_APPS_MAXIMIZED, url, 411 [this.appId, APP_LAUNCH.NTP_APPS_MAXIMIZED, url,
405 e.button, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey]); 412 e.button, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey]);
406 413
407 // Don't allow the click to trigger a link or anything 414 // Don't allow the click to trigger a link or anything
408 e.preventDefault(); 415 e.preventDefault();
409 }, 416 },
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 } else { 484 } else {
478 this.appContents_.classList.remove('suppress-active'); 485 this.appContents_.classList.remove('suppress-active');
479 } 486 }
480 487
481 // This class is here so we don't show the focus state for apps that 488 // This class is here so we don't show the focus state for apps that
482 // gain keyboard focus via mouse clicking. 489 // gain keyboard focus via mouse clicking.
483 this.classList.add('click-focus'); 490 this.classList.add('click-focus');
484 }, 491 },
485 492
486 /** 493 /**
487 * Change the appData and update the appearance of the app. 494 * Change the data and update the appearance of the app.
488 * @param {Object} appData The new data object that describes the app. 495 * @param {Object} data The new data object that describes the app.
489 */ 496 */
490 replaceAppData: function(appData) { 497 replaceAppData: function(data) {
491 this.appData_ = appData; 498 assert(data);
499 this.data = data;
492 this.setIcon(); 500 this.setIcon();
493 this.loadIcon(); 501 this.loadIcon();
494 }, 502 },
495 503
496 /** 504 /**
497 * The data and preferences for this app. 505 * The data and preferences for this app.
498 * @type {Object} 506 * @type {Object}
499 */ 507 */
500 set appData(data) { 508 set data(data) {
501 this.appData_ = data; 509 Object.getOwnPropertyDescriptor(Tile.prototype, 'data').set.apply(this,
510 arguments);
511
512 this.formatApp_(data);
Dan Beam 2012/12/11 01:49:24 what is the difference between formatApp_, replace
pedro (no code reviews) 2012/12/11 07:20:53 'set data' is the setter of, well, data. When that
502 }, 513 },
503 get appData() { 514 get data() {
504 return this.appData_; 515 return this.data_;
505 }, 516 },
506 517
507 get appId() { 518 get appId() {
508 return this.appData_.id; 519 return this.data_.id;
509 }, 520 },
510 521
511 /** 522 /**
512 * Returns a pointer to the context menu for this app. All apps share the 523 * Returns a pointer to the context menu for this app. All apps share the
513 * singleton AppContextMenu. This function is called by the 524 * singleton AppContextMenu. This function is called by the
514 * ContextMenuHandler in response to the 'contextmenu' event. 525 * ContextMenuHandler in response to the 'contextmenu' event.
515 * @type {cr.ui.Menu} 526 * @type {cr.ui.Menu}
516 */ 527 */
517 get contextMenu() { 528 get contextMenu() {
518 var menu = AppContextMenu.getInstance(); 529 var menu = AppContextMenu.getInstance();
519 menu.setupForApp(this); 530 menu.setupForApp(this);
520 return menu.menu; 531 return menu.menu;
521 }, 532 },
522 533
523 /** 534 /**
524 * Returns whether this element can be 'removed' from chrome (i.e. whether 535 * Returns whether this element can be 'removed' from chrome (i.e. whether
525 * the user can drag it onto the trash and expect something to happen). 536 * the user can drag it onto the trash and expect something to happen).
526 * @return {boolean} True if the app can be uninstalled. 537 * @return {boolean} True if the app can be uninstalled.
527 */ 538 */
528 canBeRemoved: function() { 539 canBeRemoved: function() {
529 return this.appData_.mayDisable; 540 return this.data_.mayDisable;
530 }, 541 },
531 542
532 /** 543 /**
533 * Uninstalls the app after it's been dropped on the trash. 544 * Uninstalls the app after it's been dropped on the trash.
534 */ 545 */
535 removeFromChrome: function() { 546 removeFromChrome: function() {
536 chrome.send('uninstallApp', [this.appData_.id, true]); 547 chrome.send('uninstallApp', [this.data_.id, true]);
537 this.tile.tilePage.removeTile(this.tile, true); 548 this.tile.tilePage.removeTile(this.tile, true);
538 if (this.currentBubbleShowing_) 549 if (this.currentBubbleShowing_)
539 this.currentBubbleShowing_.hide(); 550 this.currentBubbleShowing_.hide();
540 }, 551 },
541
542 /**
543 * Called when a drag is starting on the tile. Updates dataTransfer with
544 * data for this tile.
545 */
546 setDragData: function(dataTransfer) {
547 dataTransfer.setData('Text', this.appData_.title);
548 dataTransfer.setData('URL', this.appData_.url);
549 },
550 }); 552 });
551 553
552 /** 554 /**
553 * Creates a new AppsPage object. 555 * Creates a new AppsPage object.
554 * @constructor 556 * @constructor
555 * @extends {TilePage} 557 * @extends {TilePage}
556 */ 558 */
557 function AppsPage() { 559 function AppsPage() {
558 var el = new TilePage(); 560 var el = new TilePage();
559 el.__proto__ = AppsPage.prototype; 561 el.__proto__ = AppsPage.prototype;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 // view. 598 // view.
597 this.addEventListener('carddeselected', this.onCardDeselected_); 599 this.addEventListener('carddeselected', this.onCardDeselected_);
598 this.addEventListener('cardSlider:card_change_ended', 600 this.addEventListener('cardSlider:card_change_ended',
599 this.onCardChangeEnded_); 601 this.onCardChangeEnded_);
600 602
601 this.addEventListener('tilePage:tile_added', this.onTileAdded_); 603 this.addEventListener('tilePage:tile_added', this.onTileAdded_);
602 }, 604 },
603 605
604 /** 606 /**
605 * Highlight a newly installed app as it's added to the NTP. 607 * Highlight a newly installed app as it's added to the NTP.
606 * @param {Object} appData The data object that describes the app. 608 * @param {Object} data The data object that describes the app.
607 */ 609 */
608 insertAndHighlightApp: function(appData) { 610 insertAndHighlightApp: function(data) {
609 ntp.getCardSlider().selectCardByValue(this); 611 ntp.getCardSlider().selectCardByValue(this);
610 this.insertApp(appData, true); 612 this.insertApp(data, true);
611 }, 613 },
612 614
613 /** 615 /**
614 * Inserts an App into the TilePage, preserving the alphabetical order. 616 * Inserts an App into the TilePage, preserving the alphabetical order.
615 * @param {Object} appData The data that describes the app. 617 * @param {Object} data The data that describes the app.
616 * @param {boolean} animate Whether to animate the insertion. 618 * @param {boolean} animate Whether to animate the insertion.
617 */ 619 */
618 insertApp: function(appData, animate) { 620 insertApp: function(data, animate) {
619 var index = this.tiles_.length; 621 var index = this.tiles_.length;
620 for (var i = 0; i < this.tiles_.length; i++) { 622 for (var i = 0; i < this.tiles_.length; i++) {
621 if (appData.title.toLocaleLowerCase() < 623 if (data.title.toLocaleLowerCase() <
622 this.tiles_[i].appData.title.toLocaleLowerCase()) { 624 this.tiles_[i].data.title.toLocaleLowerCase()) {
623 index = i; 625 index = i;
624 break; 626 break;
625 } 627 }
626 } 628 }
627 629
628 var app = new App(appData); 630 // TODO(pedrosimonetti): Refactor code so instantiation is new App(data).
Dan Beam 2012/12/11 01:49:24 why TODO() when you could just do?
pedro (no code reviews) 2012/12/11 07:20:53 Because not having to do this would've made this C
631 var app = new App();
632 app.data = data;
629 this.addTileAt(app, index); 633 this.addTileAt(app, index);
630 this.renderGrid_(); 634 this.renderGrid_();
631 }, 635 },
632 636
633 /** 637 /**
634 * Handler for 'cardselected' event, fired when |this| is selected. The 638 * Handler for 'cardselected' event, fired when |this| is selected. The
635 * first time this is called, we load all the app icons. 639 * first time this is called, we load all the app icons.
636 * @private 640 * @private
637 */ 641 */
638 onCardSelected_: function(e) { 642 onCardSelected_: function(e) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 TilePage.prototype.onScroll.apply(this, arguments); 694 TilePage.prototype.onScroll.apply(this, arguments);
691 695
692 for (var i = 0; i < this.tiles_.length; i++) { 696 for (var i = 0; i < this.tiles_.length; i++) {
693 var app = this.tiles_[i]; 697 var app = this.tiles_[i];
694 assert(app instanceof App); 698 assert(app instanceof App);
695 if (app.currentBubbleShowing_) 699 if (app.currentBubbleShowing_)
696 app.currentBubbleShowing_.resizeAndReposition(); 700 app.currentBubbleShowing_.resizeAndReposition();
697 } 701 }
698 }, 702 },
699 703
700 /** @override */
701 doDragOver: function(e) {
702 // Only animatedly re-arrange if the user is currently dragging an app.
703 var tile = ntp.getCurrentlyDraggingTile();
704 if (tile && tile.querySelector('.app')) {
705 TilePage.prototype.doDragOver.call(this, e);
706 } else {
707 e.preventDefault();
708 this.setDropEffect(e.dataTransfer);
709 }
710 },
711
712 /** @override */
713 shouldAcceptDrag: function(e) {
714 if (ntp.getCurrentlyDraggingTile())
715 return true;
716 if (!e.dataTransfer || !e.dataTransfer.types)
717 return false;
718 return Array.prototype.indexOf.call(e.dataTransfer.types,
719 'text/uri-list') != -1;
720 },
721
722 /** @override */
723 addDragData: function(dataTransfer, index) {
724 var sourceId = -1;
725 var currentlyDraggingTile = ntp.getCurrentlyDraggingTile();
726 if (currentlyDraggingTile) {
727 var tileContents = currentlyDraggingTile.firstChild;
728 if (tileContents.classList.contains('app')) {
729 var originalPage = currentlyDraggingTile.tilePage;
730 var samePageDrag = originalPage == this;
731 sourceId = samePageDrag ? DRAG_SOURCE.SAME_APPS_PANE :
732 DRAG_SOURCE.OTHER_APPS_PANE;
733 this.tileGrid_.insertBefore(currentlyDraggingTile,
734 this.tileElements_[index]);
735 this.tileMoved(currentlyDraggingTile);
736 if (!samePageDrag) {
737 originalPage.fireRemovedEvent(currentlyDraggingTile, index, true);
738 this.fireAddedEvent(currentlyDraggingTile, index, true);
739 }
740 } else if (currentlyDraggingTile.querySelector('.most-visited')) {
741 this.generateAppForLink(tileContents.data);
742 sourceId = DRAG_SOURCE.MOST_VISITED_PANE;
743 }
744 } else {
745 this.addOutsideData_(dataTransfer);
746 sourceId = DRAG_SOURCE.OUTSIDE_NTP;
747 }
748
749 assert(sourceId != -1);
750 chrome.send('metricsHandler:recordInHistogram',
751 ['NewTabPage.AppsPageDragSource', sourceId, DRAG_SOURCE_LIMIT]);
752 },
753
754 /**
755 * Adds drag data that has been dropped from a source that is not a tile.
756 * @param {Object} dataTransfer The data transfer object that holds drop
757 * data.
758 * @private
759 */
760 addOutsideData_: function(dataTransfer) {
761 var url = dataTransfer.getData('url');
762 assert(url);
763
764 // If the dataTransfer has html data, use that html's text contents as the
765 // title of the new link.
766 var html = dataTransfer.getData('text/html');
767 var title;
768 if (html) {
769 // It's important that we don't attach this node to the document
770 // because it might contain scripts.
771 var node = this.ownerDocument.createElement('div');
772 node.innerHTML = html;
773 title = node.textContent;
774 }
775
776 // Make sure title is >=1 and <=45 characters for Chrome app limits.
777 if (!title)
778 title = url;
779 if (title.length > 45)
780 title = title.substring(0, 45);
781 var data = {url: url, title: title};
782
783 // Synthesize an app.
784 this.generateAppForLink(data);
785 },
786
787 /** 704 /**
788 * Creates a new crx-less app manifest and installs it. 705 * Creates a new crx-less app manifest and installs it.
789 * @param {Object} data The data object describing the link. Must have |url| 706 * @param {Object} data The data object describing the link. Must have |url|
790 * and |title| members. 707 * and |title| members.
791 */ 708 */
792 generateAppForLink: function(data) { 709 generateAppForLink: function(data) {
793 assert(data.url != undefined); 710 assert(data.url != undefined);
794 assert(data.title != undefined); 711 assert(data.title != undefined);
795 chrome.send('generateAppForLink', [data.url, data.title, 0]); 712 chrome.send('generateAppForLink', [data.url, data.title, 0]);
796 }, 713 },
797
798 /** @override */
799 tileMoved: function(draggedTile) {
800 if (!(draggedTile.firstChild instanceof App))
801 return;
802
803 chrome.send('setPageIndex', [draggedTile.firstChild.appId, 0]);
804
805 var appIds = [];
806 for (var i = 0; i < this.tiles_.length; i++) {
807 var tileContents = this.tiles_[i];
808 if (tileContents instanceof App)
809 appIds.push(tileContents.appId);
810 }
811
812 chrome.send('reorderApps', [draggedTile.firstChild.appId, appIds]);
813 },
814
815 /** @override */
816 setDropEffect: function(dataTransfer) {
817 var tile = ntp.getCurrentlyDraggingTile();
818 if (tile && tile.querySelector('.app'))
819 ntp.setCurrentDropEffect(dataTransfer, 'move');
820 else
821 ntp.setCurrentDropEffect(dataTransfer, 'copy');
822 },
823 }; 714 };
824 715
825 /** 716 /**
826 * Launches the specified app using the APP_LAUNCH_NTP_APP_RE_ENABLE 717 * Launches the specified app using the APP_LAUNCH_NTP_APP_RE_ENABLE
827 * histogram. This should only be invoked from the AppLauncherHandler. 718 * histogram. This should only be invoked from the AppLauncherHandler.
828 * @param {String} appID The ID of the app. 719 * @param {String} appID The ID of the app.
829 */ 720 */
830 function launchAppAfterEnable(appId) { 721 function launchAppAfterEnable(appId) {
831 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]); 722 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]);
832 } 723 }
833 724
834 function appNotificationChanged(id, notification) { 725 function appNotificationChanged(id, notification) {
835 var app = $(id); 726 var app = $(id);
836 // The app might have been uninstalled, or notifications might be disabled. 727 // The app might have been uninstalled, or notifications might be disabled.
837 if (app && !app.appData.notifications_disabled) 728 if (app && !app.data.notifications_disabled)
838 app.setupNotification_(notification); 729 app.setupNotification_(notification);
839 } 730 }
840 731
841 return { 732 return {
842 appNotificationChanged: appNotificationChanged, 733 appNotificationChanged: appNotificationChanged,
843 AppsPage: AppsPage, 734 AppsPage: AppsPage,
844 launchAppAfterEnable: launchAppAfterEnable, 735 launchAppAfterEnable: launchAppAfterEnable,
845 }; 736 };
846 }); 737 });
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/ntp_search/mock/mock.js » ('j') | chrome/browser/resources/ntp_search/tile_page.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698