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

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

Issue 11445009: NTP5: Reuse insertion/removal animations for Apps. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: NTP5: Reuse insertion/removal animations for Apps 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 | « chrome/browser/resources/ntp_search/new_tab.js ('k') | no next file » | 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 /** 8 /**
9 * The maximum gap from the edge of the scrolling area which will display 9 * The maximum gap from the edge of the scrolling area which will display
10 * the shadow with transparency. After this point the shadow will become 10 * the shadow with transparency. After this point the shadow will become
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 // |opt_animate| argument, but that's not necesarilly applicable to 320 // |opt_animate| argument, but that's not necesarilly applicable to
321 // removing a tilePage. Selecting a different card in an animated way and 321 // removing a tilePage. Selecting a different card in an animated way and
322 // deleting the card afterward is probably a better choice. 322 // deleting the card afterward is probably a better choice.
323 assert(typeof arguments[0] != 'boolean', 323 assert(typeof arguments[0] != 'boolean',
324 'This function takes no |opt_animate| argument.'); 324 'This function takes no |opt_animate| argument.');
325 this.parentNode.removeChild(this); 325 this.parentNode.removeChild(this);
326 }, 326 },
327 327
328 /** 328 /**
329 * Notify interested subscribers that a tile has been removed from this 329 * Notify interested subscribers that a tile has been removed from this
330 * page. TODO(pedrosimonetti): Do we really need to fire this event? 330 * page.
331 * @param {TileCell} tile The newly added tile. 331 * @param {Tile} tile The newly added tile.
332 * @param {number} index The index of the tile that was added. 332 * @param {number} index The index of the tile that was added.
333 * @param {boolean} wasAnimated Whether the removal was animated. 333 * @param {boolean} wasAnimated Whether the removal was animated.
334 */ 334 */
335 fireAddedEvent: function(tile, index, wasAnimated) { 335 fireAddedEvent: function(tile, index, wasAnimated) {
336 var e = document.createEvent('Event'); 336 var e = document.createEvent('Event');
337 e.initEvent('tilePage:tile_added', true, true); 337 e.initEvent('tilePage:tile_added', true, true);
338 e.addedIndex = index; 338 e.addedIndex = index;
339 e.addedTile = tile; 339 e.addedTile = tile;
340 e.wasAnimated = wasAnimated; 340 e.wasAnimated = wasAnimated;
341 this.dispatchEvent(e); 341 this.dispatchEvent(e);
342 }, 342 },
343 343
344 /** 344 /**
345 * Removes the given tile and animates the repositioning of the other tiles. 345 * Removes the given tile and animates the repositioning of the other tiles.
346 * @param {boolean=} opt_animate Whether the removal should be animated. 346 * @param {boolean=} opt_animate Whether the removal should be animated.
347 * @param {boolean=} opt_dontNotify Whether a page should be removed if the 347 * @param {boolean=} opt_dontNotify Whether a page should be removed if the
348 * last tile is removed from it. 348 * last tile is removed from it.
349 */ 349 */
350 removeTile: function(tile, opt_animate, opt_dontNotify) { 350 removeTile: function(tile, opt_animate, opt_dontNotify) {
351 var tiles = this.tiles; 351 var tiles = this.tiles;
352 var index = tiles.indexOf(tile); 352 var index = tiles.indexOf(tile);
353 tile.parentNode.removeChild(tile); 353 tile.parentNode.removeChild(tile);
354 tiles.splice(index, 1); 354 tiles.splice(index, 1);
355 this.renderGrid_(); 355 this.renderGrid();
356 356
357 if (!opt_dontNotify) 357 if (!opt_dontNotify)
358 this.fireRemovedEvent(tile, index, !!opt_animate); 358 this.fireRemovedEvent(tile, index, !!opt_animate);
359 }, 359 },
360 360
361 /** 361 /**
362 * Notify interested subscribers that a tile has been removed from this 362 * Notify interested subscribers that a tile has been removed from this
363 * page. 363 * page.
364 * @param {TileCell} tile The tile that was removed. 364 * @param {TileCell} tile The tile that was removed.
365 * @param {number} oldIndex Where the tile was positioned before removal. 365 * @param {number} oldIndex Where the tile was positioned before removal.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 }, 435 },
436 436
437 /** 437 /**
438 * Adds the given element to the tile grid. 438 * Adds the given element to the tile grid.
439 * @param {Tile} tile The tile to be added. 439 * @param {Tile} tile The tile to be added.
440 * @param {number} index The location in the tile grid to insert it at. 440 * @param {number} index The location in the tile grid to insert it at.
441 * @protected 441 * @protected
442 */ 442 */
443 addTileAt: function(tile, index) { 443 addTileAt: function(tile, index) {
444 this.tiles_.splice(index, 0, tile); 444 this.tiles_.splice(index, 0, tile);
445 this.fireAddedEvent(tile, index); 445 this.fireAddedEvent(tile, index, false);
446 this.renderGrid();
446 }, 447 },
447 448
448 /** 449 /**
449 * Create a blank tile. 450 * Create a blank tile.
450 * @protected 451 * @protected
451 */ 452 */
452 createTile_: function() { 453 createTile_: function() {
453 return new this.TileClass(this.config); 454 return new this.TileClass(this.config);
454 }, 455 },
455 456
456 /** 457 /**
457 * Create blank tiles. 458 * Create blank tiles.
458 * @param {number} count The desired number of Tiles to be created. If this 459 * @param {number} count The desired number of Tiles to be created. If this
459 * value the maximum value defined in |config.maxTileCount|, the maximum 460 * value the maximum value defined in |config.maxTileCount|, the maximum
460 * value will be used instead. 461 * value will be used instead.
461 * @protected 462 * @protected
462 */ 463 */
463 createTiles_: function(count) { 464 createTiles_: function(count) {
464 count = Math.min(count, this.config.maxTileCount); 465 count = Math.min(count, this.config.maxTileCount);
465 for (var i = 0; i < count; i++) { 466 for (var i = 0; i < count; i++) {
466 this.appendTile(this.createTile_()); 467 this.appendTile(this.createTile_());
467 } 468 }
468 }, 469 },
469 470
470 /** 471 /**
472 * This method will create/remove necessary/unnecessary tiles, render the
473 * grid when the number of tiles has changed, and finally will call
474 * |updateTiles_| which will in turn render the individual tiles.
475 * @protected
476 */
477 updateGrid: function() {
478 var dataListLength = this.dataList_.length;
479 var tileCount = this.tileCount;
480 // Create or remove tiles if necessary.
481 if (tileCount < dataListLength) {
482 this.createTiles_(dataListLength - tileCount);
483 } else if (tileCount > dataListLength) {
484 var tiles = this.tiles_;
485 while (tiles.length > dataListLength) {
486 var previousLength = tiles.length;
487 // It doesn't matter which tiles are being removed here because
488 // they're going to be reconstructed below when calling updateTiles_
489 // method, so the first tiles are being removed here.
490 this.removeTile(tiles[0]);
491 assert(tiles.length < previousLength);
492 }
493 }
494
495 this.updateTiles_();
496 },
497
498 /**
471 * Update the tiles after a change to |dataList_|. 499 * Update the tiles after a change to |dataList_|.
472 */ 500 */
473 updateTiles_: function() { 501 updateTiles_: function() {
474 var maxTileCount = this.config.maxTileCount; 502 var maxTileCount = this.config.maxTileCount;
475 var dataList = this.dataList_; 503 var dataList = this.dataList_;
476 var tiles = this.tiles; 504 var tiles = this.tiles;
477 for (var i = 0; i < maxTileCount; i++) { 505 for (var i = 0; i < maxTileCount; i++) {
478 var data = dataList[i]; 506 var data = dataList[i];
479 var tile = tiles[i]; 507 var tile = tiles[i];
480 508
481 // TODO(pedrosimonetti): What do we do when there's no tile here? 509 // TODO(pedrosimonetti): What do we do when there's no tile here?
482 if (!tile) 510 if (!tile)
483 return; 511 return;
484 512
485 if (i >= dataList.length) 513 if (i >= dataList.length)
486 tile.reset(); 514 tile.reset();
487 else 515 else
488 tile.data = data; 516 tile.data = data;
489 } 517 }
490 }, 518 },
491 519
492 /** 520 /**
493 * Sets the dataList that will be used to create Tiles. This method will 521 * Sets the dataList that will be used to create Tiles.
494 * create/remove necessary/unnecessary tiles, render the grid when the 522 * TODO(pedrosimonetti): Use setters and getters instead.
495 * number of tiles has changed, and finally will call |updateTiles_| which
496 * will in turn render the individual tiles.
497 * @param {Array} dataList The array of data.
498 */ 523 */
499 setDataList: function(dataList) { 524 setDataList: function(dataList) {
500 this.dataList_ = dataList.slice(0, this.config.maxTileCount); 525 this.dataList_ = dataList.slice(0, this.config.maxTileCount);
501
502 var dataListLength = this.dataList_.length;
503 var tileCount = this.tileCount;
504 // Create or remove tiles if necessary.
505 if (tileCount < dataListLength) {
506 this.createTiles_(dataListLength - tileCount);
507 } else if (tileCount > dataListLength) {
508 var tiles = this.tiles_;
509 while (tiles.length > dataListLength) {
510 var previousLength = tiles.length;
511 // It doesn't matter which tiles are being removed here because
512 // they're going to be reconstructed below when calling updateTiles_
513 // method, so the first tiles are being removed here.
514 this.removeTile(tiles[0]);
515 assert(tiles.length < previousLength);
516 }
517 }
518
519 if (dataListLength != tileCount)
520 this.renderGrid_();
521
522 this.updateTiles_();
523 }, 526 },
524 527
525 // internal helpers 528 // internal helpers
526 // ------------------------------------------------------------------------- 529 // -------------------------------------------------------------------------
527 530
528 /** 531 /**
529 * Gets the required width for a Tile. 532 * Gets the required width for a Tile.
530 * @private 533 * @private
531 */ 534 */
532 getTileRequiredWidth_: function() { 535 getTileRequiredWidth_: function() {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 * Renders the tile grid, and the individual tiles. Rendering the grid 589 * Renders the tile grid, and the individual tiles. Rendering the grid
587 * consists of adding/removing tile rows and tile cells according to the 590 * consists of adding/removing tile rows and tile cells according to the
588 * specified size (defined by the number of columns in the grid). While 591 * specified size (defined by the number of columns in the grid). While
589 * rendering the grid, the tiles are rendered in order in their respective 592 * rendering the grid, the tiles are rendered in order in their respective
590 * cells and tile fillers are rendered when needed. This method sets the 593 * cells and tile fillers are rendered when needed. This method sets the
591 * private properties colCount_ and rowCount_. 594 * private properties colCount_ and rowCount_.
592 * 595 *
593 * This method should be called every time the contents of the grid changes, 596 * This method should be called every time the contents of the grid changes,
594 * that is, when the number, contents or order of the tiles has changed. 597 * that is, when the number, contents or order of the tiles has changed.
595 * @param {number=} opt_colCount The number of columns. 598 * @param {number=} opt_colCount The number of columns.
596 * @private 599 * @protected
597 */ 600 */
598 renderGrid_: function(opt_colCount) { 601 renderGrid: function(opt_colCount) {
599 var colCount = opt_colCount || this.colCount_; 602 var colCount = opt_colCount || this.colCount_;
600 603
601 var tileGridContent = this.tileGridContent_; 604 var tileGridContent = this.tileGridContent_;
602 var tiles = this.tiles_; 605 var tiles = this.tiles_;
603 var tileCount = tiles.length; 606 var tileCount = tiles.length;
604 607
605 var rowCount = Math.ceil(tileCount / colCount); 608 var rowCount = Math.ceil(tileCount / colCount);
606 var tileRows = tileGridContent.getElementsByClassName('tile-row'); 609 var tileRows = tileGridContent.getElementsByClassName('tile-row');
607 610
608 for (var tile = 0, row = 0; row < rowCount; row++) { 611 for (var tile = 0, row = 0; row < rowCount; row++) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 var lastColCount = this.colCount_; 696 var lastColCount = this.colCount_;
694 var animatingColCount = this.animatingColCount_; 697 var animatingColCount = this.animatingColCount_;
695 if (colCount != animatingColCount) { 698 if (colCount != animatingColCount) {
696 if (opt_animate) 699 if (opt_animate)
697 this.tileGrid_.classList.add('animate-grid-width'); 700 this.tileGrid_.classList.add('animate-grid-width');
698 701
699 if (colCount > animatingColCount) { 702 if (colCount > animatingColCount) {
700 // If the grid is expanding, it needs to be rendered first so the 703 // If the grid is expanding, it needs to be rendered first so the
701 // revealing tiles are visible as soon as the animation starts. 704 // revealing tiles are visible as soon as the animation starts.
702 if (colCount != lastColCount) 705 if (colCount != lastColCount)
703 this.renderGrid_(colCount); 706 this.renderGrid(colCount);
704 707
705 // Hides affected columns and forces the reflow. 708 // Hides affected columns and forces the reflow.
706 this.showTileCols_(animatingColCount, false); 709 this.showTileCols_(animatingColCount, false);
707 // Trigger reflow, making the tiles completely hidden. 710 // Trigger reflow, making the tiles completely hidden.
708 this.tileGrid_.offsetTop; 711 this.tileGrid_.offsetTop;
709 // Fades in the affected columns. 712 // Fades in the affected columns.
710 this.showTileCols_(animatingColCount, true); 713 this.showTileCols_(animatingColCount, true);
711 } else { 714 } else {
712 // Fades out the affected columns. 715 // Fades out the affected columns.
713 this.showTileCols_(colCount, false); 716 this.showTileCols_(colCount, false);
714 } 717 }
715 718
716 var newWidth = this.getWidthForColCount_(colCount); 719 var newWidth = this.getWidthForColCount_(colCount);
717 this.tileGrid_.style.width = newWidth + 'px'; 720 this.tileGrid_.style.width = newWidth + 'px';
718 721
719 // TODO(pedrosimonetti): move to handler below. 722 // TODO(pedrosimonetti): move to handler below.
720 var self = this; 723 var self = this;
721 this.onTileGridTransitionEndHandler_ = function() { 724 this.onTileGridTransitionEndHandler_ = function() {
722 if (colCount < lastColCount) 725 if (colCount < lastColCount)
723 self.renderGrid_(colCount); 726 self.renderGrid(colCount);
724 else 727 else
725 self.showTileCols_(0, true); 728 self.showTileCols_(0, true);
726 }; 729 };
727 } 730 }
728 731
729 this.animatingColCount_ = colCount; 732 this.animatingColCount_ = colCount;
730 733
731 this.frame_.style.width = contentWidth + 'px'; 734 this.frame_.style.width = contentWidth + 'px';
732 735
733 this.onScroll(); 736 this.onScroll();
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 repositioningStartIndex, repositioningEndIndex, true); 822 repositioningStartIndex, repositioningEndIndex, true);
820 823
821 this.removeTile(tileBeingRemoved); 824 this.removeTile(tileBeingRemoved);
822 825
823 // If the extra tile is a real one (not a filler), then it needs to be 826 // If the extra tile is a real one (not a filler), then it needs to be
824 // added to the tile list. The tile has been placed in the right spot 827 // added to the tile list. The tile has been placed in the right spot
825 // but the tile page still doesn't know about this new tile. 828 // but the tile page still doesn't know about this new tile.
826 if (extraTileData) 829 if (extraTileData)
827 this.appendTile(extraTile); 830 this.appendTile(extraTile);
828 831
829 this.renderGrid_();
830 }.bind(this); 832 }.bind(this);
831 833
832 // Listens to the animation end. 834 // Listens to the animation end.
833 var lastAnimatingTile = extraTile; 835 var lastAnimatingTile = extraTile;
834 lastAnimatingTile.addEventListener('webkitTransitionEnd', 836 lastAnimatingTile.addEventListener('webkitTransitionEnd',
835 onPositioningTransitionEnd); 837 onPositioningTransitionEnd);
836 }, 838 },
837 839
838 /** 840 /**
839 * Animates a tile restoration. 841 * Animates a tile restoration.
(...skipping 11 matching lines...) Expand all
851 853
852 var repositioningStartIndex = index; 854 var repositioningStartIndex = index;
853 var repositioningEndIndex = tileCount - (extraTileData ? 1 : 0); 855 var repositioningEndIndex = tileCount - (extraTileData ? 1 : 0);
854 856
855 this.initializeRepositioningAnimation_(index, repositioningEndIndex); 857 this.initializeRepositioningAnimation_(index, repositioningEndIndex);
856 858
857 var restoredData = newDataList[index]; 859 var restoredData = newDataList[index];
858 var tileBeingRestored = createTile(this, restoredData); 860 var tileBeingRestored = createTile(this, restoredData);
859 tileCells[index].appendChild(tileBeingRestored); 861 tileCells[index].appendChild(tileBeingRestored);
860 862
861 var extraTile = extraCell.tile; 863 if (this.config.scrollable)
864 this.content_.scrollTop = tileCells[index].offsetTop;
865
866 var extraTile;
867 if (extraCell)
868 extraTile = extraCell.tile;
862 869
863 this.executeRepositioningAnimation_(tileBeingRestored, extraTile, 870 this.executeRepositioningAnimation_(tileBeingRestored, extraTile,
864 repositioningStartIndex, repositioningEndIndex, false); 871 repositioningStartIndex, repositioningEndIndex, false);
865 872
866 // Cleans up the animation. 873 // Cleans up the animation.
867 var onPositioningTransitionEnd = function(e) { 874 var onPositioningTransitionEnd = function(e) {
868 var propertyName = e.propertyName; 875 var propertyName = e.propertyName;
869 if (!(propertyName == '-webkit-transform' || 876 if (!(propertyName == '-webkit-transform' ||
870 propertyName == 'opacity')) { 877 propertyName == 'opacity')) {
871 return; 878 return;
872 } 879 }
873 880
874 lastAnimatingTile.removeEventListener('webkitTransitionEnd', 881 lastAnimatingTile.removeEventListener('webkitTransitionEnd',
875 onPositioningTransitionEnd); 882 onPositioningTransitionEnd);
876 883
877 // When there's an extra data, it means the tile is a real one (not a 884 // When there's an extra data, it means the tile is a real one (not a
878 // filler), and therefore it needs to be removed from the tile list. 885 // filler), and therefore it needs to be removed from the tile list.
879 if (extraTileData) 886 if (extraTileData)
880 this.removeTile(extraTile); 887 this.removeTile(extraTile);
881 888
882 this.finalizeRepositioningAnimation_(tileBeingRestored, 889 this.finalizeRepositioningAnimation_(tileBeingRestored,
883 repositioningStartIndex, repositioningEndIndex, false); 890 repositioningStartIndex, repositioningEndIndex, false);
884 891
885 this.addTileAt(tileBeingRestored, index); 892 this.addTileAt(tileBeingRestored, index);
886 893
887 this.renderGrid_();
888 }.bind(this); 894 }.bind(this);
889 895
890 // Listens to the animation end. 896 // Listens to the animation end.
891 var lastAnimatingTile = tileBeingRestored; 897 var lastAnimatingTile = tileBeingRestored;
892 lastAnimatingTile.addEventListener('webkitTransitionEnd', 898 lastAnimatingTile.addEventListener('webkitTransitionEnd',
893 onPositioningTransitionEnd); 899 onPositioningTransitionEnd);
894 }, 900 },
895 901
896 // animation helpers 902 // animation helpers
897 // ------------------------------------------------------------------------- 903 // -------------------------------------------------------------------------
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 * @param {number} endIndex Index of the last tile to be repositioned. 958 * @param {number} endIndex Index of the last tile to be repositioned.
953 * @param {boolean} isRemoving Whether the tile is being removed. 959 * @param {boolean} isRemoving Whether the tile is being removed.
954 * @private 960 * @private
955 */ 961 */
956 executeRepositioningAnimation_: function(targetTile, extraTile, startIndex, 962 executeRepositioningAnimation_: function(targetTile, extraTile, startIndex,
957 endIndex, isRemoving) { 963 endIndex, isRemoving) {
958 targetTile.classList.add('target-tile'); 964 targetTile.classList.add('target-tile');
959 965
960 // Alternate the visualization of the target and extra tiles. 966 // Alternate the visualization of the target and extra tiles.
961 fadeTile(targetTile, !isRemoving); 967 fadeTile(targetTile, !isRemoving);
962 fadeTile(extraTile, isRemoving); 968 if (extraTile)
969 fadeTile(extraTile, isRemoving);
963 970
964 // Move tiles to the new position. 971 // Move tiles to the new position.
965 var tiles = this.tiles_; 972 var tiles = this.tiles_;
966 var positionDiff = isRemoving ? -1 : 1; 973 var positionDiff = isRemoving ? -1 : 1;
967 for (var i = startIndex; i < endIndex; i++) { 974 for (var i = startIndex; i < endIndex; i++) {
968 var position = this.getTilePosition_(i + positionDiff); 975 var position = this.getTilePosition_(i + positionDiff);
969 this.moveTileTo_(tiles[i], position.left, position.top); 976 this.moveTileTo_(tiles[i], position.left, position.top);
970 } 977 }
971 }, 978 },
972 979
(...skipping 14 matching lines...) Expand all
987 targetTile.classList.remove('target-tile'); 994 targetTile.classList.remove('target-tile');
988 995
989 // Move tiles back to relative position. 996 // Move tiles back to relative position.
990 var tiles = this.tiles_; 997 var tiles = this.tiles_;
991 var tileCells = this.querySelectorAll('.tile-cell'); 998 var tileCells = this.querySelectorAll('.tile-cell');
992 var positionDiff = isRemoving ? -1 : 1; 999 var positionDiff = isRemoving ? -1 : 1;
993 for (var i = startIndex; i < endIndex; i++) { 1000 for (var i = startIndex; i < endIndex; i++) {
994 var tile = tiles[i]; 1001 var tile = tiles[i];
995 this.resetTilePosition_(tile); 1002 this.resetTilePosition_(tile);
996 tile.style.zIndex = ''; 1003 tile.style.zIndex = '';
997 tileCells[i + positionDiff].assign(tile); 1004 var tileCell = tileCells[i + positionDiff];
1005 if (tileCell)
1006 tileCell.assign(tile);
998 } 1007 }
999 }, 1008 },
1000 1009
1001 /** 1010 /**
1002 * Animates the display of columns. 1011 * Animates the display of columns.
1003 * @param {number} col The column number. 1012 * @param {number} col The column number.
1004 * @param {boolean} show Whether or not to show the row. 1013 * @param {boolean} show Whether or not to show the row.
1005 */ 1014 */
1006 showTileCols_: function(col, show) { 1015 showTileCols_: function(col, show) {
1007 var prop = show ? 'remove' : 'add'; 1016 var prop = show ? 'remove' : 'add';
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 tile.scrollTop; 1108 tile.scrollTop;
1100 tile.classList.remove(className); 1109 tile.classList.remove(className);
1101 } 1110 }
1102 } 1111 }
1103 1112
1104 return { 1113 return {
1105 Tile: Tile, 1114 Tile: Tile,
1106 TilePage: TilePage, 1115 TilePage: TilePage,
1107 }; 1116 };
1108 }); 1117 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/ntp_search/new_tab.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698