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

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

Issue 11412214: NTP5: Fine tuning of Apps implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 /**
9 * @type {number}
10 * @const
11 */
12 var TILE_ROW_HEIGHT = 92;
13
14 /**
15 * @type {number}
16 * @const
17 */
18 var SCROLL_BAR_WIDTH = 12;
19
8 //---------------------------------------------------------------------------- 20 //----------------------------------------------------------------------------
9 // Tile 21 // Tile
10 //---------------------------------------------------------------------------- 22 //----------------------------------------------------------------------------
11 23
12 /** 24 /**
13 * A virtual Tile class. Each TilePage subclass should have its own Tile 25 * A virtual Tile class. Each TilePage subclass should have its own Tile
14 * subclass implemented too (e.g. MostVisitedPage contains MostVisited 26 * subclass implemented too (e.g. MostVisitedPage contains MostVisited
15 * tiles, and MostVisited is a Tile subclass). 27 * tiles, and MostVisited is a Tile subclass).
16 * @constructor 28 * @constructor
17 * @param {Object} config TilePage configuration object. 29 * @param {Object} config TilePage configuration object.
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 202
191 /** 203 /**
192 * Creates a new TilePage object. This object contains tiles and controls 204 * Creates a new TilePage object. This object contains tiles and controls
193 * their layout. 205 * their layout.
194 * @constructor 206 * @constructor
195 * @extends {HTMLDivElement} 207 * @extends {HTMLDivElement}
196 */ 208 */
197 function TilePage() { 209 function TilePage() {
198 var el = cr.doc.createElement('div'); 210 var el = cr.doc.createElement('div');
199 el.__proto__ = TilePage.prototype; 211 el.__proto__ = TilePage.prototype;
200 el.initialize();
201 212
202 return el; 213 return el;
203 } 214 }
204 215
205 TilePage.prototype = { 216 TilePage.prototype = {
206 __proto__: HTMLDivElement.prototype, 217 __proto__: HTMLDivElement.prototype,
207 218
208 /** 219 /**
209 * Reference to the Tile subclass that will be used to create the tiles. 220 * Reference to the Tile subclass that will be used to create the tiles.
210 * @constructor 221 * @constructor
211 * @extends {Tile} 222 * @extends {Tile}
212 */ 223 */
213 TileClass: Tile, 224 TileClass: Tile,
214 225
215 // The config object should be defined by a TilePage subclass if it 226 // The config object should be defined by a TilePage subclass if it
216 // wants the non-default behavior. 227 // wants the non-default behavior.
217 config: { 228 config: {
218 // The width of a cell. 229 // The width of a cell.
219 cellWidth: 110, 230 cellWidth: 110,
220 // The start margin of a cell (left or right according to text direction). 231 // The start margin of a cell (left or right according to text direction).
221 cellMarginStart: 12, 232 cellMarginStart: 12,
222 // The maximum number of Tiles to be displayed. 233 // The maximum number of Tiles to be displayed.
223 maxTileCount: 6 234 maxTileCount: 6,
235 // Whether the TilePage content will be scrollable.
236 scrollable: false
224 }, 237 },
225 238
226 /** 239 /**
227 * Initializes a TilePage. 240 * Initializes a TilePage.
228 */ 241 */
229 initialize: function() { 242 initialize: function() {
230 this.className = 'tile-page'; 243 this.className = 'tile-page';
231 244
232 // The content defines the actual space a page has to display tiles. 245 // The div that wraps the scrollable element.
246 this.frame_ = this.ownerDocument.createElement('div');
247 this.frame_.className = 'tile-page-frame';
248 this.appendChild(this.frame_);
249
250 // The content/scrollable element.
233 this.content_ = this.ownerDocument.createElement('div'); 251 this.content_ = this.ownerDocument.createElement('div');
234 this.content_.className = 'tile-page-content'; 252 this.content_.className = 'tile-page-content';
235 this.appendChild(this.content_); 253 this.frame_.appendChild(this.content_);
254
255 if (this.config.scrollable) {
256 this.content_.classList.add('scrollable');
257
258 // The scrollable shadow top.
259 this.shadowTop_ = document.createElement('div');
Dan Beam 2012/11/29 04:59:55 this.ownerDocument.createElement('div') here and b
pedro (no code reviews) 2012/11/29 08:02:37 Done.
260 this.shadowTop_.className = 'scrollable-shadow-top';
261 this.content_.appendChild(this.shadowTop_);
262
263 // The scrollable shadow bottom.
264 this.shadowBottom_ = document.createElement('div');
265 this.shadowBottom_.className = 'scrollable-shadow-bottom';
266 this.content_.appendChild(this.shadowBottom_);
267 }
236 268
237 // The div that defines the tile grid viewport. 269 // The div that defines the tile grid viewport.
238 this.tileGrid_ = this.ownerDocument.createElement('div'); 270 this.tileGrid_ = this.ownerDocument.createElement('div');
239 this.tileGrid_.className = 'tile-grid'; 271 this.tileGrid_.className = 'tile-grid';
240 this.content_.appendChild(this.tileGrid_); 272 this.content_.appendChild(this.tileGrid_);
241 273
242 // The tile grid contents, which can be scrolled. 274 // The tile grid contents, which can be scrolled.
243 this.tileGridContent_ = this.ownerDocument.createElement('div'); 275 this.tileGridContent_ = this.ownerDocument.createElement('div');
244 this.tileGridContent_.className = 'tile-grid-content'; 276 this.tileGridContent_.className = 'tile-grid-content';
245 this.tileGrid_.appendChild(this.tileGridContent_); 277 this.tileGrid_.appendChild(this.tileGridContent_);
246 278
247 // The list of Tile elements which is used to fill the TileGrid cells. 279 // The list of Tile elements which is used to fill the TileGrid cells.
248 this.tiles_ = []; 280 this.tiles_ = [];
249 281
250 // TODO(pedrosimonetti): Check duplication of these methods. 282 // TODO(pedrosimonetti): Check duplication of these methods.
251 this.addEventListener('cardselected', this.handleCardSelection_); 283 this.addEventListener('cardselected', this.handleCardSelection_);
252 this.addEventListener('carddeselected', this.handleCardDeselection_); 284 this.addEventListener('carddeselected', this.handleCardDeselection_);
253 285
254 this.tileGrid_.addEventListener('webkitTransitionEnd', 286 this.tileGrid_.addEventListener('webkitTransitionEnd',
255 this.onTileGridTransitionEnd_.bind(this)); 287 this.onTileGridTransitionEnd_.bind(this));
288
289 this.content_.addEventListener('scroll', this.onScroll_.bind(this));
256 }, 290 },
257 291
258 /** 292 /**
259 * The list of Tile elements. 293 * The list of Tile elements.
260 * @type {Array<Tile>} 294 * @type {Array<Tile>}
261 */ 295 */
262 get tiles() { 296 get tiles() {
263 return this.tiles_; 297 return this.tiles_;
264 }, 298 },
265 299
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 var config = this.config; 525 var config = this.config;
492 return config.cellWidth + config.cellMarginStart; 526 return config.cellWidth + config.cellMarginStart;
493 }, 527 },
494 528
495 /** 529 /**
496 * Gets the the maximum number of columns that can fit in a given width. 530 * Gets the the maximum number of columns that can fit in a given width.
497 * @param {number} width The width in pixels. 531 * @param {number} width The width in pixels.
498 * @private 532 * @private
499 */ 533 */
500 getColCountForWidth_: function(width) { 534 getColCountForWidth_: function(width) {
501 var availableWidth = width + this.config.cellMarginStart; 535 var content = this.content_;
Dan Beam 2012/11/29 04:59:55 nit: don't really see the point to this var...
pedro (no code reviews) 2012/11/29 08:02:37 Var removed.
536 var scrollBarIsVisible = this.config.scrollable &&
537 content.scrollHeight > content.clientHeight;
538 var scrollBarWidth = scrollBarIsVisible ? SCROLL_BAR_WIDTH : 0;
539 var availableWidth = width + this.config.cellMarginStart - scrollBarWidth;
540
502 var requiredWidth = this.getTileRequiredWidth_(); 541 var requiredWidth = this.getTileRequiredWidth_();
503 var colCount = Math.floor(availableWidth / requiredWidth); 542 var colCount = Math.floor(availableWidth / requiredWidth);
504 return colCount; 543 return colCount;
505 }, 544 },
506 545
507 /** 546 /**
508 * Gets the width for a given number of columns. 547 * Gets the width for a given number of columns.
509 * @param {number} colCount The number of columns. 548 * @param {number} colCount The number of columns.
510 * @private 549 * @private
511 */ 550 */
512 getWidthForColCount_: function(colCount) { 551 getWidthForColCount_: function(colCount) {
513 var requiredWidth = this.getTileRequiredWidth_(); 552 var requiredWidth = this.getTileRequiredWidth_();
514 var width = colCount * requiredWidth - this.config.cellMarginStart; 553 var width = colCount * requiredWidth - this.config.cellMarginStart;
515 return width; 554 return width;
516 }, 555 },
517 556
518 /** 557 /**
519 * Returns the position of the tile at |index|. 558 * Returns the position of the tile at |index|.
520 * @param {number} index Tile index. 559 * @param {number} index Tile index.
521 * @private 560 * @private
522 * @return {!{top: number, left: number}} Position. 561 * @return {!{top: number, left: number}} Position.
523 */ 562 */
524 getTilePosition_: function(index) { 563 getTilePosition_: function(index) {
525 var colCount = this.colCount_; 564 var colCount = this.colCount_;
565 var row = Math.floor(index / colCount);
526 var col = index % colCount; 566 var col = index % colCount;
527 if (isRTL()) 567 if (isRTL())
528 col = colCount - col - 1; 568 col = colCount - col - 1;
529 var config = this.config; 569 var config = this.config;
570 var top = TILE_ROW_HEIGHT * row;
530 var left = col * (config.cellWidth + config.cellMarginStart); 571 var left = col * (config.cellWidth + config.cellMarginStart);
531 return {top: 0, left: left}; 572 return {top: top, left: left};
532 }, 573 },
533 574
534 // rendering 575 // rendering
535 // ------------------------------------------------------------------------- 576 // -------------------------------------------------------------------------
536 577
537 /** 578 /**
538 * Renders the tile grid, and the individual tiles. Rendering the grid 579 * Renders the tile grid, and the individual tiles. Rendering the grid
539 * consists of adding/removing tile rows and tile cells according to the 580 * consists of adding/removing tile rows and tile cells according to the
540 * specified size (defined by the number of columns in the grid). While 581 * specified size (defined by the number of columns in the grid). While
541 * rendering the grid, the tiles are rendered in order in their respective 582 * rendering the grid, the tiles are rendered in order in their respective
(...skipping 21 matching lines...) Expand all
563 for (var tile = 0, row = 0; row < rowCount; row++) { 604 for (var tile = 0, row = 0; row < rowCount; row++) {
564 var tileRow = tileRows[row]; 605 var tileRow = tileRows[row];
565 606
566 // Create tile row if there's no one yet. 607 // Create tile row if there's no one yet.
567 if (!tileRow) { 608 if (!tileRow) {
568 tileRow = cr.doc.createElement('div'); 609 tileRow = cr.doc.createElement('div');
569 tileRow.className = 'tile-row'; 610 tileRow.className = 'tile-row';
570 tileGridContent.appendChild(tileRow); 611 tileGridContent.appendChild(tileRow);
571 } 612 }
572 613
573 // Adjust row visibility.
574 var rowVisible = row >= pageOffset &&
575 row <= (pageOffset + numOfVisibleRows - 1);
576 this.showTileRow_(tileRow, rowVisible);
577
578 // The tiles inside the current row. 614 // The tiles inside the current row.
579 var tileRowTiles = tileRow.childNodes; 615 var tileRowTiles = tileRow.childNodes;
580 616
581 // Remove excessive columns from a particular tile row. 617 // Remove excessive columns from a particular tile row.
582 var maxColCount = Math.min(colCount, tileCount - tile); 618 var maxColCount = Math.min(colCount, tileCount - tile);
583 maxColCount = Math.max(0, maxColCount); 619 maxColCount = Math.max(0, maxColCount);
584 while (tileRowTiles.length > maxColCount) { 620 while (tileRowTiles.length > maxColCount) {
585 tileRow.removeChild(tileRow.lastElementChild); 621 tileRow.removeChild(tileRow.lastElementChild);
586 } 622 }
587 623
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 } 655 }
620 } 656 }
621 657
622 // Remove excessive tile rows from the tile grid. 658 // Remove excessive tile rows from the tile grid.
623 while (tileRows.length > rowCount) { 659 while (tileRows.length > rowCount) {
624 tileGridContent.removeChild(tileGridContent.lastElementChild); 660 tileGridContent.removeChild(tileGridContent.lastElementChild);
625 } 661 }
626 662
627 this.colCount_ = colCount; 663 this.colCount_ = colCount;
628 this.rowCount_ = rowCount; 664 this.rowCount_ = rowCount;
665
666 if (this.onScroll_)
Dan Beam 2012/11/29 04:59:55 nit: like I already mentioned, this should be prot
pedro (no code reviews) 2012/11/29 08:02:37 Ack.
667 this.onScroll_();
629 }, 668 },
630 669
631 // layout 670 // layout
632 // ------------------------------------------------------------------------- 671 // -------------------------------------------------------------------------
633 672
634 /** 673 /**
635 * Calculates the layout of the tile page according to the current Bottom 674 * Calculates the layout of the tile page according to the current Bottom
636 * Panel's size. This method will resize the containers of the tile page, 675 * Panel's size. This method will resize the containers of the tile page,
637 * and re-render the grid when its dimension changes (number of columns or 676 * and re-render the grid when its dimension changes (number of columns or
638 * visible rows changes). This method also sets the private properties 677 * visible rows changes). This method also sets the private properties
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 // TODO(pedrosimonetti): move to handler below. 713 // TODO(pedrosimonetti): move to handler below.
675 var self = this; 714 var self = this;
676 this.onTileGridTransitionEndHandler_ = function() { 715 this.onTileGridTransitionEndHandler_ = function() {
677 if (colCount < lastColCount) 716 if (colCount < lastColCount)
678 self.renderGrid_(colCount); 717 self.renderGrid_(colCount);
679 else 718 else
680 self.showTileCols_(0, true); 719 self.showTileCols_(0, true);
681 }; 720 };
682 } 721 }
683 722
684 this.content_.style.width = contentWidth + 'px'; 723 this.animatingColCount_ = colCount;
685 724
686 this.animatingColCount_ = colCount; 725 this.frame_.style.width = contentWidth + 'px';
726 if (this.onScroll_)
727 this.onScroll_();
687 }, 728 },
688 729
689 // tile repositioning animation 730 // tile repositioning animation
690 // ------------------------------------------------------------------------- 731 // -------------------------------------------------------------------------
691 732
692 /** 733 /**
693 * Tile repositioning state. 734 * Tile repositioning state.
694 * @type {{index: number, isRemoving: number}} 735 * @type {{index: number, isRemoving: number}}
695 */ 736 */
696 tileRepositioningState_: null, 737 tileRepositioningState_: null,
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 var positionDiff = isRemoving ? -1 : 1; 986 var positionDiff = isRemoving ? -1 : 1;
946 for (var i = startIndex; i < endIndex; i++) { 987 for (var i = startIndex; i < endIndex; i++) {
947 var tile = tiles[i]; 988 var tile = tiles[i];
948 this.resetTilePosition_(tile); 989 this.resetTilePosition_(tile);
949 tile.style.zIndex = ''; 990 tile.style.zIndex = '';
950 tileCells[i + positionDiff].assign(tile); 991 tileCells[i + positionDiff].assign(tile);
951 } 992 }
952 }, 993 },
953 994
954 /** 995 /**
955 * Animates the display of a row. TODO(pedrosimonetti): Make it local? 996 * Animates the display of columns.
956 * @param {HTMLElement} row The row element.
957 * @param {boolean} show Whether or not to show the row.
958 */
959 showTileRow_: function(row, show) {
960 row.classList[show ? 'remove' : 'add']('hide-row');
961 },
962
963 /**
964 * Animates the display of columns. TODO(pedrosimonetti): Make it local?
965 * @param {number} col The column number. 997 * @param {number} col The column number.
966 * @param {boolean} show Whether or not to show the row. 998 * @param {boolean} show Whether or not to show the row.
967 */ 999 */
968 showTileCols_: function(col, show) { 1000 showTileCols_: function(col, show) {
969 var prop = show ? 'remove' : 'add'; 1001 var prop = show ? 'remove' : 'add';
970 var max = 10; // TODO(pedrosimonetti): Add const? 1002 var max = 10; // TODO(pedrosimonetti): Add const?
971 var tileGridContent = this.tileGridContent_; 1003 var tileGridContent = this.tileGridContent_;
972 for (var i = col; i < max; i++) { 1004 for (var i = col; i < max; i++) {
973 tileGridContent.classList[prop]('hide-col-' + i); 1005 tileGridContent.classList[prop]('hide-col-' + i);
974 } 1006 }
975 }, 1007 },
976 1008
977 // event handlers 1009 // event handlers
978 // ------------------------------------------------------------------------- 1010 // -------------------------------------------------------------------------
979 1011
980 /** 1012 /**
1013 * Handles the scroll event.
1014 * @private
Dan Beam 2012/11/29 04:59:55 definitely make this @protected, this would fail t
pedro (no code reviews) 2012/11/29 08:02:37 Done.
1015 */
1016 onScroll_: function(e) {
Dan Beam 2012/11/29 04:59:55 I prefer: BaseClass.prototype = { /** @prot
pedro (no code reviews) 2012/11/29 08:02:37 Done.
1017 if (!this.selected)
1018 return;
1019
1020 // If the TilePage is scrollable, then the opacity of shadow top and
1021 // bottom must adjusted, indicating when there's an overflow content.
1022 if (this.config.scrollable) {
1023 var content = this.content_;
1024 var maxGap = 16;
1025 var topGap = Math.min(maxGap, content.scrollTop);
1026 var bottomGap = Math.min(maxGap, content.scrollHeight -
1027 content.scrollTop - content.clientHeight);
1028
1029 this.shadowTop_.style.opacity = topGap / 16;
1030 this.shadowBottom_.style.opacity = bottomGap / 16;
1031 }
1032 },
1033
1034 /**
981 * Handles the end of the horizontal tile grid transition. 1035 * Handles the end of the horizontal tile grid transition.
982 * @param {Event} e The tile grid webkitTransitionEnd event. 1036 * @param {Event} e The tile grid webkitTransitionEnd event.
983 */ 1037 */
984 onTileGridTransitionEnd_: function(e) { 1038 onTileGridTransitionEnd_: function(e) {
985 if (!this.selected) 1039 if (!this.selected)
986 return; 1040 return;
987 1041
988 // We should remove the classes that control transitions when the 1042 // We should remove the classes that control transitions when the
989 // transition ends so when the text is resized (Ctrl + '+'), no other 1043 // transition ends so when the text is resized (Ctrl + '+'), no other
990 // transition should happen except those defined in the specification. 1044 // transition should happen except those defined in the specification.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 tile.scrollTop; 1097 tile.scrollTop;
1044 tile.classList.remove(className); 1098 tile.classList.remove(className);
1045 } 1099 }
1046 } 1100 }
1047 1101
1048 return { 1102 return {
1049 Tile: Tile, 1103 Tile: Tile,
1050 TilePage: TilePage, 1104 TilePage: TilePage,
1051 }; 1105 };
1052 }); 1106 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698