Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wait for CSS to be loaded before replacing the Body #614

Merged
merged 9 commits into from Jul 29, 2022
17 changes: 12 additions & 5 deletions src/core/drive/page_renderer.ts
@@ -1,6 +1,7 @@
import { Renderer } from "../renderer"
import { PageSnapshot } from "./page_snapshot"
import { ReloadReason } from "../native/browser_adapter"
import { waitForLoad } from "../../util"

export class PageRenderer extends Renderer<HTMLBodyElement, PageSnapshot> {
get shouldRender() {
Expand All @@ -21,8 +22,8 @@ export class PageRenderer extends Renderer<HTMLBodyElement, PageSnapshot> {
}
}

prepareToRender() {
this.mergeHead()
async prepareToRender() {
await this.mergeHead()
}

async render() {
Expand Down Expand Up @@ -50,8 +51,8 @@ export class PageRenderer extends Renderer<HTMLBodyElement, PageSnapshot> {
return this.newSnapshot.element
}

mergeHead() {
this.copyNewHeadStylesheetElements()
async mergeHead() {
await this.copyNewHeadStylesheetElements()
this.copyNewHeadScriptElements()
this.removeCurrentHeadProvisionalElements()
this.copyNewHeadProvisionalElements()
manuelpuyol marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -68,10 +69,16 @@ export class PageRenderer extends Renderer<HTMLBodyElement, PageSnapshot> {
return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature
}

copyNewHeadStylesheetElements() {
async copyNewHeadStylesheetElements() {
const loadingElements = []

for (const element of this.newHeadStylesheetElements) {
loadingElements.push(waitForLoad(element as HTMLLinkElement))

document.head.appendChild(element)
}

await Promise.all(loadingElements)
}

copyNewHeadScriptElements() {
Expand Down
6 changes: 3 additions & 3 deletions src/core/view.ts
Expand Up @@ -82,7 +82,7 @@ export abstract class View<
try {
this.renderPromise = new Promise((resolve) => (this.resolveRenderPromise = resolve))
this.renderer = renderer
this.prepareToRenderSnapshot(renderer)
await this.prepareToRenderSnapshot(renderer)

const renderInterception = new Promise((resolve) => (this.resolveInterceptionPromise = resolve))
const immediateRender = this.delegate.allowsImmediateRender(snapshot, this.resolveInterceptionPromise)
Expand All @@ -106,9 +106,9 @@ export abstract class View<
this.delegate.viewInvalidated(reason)
}

prepareToRenderSnapshot(renderer: R) {
async prepareToRenderSnapshot(renderer: R) {
this.markAsPreview(renderer.isPreview)
renderer.prepareToRender()
await renderer.prepareToRender()
}

markAsPreview(isPreview: boolean) {
Expand Down
14 changes: 14 additions & 0 deletions src/util.ts
Expand Up @@ -92,3 +92,17 @@ export function clearBusyState(...elements: Element[]) {
element.removeAttribute("aria-busy")
}
}

export function waitForLoad(element: HTMLLinkElement, timeoutInMilliseconds = 2000): Promise<void> {
return new Promise((resolve) => {
const onComplete = () => {
element.removeEventListener("error", onComplete)
element.removeEventListener("load", onComplete)
resolve()
}

manuelpuyol marked this conversation as resolved.
Show resolved Hide resolved
element.addEventListener("load", onComplete, { once: true })
element.addEventListener("error", onComplete, { once: true })
setTimeout(resolve, timeoutInMilliseconds)
})
}