mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 01:52:19 +08:00
refactor(router): init ng router refactor
This commit is contained in:
@ -21,7 +21,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run clean && npm run compile && npm run clean-generated",
|
"build": "npm run clean && npm run compile && npm run clean-generated",
|
||||||
"build.link": "node scripts/link-copy.js",
|
"build.link": "npm run build && node scripts/link-copy.js",
|
||||||
"clean": "node scripts/clean.js",
|
"clean": "node scripts/clean.js",
|
||||||
"clean-generated": "node ./scripts/clean-generated.js",
|
"clean-generated": "node ./scripts/clean-generated.js",
|
||||||
"compile": "./node_modules/.bin/ngc",
|
"compile": "./node_modules/.bin/ngc",
|
||||||
|
@ -1,29 +1,24 @@
|
|||||||
export { IonicAngularModule } from './module';
|
export { IonicAngularModule } from './module';
|
||||||
|
|
||||||
|
/* Navigation */
|
||||||
|
export { IonNav } from './navigation/ion-nav';
|
||||||
|
export { IonRouterOutlet } from './navigation/ion-router-outlet';
|
||||||
|
export { IonTab } from './navigation/ion-tab';
|
||||||
|
export { IonTabs } from './navigation/ion-tabs';
|
||||||
|
|
||||||
/* Directives */
|
/* Directives */
|
||||||
export { IonNav } from './directives/ion-nav';
|
|
||||||
export { VirtualScroll } from './directives/virtual-scroll';
|
export { VirtualScroll } from './directives/virtual-scroll';
|
||||||
export { VirtualItem } from './directives/virtual-item';
|
export { VirtualItem } from './directives/virtual-item';
|
||||||
export { VirtualHeader } from './directives/virtual-header';
|
export { VirtualHeader } from './directives/virtual-header';
|
||||||
export { VirtualFooter } from './directives/virtual-footer';
|
export { VirtualFooter } from './directives/virtual-footer';
|
||||||
|
|
||||||
/* Router */
|
|
||||||
export { RouterOutlet } from './router/outlet';
|
|
||||||
export { AsyncActivateRoutes } from './router/async-activated-routes';
|
|
||||||
export { OutletInjector } from './router/outlet-injector';
|
|
||||||
export { IonicRouterModule } from './router/router-module';
|
|
||||||
|
|
||||||
/* Providers */
|
/* Providers */
|
||||||
export { ActionSheetController, ActionSheetProxy } from './providers/action-sheet-controller';
|
export { ActionSheetController, ActionSheetProxy } from './providers/action-sheet-controller';
|
||||||
export { AlertController, AlertProxy } from './providers/alert-controller';
|
export { AlertController, AlertProxy } from './providers/alert-controller';
|
||||||
export { AngularComponentMounter } from './providers/angular-component-mounter';
|
|
||||||
export { App } from './providers/app';
|
|
||||||
export { Events } from './providers/events';
|
export { Events } from './providers/events';
|
||||||
export { LoadingController, LoadingProxy } from './providers/loading-controller';
|
export { LoadingController, LoadingProxy } from './providers/loading-controller';
|
||||||
export { MenuController } from './providers/menu-controller';
|
export { MenuController } from './providers/menu-controller';
|
||||||
export { ModalController, ModalProxy } from './providers/modal-controller';
|
export { ModalController, ModalProxy } from './providers/modal-controller';
|
||||||
export { NavController } from './providers/nav-controller';
|
|
||||||
export { NavParams } from './providers/nav-params';
|
|
||||||
export { Platform } from './providers/platform';
|
export { Platform } from './providers/platform';
|
||||||
export { PopoverController, PopoverProxy } from './providers/popover-controller';
|
export { PopoverController, PopoverProxy } from './providers/popover-controller';
|
||||||
export { ToastController, ToastProxy } from './providers/toast-controller';
|
export { ToastController, ToastProxy } from './providers/toast-controller';
|
||||||
|
@ -12,8 +12,13 @@ import { RadioValueAccessor } from './control-value-accessors/radio-value-access
|
|||||||
import { SelectValueAccessor } from './control-value-accessors/select-value-accessor';
|
import { SelectValueAccessor } from './control-value-accessors/select-value-accessor';
|
||||||
import { TextValueAccessor } from './control-value-accessors/text-value-accessor';
|
import { TextValueAccessor } from './control-value-accessors/text-value-accessor';
|
||||||
|
|
||||||
|
/* Navigation */
|
||||||
|
import { IonNav } from './navigation/ion-nav';
|
||||||
|
import { IonRouterOutlet } from './navigation/ion-router-outlet';
|
||||||
|
import { IonTab } from './navigation/ion-tab';
|
||||||
|
import { IonTabs } from './navigation/ion-tabs';
|
||||||
|
|
||||||
/* Directives */
|
/* Directives */
|
||||||
import { IonNav } from './directives/ion-nav';
|
|
||||||
import { VirtualScroll } from './directives/virtual-scroll';
|
import { VirtualScroll } from './directives/virtual-scroll';
|
||||||
import { VirtualItem } from './directives/virtual-item';
|
import { VirtualItem } from './directives/virtual-item';
|
||||||
import { VirtualHeader } from './directives/virtual-header';
|
import { VirtualHeader } from './directives/virtual-header';
|
||||||
@ -22,8 +27,6 @@ import { VirtualFooter } from './directives/virtual-footer';
|
|||||||
/* Providers */
|
/* Providers */
|
||||||
import { ActionSheetController } from './providers/action-sheet-controller';
|
import { ActionSheetController } from './providers/action-sheet-controller';
|
||||||
import { AlertController } from './providers/alert-controller';
|
import { AlertController } from './providers/alert-controller';
|
||||||
import { AngularComponentMounter } from './providers/angular-component-mounter';
|
|
||||||
import { App } from './providers/app';
|
|
||||||
import { Events, setupProvideEvents } from './providers/events';
|
import { Events, setupProvideEvents } from './providers/events';
|
||||||
import { LoadingController } from './providers/loading-controller';
|
import { LoadingController } from './providers/loading-controller';
|
||||||
import { MenuController } from './providers/menu-controller';
|
import { MenuController } from './providers/menu-controller';
|
||||||
@ -36,6 +39,9 @@ import { ToastController } from './providers/toast-controller';
|
|||||||
declarations: [
|
declarations: [
|
||||||
BooleanValueAccessor,
|
BooleanValueAccessor,
|
||||||
IonNav,
|
IonNav,
|
||||||
|
IonRouterOutlet,
|
||||||
|
IonTab,
|
||||||
|
IonTabs,
|
||||||
NumericValueAccessor,
|
NumericValueAccessor,
|
||||||
RadioValueAccessor,
|
RadioValueAccessor,
|
||||||
SelectValueAccessor,
|
SelectValueAccessor,
|
||||||
@ -48,6 +54,9 @@ import { ToastController } from './providers/toast-controller';
|
|||||||
exports: [
|
exports: [
|
||||||
BooleanValueAccessor,
|
BooleanValueAccessor,
|
||||||
IonNav,
|
IonNav,
|
||||||
|
IonRouterOutlet,
|
||||||
|
IonTab,
|
||||||
|
IonTabs,
|
||||||
NumericValueAccessor,
|
NumericValueAccessor,
|
||||||
RadioValueAccessor,
|
RadioValueAccessor,
|
||||||
SelectValueAccessor,
|
SelectValueAccessor,
|
||||||
@ -63,8 +72,7 @@ import { ToastController } from './providers/toast-controller';
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
ModalController,
|
ModalController,
|
||||||
PopoverController,
|
PopoverController
|
||||||
AngularComponentMounter
|
|
||||||
],
|
],
|
||||||
schemas: [
|
schemas: [
|
||||||
CUSTOM_ELEMENTS_SCHEMA
|
CUSTOM_ELEMENTS_SCHEMA
|
||||||
@ -77,7 +85,6 @@ export class IonicAngularModule {
|
|||||||
providers: [
|
providers: [
|
||||||
AlertController,
|
AlertController,
|
||||||
ActionSheetController,
|
ActionSheetController,
|
||||||
App,
|
|
||||||
Events,
|
Events,
|
||||||
LoadingController,
|
LoadingController,
|
||||||
MenuController,
|
MenuController,
|
||||||
|
32
packages/angular/src/navigation/ion-nav.ts
Normal file
32
packages/angular/src/navigation/ion-nav.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { Component, ViewEncapsulation } from '@angular/core';
|
||||||
|
import {
|
||||||
|
NavigationEnd,
|
||||||
|
NavigationStart,
|
||||||
|
Router
|
||||||
|
} from '@angular/router';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ion-nav',
|
||||||
|
template: '<ng-content></ng-content>',
|
||||||
|
styles: [`
|
||||||
|
ion-nav > :not(.show-page) { display: none; }
|
||||||
|
`],
|
||||||
|
encapsulation: ViewEncapsulation.None
|
||||||
|
})
|
||||||
|
export class IonNav {
|
||||||
|
|
||||||
|
constructor(router: Router) {
|
||||||
|
console.log('ion-nav');
|
||||||
|
|
||||||
|
router.events.subscribe(ev => {
|
||||||
|
if (ev instanceof NavigationStart) {
|
||||||
|
console.log('NavigationStart', ev.url);
|
||||||
|
|
||||||
|
} else if (ev instanceof NavigationEnd) {
|
||||||
|
console.log('NavigationEnd', ev.url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
160
packages/angular/src/navigation/ion-router-outlet.ts
Normal file
160
packages/angular/src/navigation/ion-router-outlet.ts
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, EventEmitter, Injector, OnDestroy, OnInit, Output, ViewContainerRef } from '@angular/core';
|
||||||
|
import { ActivatedRoute, ChildrenOutletContexts } from '@angular/router';
|
||||||
|
import * as ctrl from './router-controller';
|
||||||
|
import { runTransition } from './router-transition';
|
||||||
|
|
||||||
|
|
||||||
|
@Directive({selector: 'ion-router-outlet', exportAs: 'ionOutlet'})
|
||||||
|
export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||||
|
private activated: ComponentRef<any>|null = null;
|
||||||
|
private _activatedRoute: ActivatedRoute|null = null;
|
||||||
|
private name: string;
|
||||||
|
|
||||||
|
private views: ctrl.RouteView[] = [];
|
||||||
|
|
||||||
|
@Output('activate') activateEvents = new EventEmitter<any>();
|
||||||
|
@Output('deactivate') deactivateEvents = new EventEmitter<any>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private parentContexts: ChildrenOutletContexts, private location: ViewContainerRef,
|
||||||
|
private resolver: ComponentFactoryResolver, @Attribute('name') name: string,
|
||||||
|
private changeDetector: ChangeDetectorRef) {
|
||||||
|
this.name = name || 'primary';
|
||||||
|
parentContexts.onChildOutletCreated(this.name, this as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
ctrl.destoryViews(this.views);
|
||||||
|
this.parentContexts.onChildOutletDestroyed(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
if (!this.activated) {
|
||||||
|
// If the outlet was not instantiated at the time the route got activated we need to populate
|
||||||
|
// the outlet when it is initialized (ie inside a NgIf)
|
||||||
|
const context = this.parentContexts.getContext(this.name);
|
||||||
|
if (context && context.route) {
|
||||||
|
if (context.attachRef) {
|
||||||
|
// `attachRef` is populated when there is an existing component to mount
|
||||||
|
this.attach(context.attachRef, context.route);
|
||||||
|
} else {
|
||||||
|
// otherwise the component defined in the configuration is created
|
||||||
|
this.activateWith(context.route, context.resolver || null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get isActivated(): boolean { return !!this.activated; }
|
||||||
|
|
||||||
|
get component(): Object {
|
||||||
|
if (!this.activated) throw new Error('Outlet is not activated');
|
||||||
|
return this.activated.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
get activatedRoute(): ActivatedRoute {
|
||||||
|
if (!this.activated) throw new Error('Outlet is not activated');
|
||||||
|
return this._activatedRoute as ActivatedRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
get activatedRouteData() {
|
||||||
|
if (this._activatedRoute) {
|
||||||
|
return this._activatedRoute.snapshot.data;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the `RouteReuseStrategy` instructs to detach the subtree
|
||||||
|
*/
|
||||||
|
detach(): ComponentRef<any> {
|
||||||
|
if (!this.activated) throw new Error('Outlet is not activated');
|
||||||
|
this.location.detach();
|
||||||
|
const cmp = this.activated;
|
||||||
|
this.activated = null;
|
||||||
|
this._activatedRoute = null;
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
|
||||||
|
*/
|
||||||
|
attach(ref: ComponentRef<any>, activatedRoute: ActivatedRoute) {
|
||||||
|
this.activated = ref;
|
||||||
|
this._activatedRoute = activatedRoute;
|
||||||
|
|
||||||
|
ctrl.attachView(this.views, this.location, ref, activatedRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
deactivate(): void {
|
||||||
|
if (this.activated) {
|
||||||
|
const c = this.component;
|
||||||
|
|
||||||
|
ctrl.deactivateView(this.views, this.activated);
|
||||||
|
|
||||||
|
this.activated = null;
|
||||||
|
this._activatedRoute = null;
|
||||||
|
this.deactivateEvents.emit(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver|null) {
|
||||||
|
if (this.isActivated) {
|
||||||
|
throw new Error('Cannot activate an already activated outlet');
|
||||||
|
}
|
||||||
|
|
||||||
|
this._activatedRoute = activatedRoute;
|
||||||
|
|
||||||
|
const existingView = ctrl.getExistingView(this.views, activatedRoute);
|
||||||
|
if (existingView) {
|
||||||
|
// we've already got a view hanging around
|
||||||
|
this.activated = existingView.ref;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// haven't created this view yet
|
||||||
|
const snapshot = (activatedRoute as any)._futureSnapshot;
|
||||||
|
|
||||||
|
const component = <any>snapshot.routeConfig !.component;
|
||||||
|
resolver = resolver || this.resolver;
|
||||||
|
|
||||||
|
const factory = resolver.resolveComponentFactory(component);
|
||||||
|
const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
|
||||||
|
|
||||||
|
const injector = new OutletInjector(activatedRoute, childContexts, this.location.injector);
|
||||||
|
this.activated = this.location.createComponent(factory, this.location.length, injector);
|
||||||
|
|
||||||
|
// keep a ref
|
||||||
|
ctrl.initRouteViewElm(this.views, this.activated, activatedRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calling `markForCheck` to make sure we will run the change detection when the
|
||||||
|
// `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
|
||||||
|
this.changeDetector.markForCheck();
|
||||||
|
|
||||||
|
const lastDeactivatedRef = ctrl.getLastDeactivatedRef(this.views);
|
||||||
|
|
||||||
|
runTransition(this.activated, lastDeactivatedRef).then(() => {
|
||||||
|
console.log('transition end');
|
||||||
|
this.activateEvents.emit(this.activated.instance);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class OutletInjector implements Injector {
|
||||||
|
constructor(
|
||||||
|
private route: ActivatedRoute, private childContexts: ChildrenOutletContexts,
|
||||||
|
private parent: Injector) {}
|
||||||
|
|
||||||
|
get(token: any, notFoundValue?: any): any {
|
||||||
|
if (token === ActivatedRoute) {
|
||||||
|
return this.route;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token === ChildrenOutletContexts) {
|
||||||
|
return this.childContexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.parent.get(token, notFoundValue);
|
||||||
|
}
|
||||||
|
}
|
17
packages/angular/src/navigation/ion-tab.ts
Normal file
17
packages/angular/src/navigation/ion-tab.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { Directive, ElementRef, Input, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: 'ion-tab'
|
||||||
|
})
|
||||||
|
export class IonTab implements OnInit {
|
||||||
|
|
||||||
|
@Input() tabLink: string;
|
||||||
|
|
||||||
|
constructor(private elementRef: ElementRef) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
console.log('routerLink', this.tabLink, this.elementRef.nativeElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
packages/angular/src/navigation/ion-tabs.ts
Normal file
25
packages/angular/src/navigation/ion-tabs.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Directive, HostListener } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: 'ion-tabs'
|
||||||
|
})
|
||||||
|
export class IonTabs {
|
||||||
|
|
||||||
|
constructor(private router: Router) {}
|
||||||
|
|
||||||
|
@HostListener('ionTabbarClick', ['$event'])
|
||||||
|
ionTabbarClick(ev: UIEvent) {
|
||||||
|
console.log('ionTabbarClick', ev);
|
||||||
|
|
||||||
|
const tabElm: HTMLIonTabElement = ev.detail as any;
|
||||||
|
if (tabElm && tabElm.href) {
|
||||||
|
console.log('tabElm', tabElm.href);
|
||||||
|
|
||||||
|
this.router.navigateByUrl(tabElm.href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
81
packages/angular/src/navigation/router-controller.ts
Normal file
81
packages/angular/src/navigation/router-controller.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import { ComponentRef, ViewContainerRef } from '@angular/core';
|
||||||
|
import { ActivatedRoute, UrlSegment } from '@angular/router';
|
||||||
|
|
||||||
|
|
||||||
|
export function attachView(views: RouteView[], location: ViewContainerRef, ref: ComponentRef<any>, activatedRoute: ActivatedRoute) {
|
||||||
|
initRouteViewElm(views, ref, activatedRoute);
|
||||||
|
location.insert(ref.hostView);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function initRouteViewElm(views: RouteView[], ref: ComponentRef<any>, activatedRoute: ActivatedRoute) {
|
||||||
|
views.push({
|
||||||
|
ref: ref,
|
||||||
|
urlKey: getUrlKey(activatedRoute),
|
||||||
|
deactivatedId: -1
|
||||||
|
});
|
||||||
|
|
||||||
|
(ref.location.nativeElement as HTMLElement).classList.add('ion-page');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getExistingView(views: RouteView[], activatedRoute: ActivatedRoute) {
|
||||||
|
return views.find(vw => {
|
||||||
|
return isMatchingActivatedRoute(vw.urlKey, activatedRoute);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function isMatchingActivatedRoute(existingUrlKey: string, activatedRoute: ActivatedRoute) {
|
||||||
|
const activatedUrlKey = getUrlKey(activatedRoute);
|
||||||
|
|
||||||
|
return activatedUrlKey === existingUrlKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getLastDeactivatedRef(views: RouteView[]) {
|
||||||
|
if (views.length < 2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return views.sort((a, b) => {
|
||||||
|
if (a.deactivatedId > b.deactivatedId) return -1;
|
||||||
|
if (a.deactivatedId < b.deactivatedId) return 1;
|
||||||
|
return 0;
|
||||||
|
})[0].ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getUrlKey(activatedRoute: ActivatedRoute) {
|
||||||
|
const url: UrlSegment[] = (activatedRoute.url as any).value;
|
||||||
|
|
||||||
|
return url.map(u => {
|
||||||
|
return u.path + '$$' + JSON.stringify(u.parameters);
|
||||||
|
}).join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function deactivateView(views: RouteView[], ref: ComponentRef<any>) {
|
||||||
|
const view = views.find(vw => vw.ref === ref);
|
||||||
|
if (view) {
|
||||||
|
view.deactivatedId = deactivatedIds++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function destoryViews(views: RouteView[]) {
|
||||||
|
views.forEach(vw => {
|
||||||
|
vw.ref.destroy();
|
||||||
|
});
|
||||||
|
views.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface RouteView {
|
||||||
|
urlKey: string;
|
||||||
|
ref: ComponentRef<any>;
|
||||||
|
deactivatedId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let deactivatedIds = 0;
|
34
packages/angular/src/navigation/router-transition.ts
Normal file
34
packages/angular/src/navigation/router-transition.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { ComponentRef } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
export function runTransition(enteringRef: ComponentRef<any>, leavingRef: ComponentRef<any>): Promise<void> {
|
||||||
|
const enteringElm = (enteringRef && enteringRef.location && enteringRef.location.nativeElement);
|
||||||
|
const leavingElm = (leavingRef && leavingRef.location && leavingRef.location.nativeElement);
|
||||||
|
|
||||||
|
if (!enteringElm && !leavingElm) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return transition(enteringElm, leavingElm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function transition(enteringElm: HTMLElement, leavingElm: HTMLElement): Promise<void> {
|
||||||
|
console.log('transition start');
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
|
||||||
|
if (enteringElm) {
|
||||||
|
enteringElm.classList.add('show-page');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leavingElm) {
|
||||||
|
leavingElm.classList.remove('show-page');
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
}, 750);
|
||||||
|
});
|
||||||
|
}
|
Reference in New Issue
Block a user