Skip to content

Commit

Permalink
fix(if): queue up changes when animating
Browse files Browse the repository at this point in the history
  • Loading branch information
martingust committed Mar 21, 2016
1 parent e6a2d45 commit ae57e50
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 3 deletions.
31 changes: 28 additions & 3 deletions src/if.js
Expand Up @@ -40,9 +40,34 @@ export class If {
* @param newValue The new value
*/
valueChanged(newValue) {
if (this.__queuedChanges) {
this.__queuedChanges.push(newValue);
return;
}

let maybePromise = this._runValueChanged(newValue);
if (maybePromise instanceof Promise) {
let queuedChanges = this.__queuedChanges = [];

let runQueuedChanges = () => {
if (!queuedChanges.length) {
this.__queuedChanges = undefined;
return;
}

let nextPromise = this._runValueChanged(queuedChanges.shift()) || Promise.resolve();
nextPromise.then(runQueuedChanges);
};

maybePromise.then(runQueuedChanges);
}
}

_runValueChanged(newValue) {
if (!newValue) {
let viewOrPromise;
if (this.view !== null && this.showing) {
let viewOrPromise = this.viewSlot.remove(this.view);
viewOrPromise = this.viewSlot.remove(this.view);
if (viewOrPromise instanceof Promise) {
viewOrPromise.then(() => this.view.unbind());
} else {
Expand All @@ -51,7 +76,7 @@ export class If {
}

this.showing = false;
return;
return viewOrPromise;
}

if (this.view === null) {
Expand All @@ -64,7 +89,7 @@ export class If {

if (!this.showing) {
this.showing = true;
this.viewSlot.add(this.view);
return this.viewSlot.add(this.view);
}
}

Expand Down
44 changes: 44 additions & 0 deletions test/if.spec.js
Expand Up @@ -104,6 +104,50 @@ describe('if', () => {

expect(view.bind).toHaveBeenCalled();
});

describe('during animation', () => {
let delay = ms => new Promise(resolve => setTimeout(resolve, ms));

let removeWithAnimation = animationDuration => {
return function(view) {
return delay(animationDuration).then(() => {
this.children = [];
});
};
};

let addWithAnimation = animationDuration => {
return function(view) {
return delay(animationDuration).then(() => {
this.children.push(view);
});
};
};

beforeEach(() => {
spyOn(viewSlot, 'remove').and.callFake(removeWithAnimation(600));
spyOn(viewSlot, 'add').and.callFake(addWithAnimation(0));
});

it('should correctly handle value changes during remove animation', done => {
sut.showing = false;
sut.view = new ViewMock();
sut.view.isBound = true;
sut.viewSlot.children = [];
sut.valueChanged(true);

delay(200).then(() => {
sut.valueChanged(false);
return delay(400);
}).then(() => {
sut.valueChanged(true);
return delay(600);
}).then(() => {
expect(viewSlot.children.length).toEqual(1);
})
.then(() => done())
})
});
});

class ViewSlotMock {
Expand Down

0 comments on commit ae57e50

Please sign in to comment.