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

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: NTP5: Refactoring appData to use Tile's data implementation 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
« no previous file with comments | « no previous file | chrome/browser/resources/ntp_search/mock/mock.js » ('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) 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(data) {
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_();
195 el.data = data;
198 196
199 return el; 197 return el;
200 } 198 }
201 199
202 App.prototype = Tile.subclass({ 200 App.prototype = Tile.subclass({
203 __proto__: HTMLDivElement.prototype, 201 __proto__: HTMLDivElement.prototype,
204 202
205 /** 203 /**
206 * Initialize the app object. 204 * Initialize the app object.
207 * @param {Object} appData The data object that describes the app. 205 * @private
208 */ 206 */
209 initialize: function(appData) { 207 initialize_: function() {
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 * Formats this app according to |data|.
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 // TODO(pedrosimonetti): Fix crbug.com/165612
223 $('app-small-icon-template').cloneNode(true) : 228 if (!this.appContents_) {
224 $('app-large-icon-template').cloneNode(true); 229 this.appContents_ = this.useSmallIcon_ ?
225 this.appContents_.id = ''; 230 $('app-small-icon-template').cloneNode(true) :
226 this.appendChild(this.appContents_); 231 $('app-large-icon-template').cloneNode(true);
232 this.appContents_.id = '';
233 this.appendChild(this.appContents_);
234 }
227 235
228 this.appImgContainer_ = this.querySelector('.app-img-container'); 236 this.appImgContainer_ = this.querySelector('.app-img-container');
229 this.appImg_ = this.appImgContainer_.querySelector('img'); 237 this.appImg_ = this.appImgContainer_.querySelector('img');
230 this.setIcon(); 238 this.setIcon();
231 239
232 if (this.useSmallIcon_) { 240 if (this.useSmallIcon_) {
233 this.imgDiv_ = this.querySelector('.app-icon-div'); 241 this.imgDiv_ = this.querySelector('.app-icon-div');
234 this.addLaunchClickTarget_(this.imgDiv_); 242 this.addLaunchClickTarget_(this.imgDiv_);
235 this.imgDiv_.title = this.appData_.title; 243 this.imgDiv_.title = this.data_.title;
236 chrome.send('getAppIconDominantColor', [this.id]); 244 chrome.send('getAppIconDominantColor', [this.id]);
237 } else { 245 } else {
238 this.addLaunchClickTarget_(this.appImgContainer_); 246 this.addLaunchClickTarget_(this.appImgContainer_);
239 this.appImgContainer_.title = this.appData_.title; 247 this.appImgContainer_.title = this.data_.title;
240 } 248 }
241 249
242 var appSpan = this.appContents_.querySelector('.title'); 250 var appSpan = this.appContents_.querySelector('.title');
243 appSpan.textContent = appSpan.title = this.appData_.title; 251 appSpan.textContent = appSpan.title = this.data_.title;
244 this.addLaunchClickTarget_(appSpan); 252 this.addLaunchClickTarget_(appSpan);
245 253
246 var notification = this.appData_.notification; 254 var notification = this.data_.notification;
247 var hasNotification = typeof notification != 'undefined' && 255 var hasNotification = typeof notification != 'undefined' &&
248 typeof notification['title'] != 'undefined' && 256 typeof notification['title'] != 'undefined' &&
249 typeof notification['body'] != 'undefined' && 257 typeof notification['body'] != 'undefined' &&
250 !this.appData_.notifications_disabled; 258 !this.data_.notifications_disabled;
251 if (hasNotification) 259 if (hasNotification)
252 this.setupNotification_(notification); 260 this.setupNotification_(notification);
253 261
254 this.addEventListener('keydown', cr.ui.contextMenuHandler); 262 this.addEventListener('keydown', cr.ui.contextMenuHandler);
255 this.addEventListener('keyup', cr.ui.contextMenuHandler); 263 this.addEventListener('keyup', cr.ui.contextMenuHandler);
256 264
257 // This hack is here so that appContents.contextMenu will be the same as 265 // This hack is here so that appContents.contextMenu will be the same as
258 // this.contextMenu. 266 // this.contextMenu.
259 var self = this; 267 var self = this;
260 this.appContents_.__defineGetter__('contextMenu', function() { 268 this.appContents_.__defineGetter__('contextMenu', function() {
(...skipping 20 matching lines...) Expand all
281 * been uninstalled. 289 * been uninstalled.
282 */ 290 */
283 remove: function(opt_animate) { 291 remove: function(opt_animate) {
284 // Unset the ID immediately, because the app is already gone. But leave 292 // Unset the ID immediately, because the app is already gone. But leave
285 // the tile on the page as it animates out. 293 // the tile on the page as it animates out.
286 this.id = ''; 294 this.id = '';
287 this.tileCell.doRemove(opt_animate); 295 this.tileCell.doRemove(opt_animate);
288 }, 296 },
289 297
290 /** 298 /**
291 * Set the URL of the icon from |appData_|. This won't actually show the 299 * 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 300 * icon until loadIcon() is called (for performance reasons; we don't want
293 * to load icons until we have to). 301 * to load icons until we have to).
294 */ 302 */
295 setIcon: function() { 303 setIcon: function() {
296 var src = this.useSmallIcon_ ? this.appData_.icon_small : 304 var src = this.useSmallIcon_ ? this.data_.icon_small :
297 this.appData_.icon_big; 305 this.data_.icon_big;
298 if (!this.appData_.enabled || 306 if (!this.data_.enabled ||
299 (!this.appData_.offlineEnabled && !navigator.onLine)) { 307 (!this.data_.offlineEnabled && !navigator.onLine)) {
300 src += '?grayscale=true'; 308 src += '?grayscale=true';
301 } 309 }
302 310
303 this.appImgSrc_ = src; 311 this.appImgSrc_ = src;
304 this.classList.add('icon-loading'); 312 this.classList.add('icon-loading');
305 }, 313 },
306 314
307 /** 315 /**
308 * Shows the icon for the app. That is, it causes chrome to load the app 316 * Shows the icon for the app. That is, it causes chrome to load the app
309 * icon resource. 317 * 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. 360 * @param {Object} notification The notification to show in the bubble.
353 * @private 361 * @private
354 */ 362 */
355 setupNotification_: function(notification) { 363 setupNotification_: function(notification) {
356 if (notification) { 364 if (notification) {
357 var infoBubble; 365 var infoBubble;
358 if (!this.currentBubbleShowing_) { 366 if (!this.currentBubbleShowing_) {
359 // Create a new bubble. 367 // Create a new bubble.
360 infoBubble = new cr.ui.ExpandableBubble; 368 infoBubble = new cr.ui.ExpandableBubble;
361 infoBubble.anchorNode = this; 369 infoBubble.anchorNode = this;
362 infoBubble.appId = this.appData_.id; 370 infoBubble.appId = this.data_.id;
363 infoBubble.handleCloseEvent = function() { 371 infoBubble.handleCloseEvent = function() {
364 chrome.send('closeNotification', [this.appId]); 372 chrome.send('closeNotification', [this.appId]);
365 infoBubble.hide(); 373 infoBubble.hide();
366 }; 374 };
367 } else { 375 } else {
368 // Reuse the old bubble instead of popping up a new bubble over 376 // Reuse the old bubble instead of popping up a new bubble over
369 // the old one. 377 // the old one.
370 infoBubble = this.currentBubbleShowing_; 378 infoBubble = this.currentBubbleShowing_;
371 infoBubble.collapseBubble_(); 379 infoBubble.collapseBubble_();
372 } 380 }
(...skipping 15 matching lines...) Expand all
388 this.currentBubbleShowing_ = null; 396 this.currentBubbleShowing_ = null;
389 } 397 }
390 }, 398 },
391 399
392 /** 400 /**
393 * Invoked when an app is clicked. 401 * Invoked when an app is clicked.
394 * @param {Event} e The click event. 402 * @param {Event} e The click event.
395 * @private 403 * @private
396 */ 404 */
397 onClick_: function(e) { 405 onClick_: function(e) {
398 var url = !this.appData_.is_webstore ? '' : 406 var url = !this.data_.is_webstore ? '' :
399 appendParam(this.appData_.url, 407 appendParam(this.data_.url,
400 'utm_source', 408 'utm_source',
401 'chrome-ntp-icon'); 409 'chrome-ntp-icon');
402 410
403 chrome.send('launchApp', 411 chrome.send('launchApp',
404 [this.appId, APP_LAUNCH.NTP_APPS_MAXIMIZED, url, 412 [this.appId, APP_LAUNCH.NTP_APPS_MAXIMIZED, url,
405 e.button, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey]); 413 e.button, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey]);
406 414
407 // Don't allow the click to trigger a link or anything 415 // Don't allow the click to trigger a link or anything
408 e.preventDefault(); 416 e.preventDefault();
409 }, 417 },
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 } else { 485 } else {
478 this.appContents_.classList.remove('suppress-active'); 486 this.appContents_.classList.remove('suppress-active');
479 } 487 }
480 488
481 // This class is here so we don't show the focus state for apps that 489 // This class is here so we don't show the focus state for apps that
482 // gain keyboard focus via mouse clicking. 490 // gain keyboard focus via mouse clicking.
483 this.classList.add('click-focus'); 491 this.classList.add('click-focus');
484 }, 492 },
485 493
486 /** 494 /**
487 * Change the appData and update the appearance of the app. 495 * Change the data and update the appearance of the app.
488 * @param {Object} appData The new data object that describes the app. 496 * @param {Object} data The new data object that describes the app.
489 */ 497 */
490 replaceAppData: function(appData) { 498 replaceAppData: function(data) {
491 this.appData_ = appData; 499 assert(data);
500 this.data = data;
492 this.setIcon(); 501 this.setIcon();
493 this.loadIcon(); 502 this.loadIcon();
494 }, 503 },
495 504
496 /** 505 /**
497 * The data and preferences for this app. 506 * The data and preferences for this app.
498 * @type {Object} 507 * @type {Object}
499 */ 508 */
500 set appData(data) { 509 set data(data) {
501 this.appData_ = data; 510 Object.getOwnPropertyDescriptor(Tile.prototype, 'data').set.apply(this,
511 arguments);
512
513 this.formatApp_(data);
502 }, 514 },
503 get appData() { 515 get data() {
504 return this.appData_; 516 return this.data_;
505 }, 517 },
506 518
507 get appId() { 519 get appId() {
508 return this.appData_.id; 520 return this.data_.id;
509 }, 521 },
510 522
511 /** 523 /**
512 * Returns a pointer to the context menu for this app. All apps share the 524 * Returns a pointer to the context menu for this app. All apps share the
513 * singleton AppContextMenu. This function is called by the 525 * singleton AppContextMenu. This function is called by the
514 * ContextMenuHandler in response to the 'contextmenu' event. 526 * ContextMenuHandler in response to the 'contextmenu' event.
515 * @type {cr.ui.Menu} 527 * @type {cr.ui.Menu}
516 */ 528 */
517 get contextMenu() { 529 get contextMenu() {
518 var menu = AppContextMenu.getInstance(); 530 var menu = AppContextMenu.getInstance();
519 menu.setupForApp(this); 531 menu.setupForApp(this);
520 return menu.menu; 532 return menu.menu;
521 }, 533 },
522 534
523 /** 535 /**
524 * Returns whether this element can be 'removed' from chrome (i.e. whether 536 * 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). 537 * the user can drag it onto the trash and expect something to happen).
526 * @return {boolean} True if the app can be uninstalled. 538 * @return {boolean} True if the app can be uninstalled.
527 */ 539 */
528 canBeRemoved: function() { 540 canBeRemoved: function() {
529 return this.appData_.mayDisable; 541 return this.data_.mayDisable;
530 }, 542 },
531 543
532 /** 544 /**
533 * Uninstalls the app after it's been dropped on the trash. 545 * Uninstalls the app after it's been dropped on the trash.
534 */ 546 */
535 removeFromChrome: function() { 547 removeFromChrome: function() {
536 chrome.send('uninstallApp', [this.appData_.id, true]); 548 chrome.send('uninstallApp', [this.data_.id, true]);
537 this.tile.tilePage.removeTile(this.tile, true); 549 this.tile.tilePage.removeTile(this.tile, true);
538 if (this.currentBubbleShowing_) 550 if (this.currentBubbleShowing_)
539 this.currentBubbleShowing_.hide(); 551 this.currentBubbleShowing_.hide();
540 }, 552 },
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 }); 553 });
551 554
552 /** 555 /**
553 * Creates a new AppsPage object. 556 * Creates a new AppsPage object.
554 * @constructor 557 * @constructor
555 * @extends {TilePage} 558 * @extends {TilePage}
556 */ 559 */
557 function AppsPage() { 560 function AppsPage() {
558 var el = new TilePage(); 561 var el = new TilePage();
559 el.__proto__ = AppsPage.prototype; 562 el.__proto__ = AppsPage.prototype;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 // view. 599 // view.
597 this.addEventListener('carddeselected', this.onCardDeselected_); 600 this.addEventListener('carddeselected', this.onCardDeselected_);
598 this.addEventListener('cardSlider:card_change_ended', 601 this.addEventListener('cardSlider:card_change_ended',
599 this.onCardChangeEnded_); 602 this.onCardChangeEnded_);
600 603
601 this.addEventListener('tilePage:tile_added', this.onTileAdded_); 604 this.addEventListener('tilePage:tile_added', this.onTileAdded_);
602 }, 605 },
603 606
604 /** 607 /**
605 * Highlight a newly installed app as it's added to the NTP. 608 * Highlight a newly installed app as it's added to the NTP.
606 * @param {Object} appData The data object that describes the app. 609 * @param {Object} data The data object that describes the app.
607 */ 610 */
608 insertAndHighlightApp: function(appData) { 611 insertAndHighlightApp: function(data) {
609 ntp.getCardSlider().selectCardByValue(this); 612 ntp.getCardSlider().selectCardByValue(this);
610 this.insertApp(appData, true); 613 this.insertApp(data, true);
611 }, 614 },
612 615
613 /** 616 /**
614 * Inserts an App into the TilePage, preserving the alphabetical order. 617 * Inserts an App into the TilePage, preserving the alphabetical order.
615 * @param {Object} appData The data that describes the app. 618 * @param {Object} data The data that describes the app.
616 * @param {boolean} animate Whether to animate the insertion. 619 * @param {boolean} animate Whether to animate the insertion.
617 */ 620 */
618 insertApp: function(appData, animate) { 621 insertApp: function(data, animate) {
619 var index = this.tiles_.length; 622 var index = this.tiles_.length;
620 for (var i = 0; i < this.tiles_.length; i++) { 623 for (var i = 0; i < this.tiles_.length; i++) {
621 if (appData.title.toLocaleLowerCase() < 624 if (data.title.toLocaleLowerCase() <
622 this.tiles_[i].appData.title.toLocaleLowerCase()) { 625 this.tiles_[i].data.title.toLocaleLowerCase()) {
623 index = i; 626 index = i;
624 break; 627 break;
625 } 628 }
626 } 629 }
627 630
628 var app = new App(appData); 631 var app = new App(data);
629 this.addTileAt(app, index); 632 this.addTileAt(app, index);
630 this.renderGrid_(); 633 this.renderGrid_();
631 }, 634 },
632 635
633 /** 636 /**
634 * Handler for 'cardselected' event, fired when |this| is selected. The 637 * Handler for 'cardselected' event, fired when |this| is selected. The
635 * first time this is called, we load all the app icons. 638 * first time this is called, we load all the app icons.
636 * @private 639 * @private
637 */ 640 */
638 onCardSelected_: function(e) { 641 onCardSelected_: function(e) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 TilePage.prototype.onScroll.apply(this, arguments); 693 TilePage.prototype.onScroll.apply(this, arguments);
691 694
692 for (var i = 0; i < this.tiles_.length; i++) { 695 for (var i = 0; i < this.tiles_.length; i++) {
693 var app = this.tiles_[i]; 696 var app = this.tiles_[i];
694 assert(app instanceof App); 697 assert(app instanceof App);
695 if (app.currentBubbleShowing_) 698 if (app.currentBubbleShowing_)
696 app.currentBubbleShowing_.resizeAndReposition(); 699 app.currentBubbleShowing_.resizeAndReposition();
697 } 700 }
698 }, 701 },
699 702
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 /** 703 /**
788 * Creates a new crx-less app manifest and installs it. 704 * Creates a new crx-less app manifest and installs it.
789 * @param {Object} data The data object describing the link. Must have |url| 705 * @param {Object} data The data object describing the link. Must have |url|
790 * and |title| members. 706 * and |title| members.
791 */ 707 */
792 generateAppForLink: function(data) { 708 generateAppForLink: function(data) {
793 assert(data.url != undefined); 709 assert(data.url != undefined);
794 assert(data.title != undefined); 710 assert(data.title != undefined);
795 chrome.send('generateAppForLink', [data.url, data.title, 0]); 711 chrome.send('generateAppForLink', [data.url, data.title, 0]);
796 }, 712 },
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 }; 713 };
824 714
825 /** 715 /**
826 * Launches the specified app using the APP_LAUNCH_NTP_APP_RE_ENABLE 716 * Launches the specified app using the APP_LAUNCH_NTP_APP_RE_ENABLE
827 * histogram. This should only be invoked from the AppLauncherHandler. 717 * histogram. This should only be invoked from the AppLauncherHandler.
828 * @param {String} appID The ID of the app. 718 * @param {String} appID The ID of the app.
829 */ 719 */
830 function launchAppAfterEnable(appId) { 720 function launchAppAfterEnable(appId) {
831 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]); 721 chrome.send('launchApp', [appId, APP_LAUNCH.NTP_APP_RE_ENABLE]);
832 } 722 }
833 723
834 function appNotificationChanged(id, notification) { 724 function appNotificationChanged(id, notification) {
835 var app = $(id); 725 var app = $(id);
836 // The app might have been uninstalled, or notifications might be disabled. 726 // The app might have been uninstalled, or notifications might be disabled.
837 if (app && !app.appData.notifications_disabled) 727 if (app && !app.data.notifications_disabled)
838 app.setupNotification_(notification); 728 app.setupNotification_(notification);
839 } 729 }
840 730
841 return { 731 return {
842 appNotificationChanged: appNotificationChanged, 732 appNotificationChanged: appNotificationChanged,
843 AppsPage: AppsPage, 733 AppsPage: AppsPage,
844 launchAppAfterEnable: launchAppAfterEnable, 734 launchAppAfterEnable: launchAppAfterEnable,
845 }; 735 };
846 }); 736 });
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/ntp_search/mock/mock.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698