UNPKG

@tinijs/router

Version:

The router module for the TiniJS framework.

104 lines 4.38 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { LitElement } from 'lit'; import { property } from 'lit/decorators.js'; import { NO_ROUTER_FOR_OUTLET_ERROR } from './consts.js'; import { Router } from './router.js'; export class RouterOutletComponent extends LitElement { connectedCallback() { super.connectedCallback(); if (!this.router) throw new Error(NO_ROUTER_FOR_OUTLET_ERROR); this.router.setCallback(this.handleRoute.bind(this)); this.handleRoute(this.router.match(new URL(location.href))); } async handleRoute(activeRoute) { const { layoutRoute, pageRoute } = activeRoute; // lazy load if (layoutRoute?.action) await layoutRoute.action(); if (pageRoute?.action) await pageRoute.action(); // render const layoutTagName = layoutRoute?.component; const pageTagName = pageRoute?.component; if (layoutTagName === this.currentLayout && pageTagName === this.currentPage) return; if (layoutTagName === this.currentLayout) return this.renderPage(activeRoute, pageTagName); return this.renderFull(activeRoute, pageTagName, layoutTagName); } async renderPage(activeRoute, pageTagName) { this.currentPage = pageTagName; const rootEl = !this.currentLayout ? this.renderRoot : this.renderRoot.querySelector(this.currentLayout) || this.renderRoot; if (!pageTagName || !rootEl) return; return this.renderer(activeRoute, rootEl, pageTagName); } async renderFull(activeRoute, pageTagName, layoutTagName) { this.currentLayout = layoutTagName; this.currentPage = pageTagName; let rootEl = this.renderRoot; if (!pageTagName || !rootEl) return; // layout if (layoutTagName) { const layoutEl = await this.renderer(activeRoute, rootEl, layoutTagName); if (layoutEl) rootEl = layoutEl; } // page return this.renderer(activeRoute, rootEl, pageTagName); } async renderer(activeRoute, rootEl, newTagName) { const currentEl = rootEl.firstElementChild; const newEl = document.createElement(newTagName); // hooks const currentBeforeLeave = currentEl?.onBeforeLeave; const currentAfterLeave = currentEl?.onAfterLeave; const newBeforeEnter = newEl?.onBeforeEnter; const newAfterEnter = newEl?.onAfterEnter; // stage 1 if (await this.runBeforeHook(currentBeforeLeave, activeRoute, newEl, currentEl)) return; if (await this.runBeforeHook(newBeforeEnter, activeRoute, newEl, currentEl)) return; // main action rootEl.replaceChildren(newEl); // stage 2 await this.runAfterHook(newAfterEnter, activeRoute, newEl, currentEl); await this.runAfterHook(currentAfterLeave, activeRoute, newEl, currentEl); // continue return newEl; } async runBeforeHook(hook, activeRoute, newEl, currentEl) { const hookCommand = !hook ? undefined : await hook.call(newEl, this.router, activeRoute, newEl, currentEl); if (!hookCommand) return false; if (typeof hookCommand === 'string') { this.router.redirect(hookCommand); } else { hookCommand(); } return true; } async runAfterHook(hook, activeRoute, newEl, currentEl) { if (hook) await hook.call(newEl, this.router, activeRoute, newEl, currentEl); return false; } } __decorate([ property({ type: Object }) ], RouterOutletComponent.prototype, "router", void 0); //# sourceMappingURL=router-outlet.js.map