Skip to content
This repository was archived by the owner on Feb 22, 2021. It is now read-only.

Commit ae1f887

Browse files
committed
feat(loader): loader script
1 parent afa7d12 commit ae1f887

File tree

5 files changed

+133
-4
lines changed

5 files changed

+133
-4
lines changed

examples/main.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1-
1+
import { BackLoader } from '../src/index'
22
document.title = 'hello'
3+
4+
const handler = async() => {
5+
const backLoader = new BackLoader({
6+
scripts: ['https://code.jquery.com/jquery-3.2.1.slim.min.js'],
7+
})
8+
backLoader.start().on(event => {
9+
console.log(event)
10+
})
11+
}
12+
13+
;(() => window.onload = () => handler().then())()

src/core/event.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
export type EventHubListener = {
2+
(evt: Event, detail?: any): void,
3+
}
4+
export type EventRecord = {
5+
type: string,
6+
handle: EventHubListener,
7+
done: EventListener,
8+
}
9+
10+
export class EventHub {
11+
12+
private source: Text
13+
private eventRecords: EventRecord[] = []
14+
15+
constructor() {
16+
this.source = document.createTextNode('')
17+
}
18+
19+
dispath(eventType: string, detail?: any): void {
20+
const event: CustomEvent = new CustomEvent(eventType,
21+
Object.assign({
22+
bubbles: true,
23+
cancelable: true,
24+
}, { detail }))
25+
this.source.dispatchEvent(event)
26+
}
27+
28+
listen(eventType: string, done: EventHubListener): void {
29+
const handle = (e: any) => done(e, e.detail)
30+
const record: EventRecord = this.eventRecords.find(record => {
31+
return record.type === eventType && record.done === done
32+
})
33+
if (!!record) return
34+
this.source.addEventListener(eventType, handle)
35+
this.eventRecords.push({ type: eventType, handle, done })
36+
}
37+
38+
remove(eventType: string, done?: EventHubListener): void {
39+
// just remove one
40+
if (done) return this.removeOne(eventType, done)
41+
// remove this type
42+
this.eventRecords
43+
.filter(re => re.type === eventType)
44+
.forEach(re => this.source.removeEventListener(re.type, re.handle))
45+
}
46+
47+
removeAll(): void {
48+
this.eventRecords
49+
.forEach(re => this.source.removeEventListener(re.type, re.handle))
50+
}
51+
52+
private removeOne(eventType: string, done?: EventHubListener): void {
53+
const record: EventRecord = this.eventRecords.find(record => {
54+
return record.type === eventType && record.done === done
55+
})
56+
if (!record) return
57+
this.source.removeEventListener(eventType, record.handle)
58+
}
59+
60+
}

src/core/loader.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { EventHub } from './event'
2+
import { LoaderEvent } from '../types'
3+
4+
5+
export class Loader {
6+
7+
readonly baseEvent: LoaderEvent = { source: '', type: 'none', success: true, insertScripts: () => {} }
8+
hub: EventHub
9+
constructor(hub: EventHub) {
10+
this.hub = hub
11+
}
12+
13+
scripts(urls: string[]): void {
14+
const scriptEvent = Object.assign({}, this.baseEvent, { type: 'script' })
15+
urls.forEach(url => {
16+
fetch(url)
17+
.then(() => {
18+
this.hub.dispath('back_load_completed', Object.assign({},
19+
scriptEvent, { source: url, insertScripts: this.makeInsertScripts(url) }))
20+
})
21+
.catch(() => {
22+
this.hub.dispath('back_load_completed', Object.assign({},
23+
scriptEvent, { source: url, success: false }))
24+
})
25+
})
26+
}
27+
28+
private makeInsertScripts(url: string): Function {
29+
return () => {
30+
const s: HTMLElement = document.createElement('script')
31+
s.setAttribute('src', url)
32+
document.body.appendChild(s)
33+
}
34+
}
35+
}

src/index.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
import * as Check from './utils/check'
2-
import { LoaderOptions } from './types'
2+
import { EventHub } from './core/event'
3+
import { Loader } from './core/loader'
4+
import { LoaderEvent, LoaderOptions } from './types'
35

46
export class BackLoader {
57

8+
options: LoaderOptions
9+
hub: EventHub
610
constructor(ops: LoaderOptions) {
711
Check.options(ops)
12+
this.options = ops
813
}
914

15+
start(): BackLoader {
16+
this.hub = new EventHub()
17+
const loader = new Loader(this.hub)
18+
const { scripts, pages } = this.options
19+
20+
scripts && loader.scripts(scripts)
21+
return this
22+
}
23+
24+
on(done: ($event: LoaderEvent) => void ): void {
25+
this.hub.listen('back_load_completed', (e, $event) => done($event))
26+
}
1027

1128
}

src/types.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11

22
export type LoaderOptions = {
3-
pages: string[]
4-
scripts: string[]
3+
pages?: string[]
4+
scripts?: string[]
55
}
66

7+
export type LoaderEvent = {
8+
source: string,
9+
type: string,
10+
success: boolean,
11+
insertScripts?: Function,
12+
}

0 commit comments

Comments
 (0)