| Index: third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
|
| diff --git a/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
|
| index 6159e4946800d830b155a8aee6043672e6d24d7d..e8b85f8ac60c7c56d471a24f1e79cfe0faa3500f 100644
|
| --- a/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
|
| +++ b/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
|
| @@ -4,7 +4,8 @@
|
| var IOS_TOUCH_SCROLLING = IOS && IOS[1] >= 8;
|
| var DEFAULT_PHYSICAL_COUNT = 3;
|
| var HIDDEN_Y = '-10000px';
|
| - var DEFAULT_GRID_SIZE = 200;
|
| + var ITEM_WIDTH = 0;
|
| + var ITEM_HEIGHT = 1;
|
| var SECRET_TABINDEX = -100;
|
|
|
| Polymer({
|
| @@ -236,7 +237,7 @@
|
| /**
|
| * The max number of pages to render. One page is equivalent to the height of the list.
|
| */
|
| - _maxPages: 3,
|
| + _maxPages: 2,
|
|
|
| /**
|
| * The currently focused physical item.
|
| @@ -391,10 +392,6 @@
|
| return this._viewportHeight * this._maxPages;
|
| },
|
|
|
| - get _optPhysicalCount() {
|
| - return this._estRowsInView * this._itemsPerRow * this._maxPages;
|
| - },
|
| -
|
| /**
|
| * True if the current list is visible.
|
| */
|
| @@ -474,7 +471,6 @@
|
| },
|
|
|
| attached: function() {
|
| - this.updateViewportBoundaries();
|
| if (this._physicalCount === 0) {
|
| this._debounceTemplate(this._render);
|
| }
|
| @@ -504,119 +500,108 @@
|
| updateViewportBoundaries: function() {
|
| this._scrollerPaddingTop = this.scrollTarget === this ? 0 :
|
| parseInt(window.getComputedStyle(this)['padding-top'], 10);
|
| -
|
| + this._viewportWidth = this.$.items.offsetWidth;
|
| this._viewportHeight = this._scrollTargetHeight;
|
| - if (this.grid) {
|
| - this._updateGridMetrics();
|
| - }
|
| + this.grid && this._updateGridMetrics();
|
| },
|
|
|
| /**
|
| - * Update the models, the position of the
|
| - * items in the viewport and recycle tiles as needed.
|
| + * Recycles the physical items when needed.
|
| */
|
| _scrollHandler: function() {
|
| - // clamp the `scrollTop` value
|
| var scrollTop = Math.max(0, Math.min(this._maxScrollTop, this._scrollTop));
|
| var delta = scrollTop - this._scrollPosition;
|
| - var tileHeight, tileTop, kth, recycledTileSet, scrollBottom, physicalBottom;
|
| - var ratio = this._ratio;
|
| - var recycledTiles = 0;
|
| - var hiddenContentSize = this._hiddenContentSize;
|
| - var currentRatio = ratio;
|
| - var movingUp = [];
|
| -
|
| - // track the last `scrollTop`
|
| + var isScrollingDown = delta >= 0;
|
| + // Track the current scroll position.
|
| this._scrollPosition = scrollTop;
|
| -
|
| - // clear cached visible indexes
|
| + // Clear indexes.
|
| this._firstVisibleIndexVal = null;
|
| this._lastVisibleIndexVal = null;
|
|
|
| - scrollBottom = this._scrollBottom;
|
| - physicalBottom = this._physicalBottom;
|
| -
|
| - // random access
|
| + // Random access.
|
| if (Math.abs(delta) > this._physicalSize) {
|
| - this._physicalTop += delta;
|
| - recycledTiles = Math.round(delta / this._physicalAverage);
|
| - }
|
| - // scroll up
|
| - else if (delta < 0) {
|
| - var topSpace = scrollTop - this._physicalTop;
|
| - var virtualStart = this._virtualStart;
|
| -
|
| - recycledTileSet = [];
|
| -
|
| - kth = this._physicalEnd;
|
| - currentRatio = topSpace / hiddenContentSize;
|
| -
|
| - // move tiles from bottom to top
|
| - while (
|
| - // approximate `currentRatio` to `ratio`
|
| - currentRatio < ratio &&
|
| - // recycle less physical items than the total
|
| - recycledTiles < this._physicalCount &&
|
| - // ensure that these recycled tiles are needed
|
| - virtualStart - recycledTiles > 0 &&
|
| - // ensure that the tile is not visible
|
| - physicalBottom - this._getPhysicalSizeIncrement(kth) > scrollBottom
|
| - ) {
|
| -
|
| - tileHeight = this._getPhysicalSizeIncrement(kth);
|
| - currentRatio += tileHeight / hiddenContentSize;
|
| - physicalBottom -= tileHeight;
|
| - recycledTileSet.push(kth);
|
| - recycledTiles++;
|
| - kth = (kth === 0) ? this._physicalCount - 1 : kth - 1;
|
| + var idxAdjustment = Math.round(delta / this._physicalAverage) * this._itemsPerRow
|
| + this._physicalTop = this._physicalTop + delta;
|
| + this._virtualStart = this._virtualStart + idxAdjustment;
|
| + this._physicalStart = this._physicalStart + idxAdjustment;
|
| + this._update();
|
| + } else {
|
| + var reusables = this._getReusables(isScrollingDown);
|
| + if (isScrollingDown) {
|
| + this._physicalTop = reusables.physicalTop;
|
| + this._virtualStart = this._virtualStart + reusables.indexes.length;
|
| + this._physicalStart = this._physicalStart + reusables.indexes.length;
|
| + } else {
|
| + this._virtualStart = this._virtualStart - reusables.indexes.length;
|
| + this._physicalStart = this._physicalStart - reusables.indexes.length;
|
| }
|
| -
|
| - movingUp = recycledTileSet;
|
| - recycledTiles = -recycledTiles;
|
| - }
|
| - // scroll down
|
| - else if (delta > 0) {
|
| - var bottomSpace = physicalBottom - scrollBottom;
|
| - var virtualEnd = this._virtualEnd;
|
| - var lastVirtualItemIndex = this._virtualCount-1;
|
| -
|
| - recycledTileSet = [];
|
| -
|
| - kth = this._physicalStart;
|
| - currentRatio = bottomSpace / hiddenContentSize;
|
| -
|
| - // move tiles from top to bottom
|
| - while (
|
| - // approximate `currentRatio` to `ratio`
|
| - currentRatio < ratio &&
|
| - // recycle less physical items than the total
|
| - recycledTiles < this._physicalCount &&
|
| - // ensure that these recycled tiles are needed
|
| - virtualEnd + recycledTiles < lastVirtualItemIndex &&
|
| - // ensure that the tile is not visible
|
| - this._physicalTop + this._getPhysicalSizeIncrement(kth) < scrollTop
|
| - ) {
|
| -
|
| - tileHeight = this._getPhysicalSizeIncrement(kth);
|
| - currentRatio += tileHeight / hiddenContentSize;
|
| -
|
| - this._physicalTop += tileHeight;
|
| - recycledTileSet.push(kth);
|
| - recycledTiles++;
|
| - kth = (kth + 1) % this._physicalCount;
|
| + if (reusables.indexes.length === 0) {
|
| + this._increasePoolIfNeeded();
|
| + } else {
|
| + this._update(reusables.indexes, isScrollingDown ? null : reusables.indexes);
|
| }
|
| }
|
| + },
|
|
|
| - if (recycledTiles === 0) {
|
| - // Try to increase the pool if the list's client isn't filled up with physical items
|
| - if (physicalBottom < scrollBottom || this._physicalTop > scrollTop) {
|
| - this._increasePoolIfNeeded();
|
| - }
|
| + /**
|
| + * Returns an object that contains the indexes of the physical items
|
| + * that might be reused and the physicalTop.
|
| + *
|
| + * @param {boolean} fromTop If the potential reusable items are above the scrolling region.
|
| + */
|
| + _getReusables: function(fromTop) {
|
| + var ith, lastIth, offsetContent, physicalItemHeight;
|
| + var idxs = [];
|
| + var protectedOffsetContent = this._hiddenContentSize * this._ratio;
|
| + var virtualStart = this._virtualStart;
|
| + var virtualEnd = this._virtualEnd;
|
| + var physicalCount = this._physicalCount;
|
| + var physicalTop = this._physicalTop;
|
| + var scrollTop = this._scrollTop;
|
| + var scrollBottom = this._scrollBottom;
|
| +
|
| + if (fromTop) {
|
| + ith = this._physicalStart;
|
| + lastIth = this._physicalEnd;
|
| + offsetContent = scrollTop - physicalTop;
|
| } else {
|
| - this._virtualStart = this._virtualStart + recycledTiles;
|
| - this._physicalStart = this._physicalStart + recycledTiles;
|
| - this._update(recycledTileSet, movingUp);
|
| + ith = this._physicalEnd;
|
| + lastIth = this._physicalStart;
|
| + offsetContent = this._physicalBottom - scrollBottom;
|
| + }
|
| + while (true) {
|
| + physicalItemHeight = this._getPhysicalSizeIncrement(ith);
|
| + offsetContent = offsetContent - physicalItemHeight;
|
| + if (idxs.length >= physicalCount || offsetContent <= protectedOffsetContent) {
|
| + break;
|
| + }
|
| + if (fromTop) {
|
| + // Check that index is within the valid range.
|
| + if (virtualEnd + idxs.length + 1 >= this._virtualCount) {
|
| + break;
|
| + }
|
| + // Check that the index is not visible.
|
| + if (physicalTop + physicalItemHeight >= scrollTop) {
|
| + break;
|
| + }
|
| + idxs.push(ith);
|
| + physicalTop = physicalTop + physicalItemHeight;
|
| + ith = (ith + 1) % physicalCount;
|
| + } else {
|
| + // Check that index is within the valid range.
|
| + if (virtualStart - idxs.length <= 0) {
|
| + break;
|
| + }
|
| + // Check that the index is not visible.
|
| + if (physicalTop + this._physicalSize - physicalItemHeight <= scrollBottom) {
|
| + break;
|
| + }
|
| + idxs.push(ith);
|
| + physicalTop = physicalTop - physicalItemHeight;
|
| + ith = (ith === 0) ? physicalCount - 1 : ith - 1;
|
| + }
|
| }
|
| + return { indexes: idxs, physicalTop: physicalTop };
|
| },
|
|
|
| /**
|
| @@ -625,6 +610,9 @@
|
| * @param {!Array<number>=} movingUp
|
| */
|
| _update: function(itemSet, movingUp) {
|
| + if (itemSet && itemSet.length === 0) {
|
| + return;
|
| + }
|
| this._manageFocus();
|
| this._assignModels(itemSet);
|
| this._updateMetrics(itemSet);
|
| @@ -736,13 +724,20 @@
|
| },
|
|
|
| /**
|
| - * Render a new list of items.
|
| + * Renders the a new list.
|
| */
|
| _render: function() {
|
| if (this.isAttached && this._isVisible) {
|
| if (this._physicalCount === 0) {
|
| + this.updateViewportBoundaries();
|
| this._increasePool(DEFAULT_PHYSICAL_COUNT);
|
| } else {
|
| + // Try to recycle nodes
|
| + var reusables = this._getReusables(true);
|
| + this._physicalTop = reusables.physicalTop;
|
| + this._virtualStart = this._virtualStart + reusables.indexes.length;
|
| + this._physicalStart = this._physicalStart + reusables.indexes.length;
|
| + this._update(reusables.indexes);
|
| this._update();
|
| }
|
| }
|
| @@ -878,6 +873,7 @@
|
| } else if (change.path === 'items.splices') {
|
| this._adjustVirtualIndex(change.value.indexSplices);
|
| this._virtualCount = this.items ? this.items.length : 0;
|
| +
|
| this._debounceTemplate(this._render);
|
|
|
| } else {
|
| @@ -972,7 +968,6 @@
|
| var el = this._physicalItems[pidx];
|
| var inst = el._templateInstance;
|
| var item = this.items && this.items[vidx];
|
| -
|
| if (item != null) {
|
| inst[this.as] = item;
|
| inst.__key__ = this._collection.getKey(item);
|
| @@ -1004,22 +999,18 @@
|
| var prevPhysicalAvg = this._physicalAverage;
|
|
|
| this._iterateItems(function(pidx, vidx) {
|
| -
|
| oldPhysicalSize += this._physicalSizes[pidx] || 0;
|
| this._physicalSizes[pidx] = this._physicalItems[pidx].offsetHeight;
|
| newPhysicalSize += this._physicalSizes[pidx];
|
| this._physicalAverageCount += this._physicalSizes[pidx] ? 1 : 0;
|
| -
|
| }, itemSet);
|
| -
|
| - this._viewportHeight = this._scrollTargetHeight;
|
| +
|
| if (this.grid) {
|
| this._updateGridMetrics();
|
| this._physicalSize = Math.ceil(this._physicalCount / this._itemsPerRow) * this._rowHeight;
|
| } else {
|
| this._physicalSize = this._physicalSize + newPhysicalSize - oldPhysicalSize;
|
| }
|
| -
|
| // Update the average if it measured something.
|
| if (this._physicalAverageCount !== prevAvgCount) {
|
| this._physicalAverage = Math.round(
|
| @@ -1029,12 +1020,8 @@
|
| },
|
|
|
| _updateGridMetrics: function() {
|
| - this._viewportWidth = this.$.items.offsetWidth;
|
| - // Set item width to the value of the _physicalItems offsetWidth
|
| - this._itemWidth = this._physicalCount > 0 ? this._physicalItems[0].getBoundingClientRect().width : DEFAULT_GRID_SIZE;
|
| - // Set row height to the value of the _physicalItems offsetHeight
|
| - this._rowHeight = this._physicalCount > 0 ? this._physicalItems[0].offsetHeight : DEFAULT_GRID_SIZE;
|
| - // If in grid mode compute how many items with exist in each row
|
| + this._itemWidth = this._physicalCount > 0 ? this._physicalItems[0].getBoundingClientRect().width : 200;
|
| + this._rowHeight = this._physicalCount > 0 ? this._physicalItems[0].offsetHeight : 200;
|
| this._itemsPerRow = this._itemWidth ? Math.floor(this._viewportWidth / this._itemWidth) : this._itemsPerRow;
|
| },
|
|
|
| @@ -1219,10 +1206,14 @@
|
| Polymer.dom.addDebouncer(this.debounce('_debounceTemplate', function() {
|
| this.updateViewportBoundaries();
|
| this._render();
|
| -
|
| - if (this._physicalCount > 0 && this._isVisible) {
|
| - this._resetAverage();
|
| - this.scrollToIndex(this.firstVisibleIndex);
|
| + if (this._isVisible) {
|
| + this.toggleScrollListener(true);
|
| + if (this._physicalCount > 0) {
|
| + this._resetAverage();
|
| + this.scrollToIndex(this.firstVisibleIndex);
|
| + }
|
| + } else {
|
| + this.toggleScrollListener(false);
|
| }
|
| }.bind(this), 1));
|
| },
|
| @@ -1365,7 +1356,6 @@
|
| model.tabIndex = SECRET_TABINDEX;
|
| activeElTabIndex = activeEl ? activeEl.tabIndex : -1;
|
| model.tabIndex = modelTabIndex;
|
| -
|
| // Only select the item if the tap wasn't on a focusable child
|
| // or the element bound to `tabIndex`
|
| if (activeEl && physicalItem !== activeEl && physicalItem.contains(activeEl) && activeElTabIndex !== SECRET_TABINDEX) {
|
| @@ -1446,7 +1436,6 @@
|
| var physicalItem = this._physicalItems[this._getPhysicalIndex(idx)];
|
| var model = physicalItem._templateInstance;
|
| var focusable;
|
| -
|
| // set a secret tab index
|
| model.tabIndex = SECRET_TABINDEX;
|
| // check if focusable element is the physical item
|
|
|