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

Side by Side Diff: chrome/browser/resources/ntp4/tile_page.js

Issue 9116037: [NTP4] Make TilePage and CardSlider evented to simplify code and fix page switcher bug (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase + event order change Created 8 years, 11 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
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('ntp4', function() { 5 cr.define('ntp4', function() {
6 'use strict'; 6 'use strict';
7 7
8 // We can't pass the currently dragging tile via dataTransfer because of 8 // We can't pass the currently dragging tile via dataTransfer because of
9 // http://crbug.com/31037 9 // http://crbug.com/31037
10 var currentlyDraggingTile = null; 10 var currentlyDraggingTile = null;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 this.finalizeDrag_(); 193 this.finalizeDrag_();
194 } else { 194 } else {
195 // The CSS3 transitions spec intentionally leaves it up to individual 195 // The CSS3 transitions spec intentionally leaves it up to individual
196 // user agents to determine when styles should be applied. On some 196 // user agents to determine when styles should be applied. On some
197 // platforms (at the moment, Windows), when you apply both classes 197 // platforms (at the moment, Windows), when you apply both classes
198 // immediately a transition may not occur correctly. That's why we're 198 // immediately a transition may not occur correctly. That's why we're
199 // using a setTimeout here to queue adding the class until the 199 // using a setTimeout here to queue adding the class until the
200 // previous class (currently: .placing) sets up a transition. 200 // previous class (currently: .placing) sets up a transition.
201 // http://dev.w3.org/csswg/css3-transitions/#starting 201 // http://dev.w3.org/csswg/css3-transitions/#starting
202 window.setTimeout(function() { 202 window.setTimeout(function() {
203 this.dragClone.classList.add('dropped-on-other-page'); 203 if (this.dragClone)
204 this.dragClone.classList.add('dropped-on-other-page');
204 }.bind(this), 0); 205 }.bind(this), 0);
205 } 206 }
206 } 207 }
207 208
208 delete this.lastDropEffect; 209 delete this.lastDropEffect;
209 this.landedOnTrash = false; 210 this.landedOnTrash = false;
210 }, 211 },
211 212
212 /** 213 /**
213 * Creates a clone of this node offset by the coordinates. Used for the 214 * Creates a clone of this node offset by the coordinates. Used for the
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 onDragCloneTransitionEnd_: function(e) { 285 onDragCloneTransitionEnd_: function(e) {
285 if (this.classList.contains('dragging') && 286 if (this.classList.contains('dragging') &&
286 (e.propertyName == 'left' || e.propertyName == 'top' || 287 (e.propertyName == 'left' || e.propertyName == 'top' ||
287 e.propertyName == '-webkit-transform')) { 288 e.propertyName == '-webkit-transform')) {
288 this.finalizeDrag_(); 289 this.finalizeDrag_();
289 } 290 }
290 }, 291 },
291 292
292 /** 293 /**
293 * Called when an app is removed from Chrome. Animates its disappearance. 294 * Called when an app is removed from Chrome. Animates its disappearance.
295 * @param {boolean=} opt_animate Whether the animation should be animated.
294 */ 296 */
295 doRemove: function() { 297 doRemove: function(opt_animate) {
296 this.firstChild.classList.add('removing-tile-contents'); 298 if (opt_animate)
299 this.firstChild.classList.add('removing-tile-contents');
300 else
301 this.parentNode.removeChild(this);
297 }, 302 },
298 303
299 /** 304 /**
300 * Callback for the webkitAnimationEnd event on the tile's contents. 305 * Callback for the webkitAnimationEnd event on the tile's contents.
301 * @param {Event} e The event object. 306 * @param {Event} e The event object.
302 */ 307 */
303 onContentsAnimationEnd_: function(e) { 308 onContentsAnimationEnd_: function(e) {
304 if (this.firstChild.classList.contains('new-tile-contents')) 309 if (this.firstChild.classList.contains('new-tile-contents'))
305 this.firstChild.classList.remove('new-tile-contents'); 310 this.firstChild.classList.remove('new-tile-contents');
306 if (this.firstChild.classList.contains('removing-tile-contents')) 311 if (this.firstChild.classList.contains('removing-tile-contents'))
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 function TilePage(gridValues) { 361 function TilePage(gridValues) {
357 var el = cr.doc.createElement('div'); 362 var el = cr.doc.createElement('div');
358 el.gridValues_ = gridValues; 363 el.gridValues_ = gridValues;
359 el.__proto__ = TilePage.prototype; 364 el.__proto__ = TilePage.prototype;
360 el.initialize(); 365 el.initialize();
361 366
362 return el; 367 return el;
363 } 368 }
364 369
365 /** 370 /**
371 * The type of events TilePage dispatches.
372 * @public
373 * @static
374 * @memberOf TilePage
375 */
376 TilePage.EventType = {
377 TILE_ADDED: 'tilePage:tile_added',
378 TILE_REMOVED: 'tilePage:tile_removed',
379 };
380
381 /**
366 * Takes a collection of grid layout pixel values and updates them with 382 * Takes a collection of grid layout pixel values and updates them with
367 * additional tiling values that are calculated from TilePage constants. 383 * additional tiling values that are calculated from TilePage constants.
368 * @param {Object} grid The grid layout pixel values to update. 384 * @param {Object} grid The grid layout pixel values to update.
369 */ 385 */
370 TilePage.initGridValues = function(grid) { 386 TilePage.initGridValues = function(grid) {
371 // The amount of space we need to display a narrow grid (all narrow grids 387 // The amount of space we need to display a narrow grid (all narrow grids
372 // are this size). 388 // are this size).
373 grid.narrowWidth = 389 grid.narrowWidth =
374 grid.minTileWidth * tileWidthFraction(grid.minColCount, 390 grid.minTileWidth * tileWidthFraction(grid.minColCount,
375 grid.tileSpacingFraction); 391 grid.tileSpacingFraction);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 /** 507 /**
492 * Returns any extra padding to insert to the bottom of a tile page. By 508 * Returns any extra padding to insert to the bottom of a tile page. By
493 * default there is none, but subclasses can override. 509 * default there is none, but subclasses can override.
494 * @type {number} 510 * @type {number}
495 */ 511 */
496 get extraBottomPadding() { 512 get extraBottomPadding() {
497 return 0; 513 return 0;
498 }, 514 },
499 515
500 /** 516 /**
517 * Removes the tilePage from the DOM and cleans up event handlers.
518 */
519 remove: function() {
520 // This checks arguments.length as most remove functions have a boolean
521 // |opt_animate| argument, but that's not necesarilly applicable to
522 // removing a tilePage. Selecting a different card in an animated way and
523 // deleting the card afterward is probably a better choice.
524 assert(typeof arguments[0] != 'boolean',
525 'This function takes no |opt_animate| argument.');
526 this.tearDown_();
527 this.parentNode.removeChild(this);
528 },
529
530 /**
501 * Cleans up resources that are no longer needed after this TilePage 531 * Cleans up resources that are no longer needed after this TilePage
502 * instance is removed from the DOM. 532 * instance is removed from the DOM.
533 * @private
503 */ 534 */
504 tearDown: function() { 535 tearDown_: function() {
505 this.eventTracker.removeAll(); 536 this.eventTracker.removeAll();
506 }, 537 },
507 538
508 /** 539 /**
509 * Appends a tile to the end of the tile grid. 540 * Appends a tile to the end of the tile grid.
510 * @param {HTMLElement} tileElement The contents of the tile. 541 * @param {HTMLElement} tileElement The contents of the tile.
511 * @param {?boolean} animate If true, the append will be animated. 542 * @param {?boolean} animate If true, the append will be animated.
512 * @protected 543 * @protected
513 */ 544 */
514 appendTile: function(tileElement, animate) { 545 appendTile: function(tileElement, animate) {
515 this.addTileAt(tileElement, this.tileElements_.length, animate); 546 this.addTileAt(tileElement, this.tileElements_.length, animate);
516 }, 547 },
517 548
518 /** 549 /**
519 * Adds the given element to the tile grid. 550 * Adds the given element to the tile grid.
520 * @param {Node} tileElement The tile object/node to insert. 551 * @param {Node} tileElement The tile object/node to insert.
521 * @param {number} index The location in the tile grid to insert it at. 552 * @param {number} index The location in the tile grid to insert it at.
522 * @param {?boolean} animate If true, the tile in question will be animated 553 * @param {boolean=} opt_animate If true, the tile in question will be
523 * (other tiles, if they must reposition, do not animate). 554 * animated (other tiles, if they must reposition, do not animate).
524 * @protected 555 * @protected
525 */ 556 */
526 addTileAt: function(tileElement, index, animate) { 557 addTileAt: function(tileElement, index, opt_animate) {
527 this.classList.remove('animating-tile-page'); 558 this.classList.remove('animating-tile-page');
528 if (animate) 559 if (opt_animate)
529 tileElement.classList.add('new-tile-contents'); 560 tileElement.classList.add('new-tile-contents');
561
562 // Make sure the index is positive and either in the the bounds of
563 // this.tileElements_ or at the end (meaning append).
564 assert(index >= 0 && index <= this.tileElements_.length);
565
530 var wrapperDiv = new Tile(tileElement); 566 var wrapperDiv = new Tile(tileElement);
531 if (index == this.tileElements_.length) { 567 // If is out of the bounds of the tile element list, .insertBefore() will
532 this.tileGrid_.appendChild(wrapperDiv); 568 // act just like appendChild().
533 } else { 569 this.tileGrid_.insertBefore(wrapperDiv, this.tileElements_[index]);
534 this.tileGrid_.insertBefore(wrapperDiv,
535 this.tileElements_[index]);
536 }
537 this.calculateLayoutValues_(); 570 this.calculateLayoutValues_();
538 this.heightChanged_(); 571 this.heightChanged_();
539 572
540 this.positionTile_(index); 573 this.positionTile_(index);
574 this.fireAddedEvent(wrapperDiv, index, !!opt_animate);
541 }, 575 },
542 576
543 /** 577 /**
544 * Removes the given tile and animates the respositioning of the other 578 * Notify interested subscribers that a tile has been removed from this
545 * tiles. 579 * page.
546 * @param {HTMLElement} tile The tile to remove from |tileGrid_|. 580 * @param {Tile} tile The newly added tile.
547 * @param {?boolean} animate If true, remaining tiles will animate. 581 * @param {number} index The index of the tile that was added.
582 * @param {boolean} wasAnimated Whether the removal was animated.
548 */ 583 */
549 removeTile: function(tile, animate) { 584 fireAddedEvent: function(tile, index, wasAnimated) {
550 if (animate) 585 var e = document.createEvent('Event');
586 e.initEvent(TilePage.EventType.TILE_ADDED, true, true);
587 e.addedIndex = index;
588 e.addedTile = tile;
589 e.tilePage = this;
590 e.wasAnimated = wasAnimated;
591 this.dispatchEvent(e);
592 },
593
594 /**
595 * Removes the given tile and animates the repositioning of the other tiles.
596 * @param {boolean=} opt_animate Whether the removal should be animated.
597 * @param {boolean=} opt_dontNotify Whether a page should be removed if the
598 * last tile is removed from it.
599 */
600 removeTile: function(tile, opt_animate, opt_dontNotify) {
601 if (opt_animate)
551 this.classList.add('animating-tile-page'); 602 this.classList.add('animating-tile-page');
552 var index = tile.index; 603 var index = tile.index;
553 tile.parentNode.removeChild(tile); 604 tile.parentNode.removeChild(tile);
554 this.calculateLayoutValues_(); 605 this.calculateLayoutValues_();
555 this.cleanupDrag(); 606 this.cleanupDrag();
607
608 if (!opt_dontNotify)
609 this.fireRemovedEvent(tile, index, !!opt_animate);
556 }, 610 },
557 611
558 /** 612 /**
613 * Notify interested subscribers that a tile has been removed from this
614 * page.
615 * @param {Tile} tile The tile that was removed.
616 * @param {number} index Where the tile was positioned before removal.
617 * @param {boolean} wasAnimated Whether the removal was animated.
618 */
619 fireRemovedEvent: function(tile, index, wasAnimated) {
620 var e = document.createEvent('Event');
621 e.initEvent(TilePage.EventType.TILE_REMOVED, true, true);
622 e.tilePage = this;
623 e.removedIndex = index;
624 e.removedTile = tile;
625 e.wasAnimated = wasAnimated;
626 this.dispatchEvent(e);
627 },
628
629 /**
559 * Removes all tiles from the page. 630 * Removes all tiles from the page.
560 */ 631 */
561 removeAllTiles: function() { 632 removeAllTiles: function() {
562 this.tileGrid_.innerHTML = ''; 633 this.tileGrid_.innerHTML = '';
563 }, 634 },
564 635
565 /** 636 /**
566 * Called when the page is selected (in the card selector). 637 * Called when the page is selected (in the card selector).
567 * @param {Event} e A custom cardselected event. 638 * @param {Event} e A custom cardselected event.
568 * @private 639 * @private
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 /** 1206 /**
1136 * Appends the currently dragged tile to the end of the page. Called 1207 * Appends the currently dragged tile to the end of the page. Called
1137 * from outside the page, e.g. when dropping on a nav dot. 1208 * from outside the page, e.g. when dropping on a nav dot.
1138 */ 1209 */
1139 appendDraggingTile: function() { 1210 appendDraggingTile: function() {
1140 var originalPage = currentlyDraggingTile.tilePage; 1211 var originalPage = currentlyDraggingTile.tilePage;
1141 if (originalPage == this) 1212 if (originalPage == this)
1142 return; 1213 return;
1143 1214
1144 this.addDragData(null, this.tileElements_.length); 1215 this.addDragData(null, this.tileElements_.length);
1145 originalPage.cleanupDrag(); 1216 if (originalPage)
1217 originalPage.cleanupDrag();
1146 }, 1218 },
1147 1219
1148 /** 1220 /**
1149 * Makes sure all the tiles are in the right place after a drag is over. 1221 * Makes sure all the tiles are in the right place after a drag is over.
1150 */ 1222 */
1151 cleanupDrag: function() { 1223 cleanupDrag: function() {
1152 this.repositionTiles_(currentlyDraggingTile); 1224 this.repositionTiles_(currentlyDraggingTile);
1153 // Remove the drag mask. 1225 // Remove the drag mask.
1154 this.updateMask_(); 1226 this.updateMask_();
1155 }, 1227 },
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 assert(false); 1302 assert(false);
1231 }, 1303 },
1232 }; 1304 };
1233 1305
1234 return { 1306 return {
1235 getCurrentlyDraggingTile: getCurrentlyDraggingTile, 1307 getCurrentlyDraggingTile: getCurrentlyDraggingTile,
1236 setCurrentDropEffect: setCurrentDropEffect, 1308 setCurrentDropEffect: setCurrentDropEffect,
1237 TilePage: TilePage, 1309 TilePage: TilePage,
1238 }; 1310 };
1239 }); 1311 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698