UNPKG

widget-router

Version:

Widget Router is another Typescript (also JavaScript) Router, but this one works better if used in widgets inside HTML

202 lines (172 loc) 8.2 kB
import { IWidgetRouter } from "./IWidgetRouter"; import { RouteResult } from "./RouteResult"; import { RouteConfig } from "./RouteConfig"; import { Utilities } from "./Utilities"; import { ITemplateProvider } from "./ITemplateProvider"; import { TemplateProvider } from "./TemplateProvider"; import { EventHandlerManager } from 'event-handler-manager'; export class WidgetRouter extends EventHandlerManager implements IWidgetRouter { private readonly containerId: string; private readonly routeConfig: RouteConfig; private readonly appScope: object; private readonly controllerHelper : any; private readonly pageIdPrefix: string; private controllersInitiated: any; private templateProvider: ITemplateProvider; public activePage: string; //public templatesCollection: Object; constructor(containerId: string, routeConfig: RouteConfig, appScope?: Object, controllerHelper?: any) { super(); const currentContainer = <HTMLElement>document.querySelector(containerId); if (currentContainer === undefined || currentContainer === null) { throw new Error(containerId + ' was not found inside document, please set a valid container Id selector.'); } this.containerId = containerId; this.routeConfig = routeConfig; this.appScope = appScope ? appScope : {}; routeConfig.routes.forEach(route => { this.appScope[route.name] = {}; }); this.controllerHelper = controllerHelper; this.pageIdPrefix = routeConfig.pageIdPrefix !== undefined && routeConfig.pageIdPrefix !== null ? routeConfig.pageIdPrefix : ''; this.controllersInitiated = {}; this.routeConfig.routes.forEach(route => { let currentPage = <HTMLElement>document.querySelector(this.containerId).querySelector('#' + this.pageIdPrefix + route.name); if (currentPage === undefined || currentPage === null) { document.querySelector(this.containerId).innerHTML += '<div id="' + this.pageIdPrefix + route.name + '" style="display:none;"></div>'; } else { currentPage.style.display = 'none'; } }); this.templateProvider = new TemplateProvider(); if (this.routeConfig.usingTemplates) { if (controllerHelper === undefined && controllerHelper === null) { controllerHelper = {}; } controllerHelper.templatesCollection = {}; } this.attach(['beforego', 'aftergo']); } private executeController(routeName, params, templateContent, initController, currentRouteConfig) : Promise<RouteResult> { const dfd = new Promise<RouteResult>((resolve, reject) => { let routeResult = { routeName: routeName, routeParams: params, routeScope: this.appScope[routeName], router: this, controllerHelper: this.controllerHelper } as RouteResult; if (this.routeConfig.usingTemplates) { if (this.controllerHelper.templatesCollection === undefined || this.controllerHelper.templatesCollection === null) { this.controllerHelper.templatesCollection = {}; } this.controllerHelper.templatesCollection[routeName] = templateContent; } if (initController && Utilities.isFunction(currentRouteConfig.controller)) { (() => { try { let controllerResult = currentRouteConfig.controller(routeResult); if (controllerResult !== undefined && controllerResult !== null && !!controllerResult.then && typeof controllerResult.then === 'function') { controllerResult.then(() => { resolve(routeResult); }).catch(err => { console.error(err); }); } else { this.controllersInitiated[routeName] = true; resolve(routeResult); } } catch (e) { console.error(e); reject(e); } })(); } else { resolve(routeResult); } }); return dfd; } go(routeName: string, params?: any, noCache?: boolean, initController?: boolean): Promise<RouteResult> { const dfd = new Promise<RouteResult>((resolve, reject) => { this.trigger('beforego').then(() => { const currentRouteConfig = this.routeConfig.routes.find(route => { return route.name === routeName; }); if (currentRouteConfig === undefined || currentRouteConfig == null) { throw new Error('Route Configuration not found for that Route Name'); } this.routeConfig.afterRouteInitController = this.routeConfig.afterRouteInitController !== undefined && this.routeConfig.afterRouteInitController !== null ? this.routeConfig.afterRouteInitController : true; initController = initController !== undefined && initController !== null ? initController : this.routeConfig.afterRouteInitController; initController = currentRouteConfig.controller !== undefined && currentRouteConfig.controller !== null ? initController : false; if (this.activePage !== undefined && this.activePage !== null && this.activePage.trim() !== '') { let activePage = <HTMLElement>document.querySelector(this.containerId).querySelector('#' + this.pageIdPrefix + this.activePage); activePage.style.display = 'none'; } let newActivePage = <HTMLElement>document.querySelector(this.containerId).querySelector('#' + this.pageIdPrefix + routeName); if (newActivePage === undefined || newActivePage === null) { document.querySelector(this.containerId).innerHTML += '<div id="' + this.pageIdPrefix + routeName + '">'; newActivePage = <HTMLElement>document.querySelector(this.containerId).querySelector('#' + this.pageIdPrefix + routeName); } else { newActivePage.style.display = 'block'; } this.activePage = routeName; if (currentRouteConfig.templateFile !== undefined && currentRouteConfig.templateFile !== null && currentRouteConfig.templateFile.trim() !== '') { this.getTemplateFromFile(currentRouteConfig.templateFile).then(templateContent => { if (!this.routeConfig.usingTemplates) { newActivePage.innerHTML = templateContent; } this.executeController(routeName, params, templateContent, initController, currentRouteConfig).then(routeResult => { this.trigger('aftergo').then(() => { resolve(routeResult); }).catch(err => reject(err)).catch(err => reject(err)); }).catch(err => { console.error(err); reject(err); }); }).catch(err => { console.error(err); reject(err); }); } else { if (newActivePage !== undefined && newActivePage !== null && currentRouteConfig.template !== undefined && currentRouteConfig.template !== null && currentRouteConfig.template.trim() !== '' && !this.routeConfig.usingTemplates) { newActivePage.innerHTML = currentRouteConfig.template; } this.executeController(routeName, params, currentRouteConfig.template, initController, currentRouteConfig).then(routeResult => { this.trigger('aftergo').then(() => { resolve(routeResult); }).catch(err => reject(err)).catch(err => reject(err)); }).catch(err => { console.error(err); reject(err); }); } }).catch(err => { console.error(err); }); }); return dfd; } private getTemplateFromFile(templateFile) { const dfd = new Promise<string>((resolve, reject) => { this.templateProvider.get(templateFile).then((templateContent) => { resolve(templateContent); }).catch(error => { console.log(error); reject(error); }); }); return dfd; } }