forked from hotwired/turbo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
page_view.ts
58 lines (48 loc) · 1.69 KB
/
page_view.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { nextEventLoopTick } from "../../util"
import { View, ViewDelegate } from "../view"
import { ErrorRenderer } from "./error_renderer"
import { PageRenderer } from "./page_renderer"
import { PageSnapshot } from "./page_snapshot"
import { SnapshotCache } from "./snapshot_cache"
export interface PageViewDelegate extends ViewDelegate<PageSnapshot> {
viewWillCacheSnapshot(): void
}
type PageViewRenderer = PageRenderer | ErrorRenderer
export class PageView extends View<Element, PageSnapshot, PageViewRenderer, PageViewDelegate> {
readonly snapshotCache = new SnapshotCache(10)
lastRenderedLocation = new URL(location.href)
forceReloaded = false
renderPage(snapshot: PageSnapshot, isPreview = false, willRender = true) {
const renderer = new PageRenderer(this.snapshot, snapshot, isPreview, willRender)
if (!renderer.shouldRender) {
this.forceReloaded = true
}
return this.render(renderer)
}
renderError(snapshot: PageSnapshot) {
const renderer = new ErrorRenderer(this.snapshot, snapshot, false)
return this.render(renderer)
}
clearSnapshotCache() {
this.snapshotCache.clear()
}
async cacheSnapshot() {
if (this.shouldCacheSnapshot) {
this.delegate.viewWillCacheSnapshot()
const { snapshot, lastRenderedLocation: location } = this
await nextEventLoopTick()
const cachedSnapshot = snapshot.clone()
this.snapshotCache.put(location, cachedSnapshot)
return cachedSnapshot
}
}
getCachedSnapshotForLocation(location: URL) {
return this.snapshotCache.get(location)
}
get snapshot() {
return PageSnapshot.fromElement(this.element)
}
get shouldCacheSnapshot() {
return this.snapshot.isCacheable
}
}