UNPKG

iportal

Version:

web-portal

155 lines (138 loc) 4.42 kB
import { ApplicationProptey } from './proptey' import { Module, ModuleManifest } from '../types' import { BASE_CSS } from './init-css' interface AppRoute { id: string param: string search: string } class ApplicationBase extends ApplicationProptey { constructor () { super() this.setBaseCSS() } get route (): AppRoute { const router = this.routerRegExp.exec(location.hash) || [] const id = router[1] const param = router[2] const search = location.search return { id: id ? decodeURIComponent(id) : '', param: param ? decodeURIComponent(param) : '', search } } get exists (): boolean { try { return parseInt(sessionStorage.getItem(location.pathname + '__EXISTS') || '-1', 10) === history.length } catch (e) { return false } } public properties = { darkTheme: window.matchMedia?.('(prefers-color-scheme: dark)')?.matches } public setBaseCSS () { const style = document.createElement('style') style.innerHTML = BASE_CSS document.getElementsByTagName('head')[0].appendChild(style) } public resolveURL (url: string) { const link = new URL( url, window.location.toString() ) const linkObject = link if (link.href === undefined) { linkObject.href = String(link) } return linkObject } public promiseModule (promise: () => Promise<ModuleManifest>): Promise<ModuleManifest> { return new Promise(async (resolve, reject) => { try { resolve(await promise()) } catch (error) { reject(error) } }) } public moduleSrcVerify (url: string): boolean { const capture = this.config.capture if (capture) return this.moduleSrcCapture(url, capture) const allowHosts = this.config.allowHosts if (!Array.isArray(allowHosts)) { this.console.warn('[Module.config.allowHosts] is not defined!', 'Security risks exist: ', '') return true } const link = new URL( decodeURIComponent(url), window.location.toString() ) const linkHost = link.host for (const host of allowHosts) { if (linkHost === host) return true } return false } public moduleSrcCapture (url: string, capture = this.config.capture): boolean { const resolve = this.resolveURL(url) const path = resolve.origin + resolve.pathname if (typeof capture === 'string') { if (capture === path) return true } else if (typeof capture === 'function') { if (capture(resolve, url)) return true } return false } public getModuleByURL (url: string): Module | undefined { const modules = this.modules const resolve = this.resolveURL(url) const path = resolve.origin + resolve.pathname for (const id in modules) { const module = modules[id] const capture = module.config.capture if (this.moduleSrcCapture(url, capture)) return module if (module.uri === path) return module } return } public setExists () { return new Promise<void>((resolve, reject) => { try { sessionStorage.setItem(location.pathname + '__EXISTS', String(history.length)) resolve() } catch (e) { reject() } }) } public readonly console = { echo: (type: 'log' | 'info' | 'warn' | 'error', pre: string[], mid: string[], suf: string[]) => { console[type]( '%c ' + (pre[0] ? pre[0] + ' ' : '') + '%c ' + (mid[0] ? mid[0] + ' ' : '') + '%c ' + (suf[0] ? suf[0] + ' ' : ''), 'color: #ffffff; background:' + pre[1], 'color: #ffffff; background:' + mid[1], 'color: #ffffff; background:' + (suf[0] ? suf[1] : mid[1]) ) }, log: (message: string, title: string, description: string) => { this.console.echo('log', [title, '#999'], [message, '#333'], [description, '#666']) }, info: (message: string, title: string, description: string) => { this.console.echo('info', [title, '#0cf'], [message, '#06c'], [description, '#0c0']) }, warn: (message: string, title: string, description: string) => { this.console.echo('warn', [title, '#f60'], [message, '#f30'], [description, '#f90']) }, error: (message: string, title: string, description: string) => { this.console.echo('warn', [title, '#f06'], [message, '#903'], [description, '#993']) } } } export { ApplicationBase }