-
Notifications
You must be signed in to change notification settings - Fork 435
/
page_view.ts
64 lines (52 loc) · 2.14 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
59
60
61
62
63
64
import { nextEventLoopTick } from "../../util"
import { View, ViewDelegate, ViewRenderOptions } from "../view"
import { ErrorRenderer } from "./error_renderer"
import { PageRenderer } from "./page_renderer"
import { PageSnapshot } from "./page_snapshot"
import { SnapshotCache } from "./snapshot_cache"
import { withViewTransition } from "./view_transitions"
import { Visit } from "./visit"
export type PageViewRenderOptions = ViewRenderOptions<HTMLBodyElement>
export interface PageViewDelegate extends ViewDelegate<HTMLBodyElement, PageSnapshot> {
viewWillCacheSnapshot(): void
}
type PageViewRenderer = PageRenderer | ErrorRenderer
export class PageView extends View<HTMLBodyElement, PageSnapshot, PageViewRenderer, PageViewDelegate> {
readonly snapshotCache = new SnapshotCache(10)
lastRenderedLocation = new URL(location.href)
forceReloaded = false
renderPage(snapshot: PageSnapshot, isPreview = false, willRender = true, visit?: Visit) {
const shouldTransition = this.snapshot.prefersViewTransitions && snapshot.prefersViewTransitions
const renderer = new PageRenderer(this.snapshot, snapshot, PageRenderer.renderElement, isPreview, willRender)
if (!renderer.shouldRender) {
this.forceReloaded = true
} else {
visit?.changeHistory()
}
return withViewTransition(shouldTransition, () => this.render(renderer))
}
renderError(snapshot: PageSnapshot, visit?: Visit) {
visit?.changeHistory()
const renderer = new ErrorRenderer(this.snapshot, snapshot, ErrorRenderer.renderElement, false)
return this.render(renderer)
}
clearSnapshotCache() {
this.snapshotCache.clear()
}
async cacheSnapshot(snapshot: PageSnapshot = this.snapshot) {
if (snapshot.isCacheable) {
this.delegate.viewWillCacheSnapshot()
const { 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)
}
}