Skip to content

Commit

Permalink
feat(templating): stateful routes
Browse files Browse the repository at this point in the history
Adds stateful routes so that route configurations can specify a module or a module in a viewport as stateful: true. A stateful module that's loaded in a viewport is never unloaded when navigating away, it's just not shown, and is displayed with the same state whenever a route places it in the same viewport again.

Required by aurelia/router/stateful-viewports.
Closes aurelia/router#534.
  • Loading branch information
jwx committed Sep 19, 2018
1 parent fe4db77 commit 4677ad9
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 6 deletions.
38 changes: 38 additions & 0 deletions src/swap-strategies.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,41 @@ export const SwapStrategies = {
return Promise.resolve(viewSlot.removeAll(true)).then(callback);
}
};

export const SwapStrategiesStateful = {
// animate the next viewports in before hiding the current viewports;
before(viewPort, previous, callback) {
return viewPort.hide(false).then(() => callback()).then(() => Promise.all(previous.map((prevViewPort) => {
if (!prevViewPort.stateful) {
return prevViewPort.viewSlot.removeAll(true);
}
else {
return prevViewPort.hide(true);
}
})));
},

// animate the next viewport at the same time the current viewports are removed
with(viewPort, previous, callback) {
return Promise.all(previous.map((prevViewPort) => {
if (!prevViewPort.stateful) {
return prevViewPort.viewSlot.removeAll(true);
}
else {
return prevViewPort.hide(true);
}
}), viewPort.hide(false).then(() => callback()));
},

// animate the next viewport in after the current viewports have been removed
after(viewPort, previous, callback) {
return Promise.all(previous.map((prevViewPort) => {
if (!prevViewPort.stateful) {
return prevViewPort.viewSlot.removeAll(true);
}
else {
return prevViewPort.hide(true);
}
})).then(() => viewPort.hide(false).then(() => callback()));
}
};
46 changes: 40 additions & 6 deletions src/view-slot.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ export class ViewSlot {

if (animatableElement !== null) {
switch (direction) {
case 'enter':
return this.animator.enter(animatableElement);
case 'leave':
return this.animator.leave(animatableElement);
default:
throw new Error('Invalid animation direction: ' + direction);
case 'enter':
return this.animator.enter(animatableElement);
case 'leave':
return this.animator.leave(animatableElement);
default:
throw new Error('Invalid animation direction: ' + direction);
}
}
}
Expand Down Expand Up @@ -357,6 +357,40 @@ export class ViewSlot {
return removeAction();
}

/**
* Hides or shows all views in the slot.
* @param hide If the views should be hidden.
* @param skipAnimation Should the removal animation be skipped?
* @return May return a promise if the view removals triggered an animation.
*/
hide(hide_: boolean, skipAnimation?: boolean): void | Promise<any> {
let children = this.children;
let rmPromises = [];

children.forEach(child => {
if (skipAnimation) {
child.hide(hide_);
}

let animation = this.animateView(child, (hide_ ? 'leave' : 'enter'));
if (animation) {
if (hide_) {
rmPromises.push(animation.then(() => child.hide(hide_)));
}
else {
child.hide(hide_);
rmPromises.push(animation);
}
} else {
child.hide(hide_);
}
});

// if (rmPromises.length > 0) {
return Promise.all(rmPromises);
// }
}

/**
* Triggers the attach for the slot and its children.
*/
Expand Down
14 changes: 14 additions & 0 deletions src/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,18 @@ export class View {
}
}
}

/**
* Hides or shows view
* @param hide If the view should be hidden
*/
hide(hide_: boolean): void {
let current = this.firstChild;
while (current) {
if (current.style) {
current.style.display = hide_ ? 'none' : '';
}
current = current.nextSibling;
}
}
}

0 comments on commit 4677ad9

Please sign in to comment.