Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
fix(virtualRepeat): Recover from scroll events that occur when hidden F…
Browse files Browse the repository at this point in the history
…ixes #5448.

fix(virtualRepeat): Recover from scroll events that occur when hidden

Fixes #5448. Closes #6389.
  • Loading branch information
kseamon authored and ThomasBurleson committed Dec 21, 2015
1 parent c0f5aea commit bbca34f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
33 changes: 29 additions & 4 deletions src/components/virtualRepeat/virtual-repeater.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ function VirtualRepeatContainerController(
this.originalSize = null;
/** @type {number} Amount to offset the total scroll size by. */
this.offsetSize = parseInt(this.$attrs.mdOffsetSize, 10) || 0;
/** @type {?string} height or width element style on the container prior to auto-shrinking. */
this.oldElementSize = null;

if (this.$attrs.mdTopIndex) {
/** @type {function(angular.Scope): number} Binds to topIndex on Angular scope */
Expand Down Expand Up @@ -184,8 +186,16 @@ VirtualRepeatContainerController.prototype.getSize = function() {
* @param {number} The new size to set.
*/
VirtualRepeatContainerController.prototype.setSize_ = function(size) {
var dimension = this.getDimensionName_();

this.size = size;
this.$element[0].style[this.isHorizontal() ? 'width' : 'height'] = size + 'px';
this.$element[0].style[dimension] = size + 'px';
};


VirtualRepeatContainerController.prototype.unsetSize_ = function() {
this.$element[0].style[this.getDimensionName_()] = this.oldElementSize;
this.oldElementSize = null;
};


Expand All @@ -197,6 +207,11 @@ VirtualRepeatContainerController.prototype.updateSize = function() {
? this.$element[0].clientWidth
: this.$element[0].clientHeight;

// Recheck the scroll position after updating the size. This resolves
// problems that can result if the scroll position was measured while the
// element was display: none or detached from the document.
this.handleScroll_();

this.repeater && this.repeater.containerUpdated();
};

Expand All @@ -207,13 +222,18 @@ VirtualRepeatContainerController.prototype.getScrollSize = function() {
};


VirtualRepeatContainerController.prototype.getDimensionName_ = function() {
return this.isHorizontal() ? 'width' : 'height';
};


/**
* Sets the scroller element to the specified size.
* @private
* @param {number} size The new size.
*/
VirtualRepeatContainerController.prototype.sizeScroller_ = function(size) {
var dimension = this.isHorizontal() ? 'width' : 'height';
var dimension = this.getDimensionName_();
var crossDimension = this.isHorizontal() ? 'height' : 'width';

// Clear any existing dimensions.
Expand Down Expand Up @@ -255,16 +275,21 @@ VirtualRepeatContainerController.prototype.sizeScroller_ = function(size) {
VirtualRepeatContainerController.prototype.autoShrink_ = function(size) {
var shrinkSize = Math.max(size, this.autoShrinkMin * this.repeater.getItemSize());
if (this.autoShrink && shrinkSize !== this.size) {
if (this.oldElementSize === null) {
this.oldElementSize = this.$element[0].style[this.getDimensionName_()];
}

var currentSize = this.originalSize || this.size;
if (!currentSize || shrinkSize < currentSize) {
if (!this.originalSize) {
this.originalSize = this.size;
}

this.setSize_(shrinkSize);
} else if (this.originalSize) {
this.setSize_(this.originalSize);
} else if (this.originalSize !== null) {
this.unsetSize_();
this.originalSize = null;
this.updateSize();
}

this.repeater.containerUpdated();
Expand Down
14 changes: 11 additions & 3 deletions src/components/virtualRepeat/virtual-repeater.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -580,17 +580,25 @@ describe('<md-virtual-repeat>', function() {
expect(offsetter.children().length).toBe(43);
});

it('should recheck container size on $md-resize scope event', function() {
it('should recheck container size and scroll position on $md-resize scope ' +
'event', function() {
scope.items = createItems(100);
createRepeater();
// Expect 13 children (10 + 3 extra).
expect(offsetter.children().length).toBe(13);

container.css('height', '300px');
scope.$parent.$broadcast('$md-resize');

// Expect 33 children (30 + 3 extra).
expect(offsetter.children().length).toBe(33);

container.css('height', '400px');
scroller[0].scrollTop = 20;
scope.$parent.$broadcast('$md-resize');

// Expect 43 children (40 + 3 extra).
expect(offsetter.children().length).toBe(43);
// Expect 43 children (40 + 5 extra).
expect(offsetter.children().length).toBe(45);
});

it('should shrink when initial results require shrinking', inject(function() {
Expand Down

0 comments on commit bbca34f

Please sign in to comment.