web-portals
Version:
web-portals
143 lines (128 loc) • 4.01 kB
text/typescript
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
}
}
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 = document.createElement('a')
link.href = url
const path = link.origin + link.pathname
return {
path,
origin: link.origin,
host: link.host,
search: link.search
}
}
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 allowHosts = this.config.allowHosts
if (!Array.isArray(allowHosts)) {
this.console.warn('Module.config.allowHosts is not defined', 'Security risks exist: ', '')
return true
}
const link = document.createElement('a')
link.href = decodeURIComponent(url)
const linkHost = link.host
for (const host of allowHosts) {
if (linkHost === host) return true
}
return false
}
public getModuleByURL (url: string): Module | undefined {
const modules = this.modules
const resolve = this.resolveURL(url)
const path = resolve.path
for (const id in modules) {
const module = modules[id]
const capture = module.config.capture
if (typeof capture === 'string') {
if (capture === path) return module
} else if (typeof capture === 'function') {
if (capture(resolve, url)) return module
}
if (module.uri === path) return module
}
return
}
public setExists () {
return new Promise<void>((resolve, reject) => {
try {
sessionStorage.setItem('__EXISTS', String(history.length))
resolve()
} catch (e) {
reject()
}
})
}
get exists (): boolean {
try {
return parseInt(sessionStorage.getItem('__EXISTS') || '-1', 10) === history.length
} catch (e) {
return false
}
}
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
}