114 lines
2.8 KiB
JavaScript
114 lines
2.8 KiB
JavaScript
import Component from '@glimmer/component';
|
|
import { tracked } from '@glimmer/tracking';
|
|
import { action } from '@ember/object';
|
|
import { inject as service } from '@ember/service';
|
|
|
|
class State {
|
|
constructor(name) {
|
|
this.name = name;
|
|
}
|
|
matches(match) {
|
|
return this.name === match;
|
|
}
|
|
}
|
|
|
|
export default class Outlet extends Component {
|
|
@service('routlet') routlet;
|
|
@service('router') router;
|
|
|
|
@tracked element;
|
|
@tracked routeName;
|
|
@tracked state;
|
|
@tracked previousState;
|
|
@tracked endTransition;
|
|
|
|
get model() {
|
|
return this.args.model || {};
|
|
}
|
|
|
|
setAppRoute(name) {
|
|
const nspace = 'nspace.';
|
|
if (name.startsWith(nspace)) {
|
|
name = name.substr(nspace.length);
|
|
}
|
|
if (name !== 'loading') {
|
|
const doc = this.element.ownerDocument.documentElement;
|
|
if (doc.classList.contains('ember-loading')) {
|
|
doc.classList.remove('ember-loading');
|
|
}
|
|
doc.dataset.route = name;
|
|
this.setAppState('idle');
|
|
}
|
|
}
|
|
|
|
setAppState(state) {
|
|
const doc = this.element.ownerDocument.documentElement;
|
|
doc.dataset.state = state;
|
|
}
|
|
|
|
@action
|
|
attributeChanged(prop, value) {
|
|
switch (prop) {
|
|
case 'element':
|
|
this.element = value;
|
|
if (this.args.name === 'application') {
|
|
this.setAppState('loading');
|
|
this.setAppRoute(this.router.currentRouteName);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
@action transitionEnd($el) {
|
|
if (typeof this.endTransition === 'function') {
|
|
this.endTransition();
|
|
}
|
|
}
|
|
|
|
@action
|
|
startLoad(transition) {
|
|
const outlet = this.routlet.findOutlet(transition.to.name) || 'application';
|
|
if (this.args.name === outlet) {
|
|
this.previousState = this.state;
|
|
this.state = new State('loading');
|
|
this.endTransition = this.routlet.transition();
|
|
// if we have no transition-duration set immediately end the transition
|
|
const duration = window
|
|
.getComputedStyle(this.element)
|
|
.getPropertyValue('transition-duration');
|
|
if (parseFloat(duration) === 0) {
|
|
this.endTransition();
|
|
}
|
|
}
|
|
if (this.args.name === 'application') {
|
|
this.setAppState('loading');
|
|
}
|
|
}
|
|
|
|
@action
|
|
endLoad(transition) {
|
|
if (this.state.matches('loading')) {
|
|
this.previousState = this.state;
|
|
this.state = new State('idle');
|
|
}
|
|
if (this.args.name === 'application') {
|
|
this.setAppRoute(this.router.currentRouteName);
|
|
}
|
|
}
|
|
|
|
@action
|
|
connect() {
|
|
this.routlet.addOutlet(this.args.name, this);
|
|
this.previousState = this.state = new State('idle');
|
|
this.router.on('routeWillChange', this.startLoad);
|
|
this.router.on('routeDidChange', this.endLoad);
|
|
}
|
|
|
|
@action
|
|
disconnect() {
|
|
this.routlet.removeOutlet(this.args.name);
|
|
this.router.off('routeWillChange', this.startLoad);
|
|
this.router.off('routeDidChange', this.endLoad);
|
|
}
|
|
}
|