basic impl of wait for stylesheet loaded
This commit is contained in:
@@ -55,6 +55,6 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"delegated-events": "git+https://git@github.com/rrweb-io/delegated-events.git",
|
"delegated-events": "git+https://git@github.com/rrweb-io/delegated-events.git",
|
||||||
"mitt": "^1.1.3",
|
"mitt": "^1.1.3",
|
||||||
"rrweb-snapshot": "^0.6.4"
|
"rrweb-snapshot": "^0.6.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ function getCode(): string {
|
|||||||
return fs.readFileSync(bundlePath, 'utf8');
|
return fs.readFileSync(bundlePath, 'utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function safeStringify(obj: Object): string {
|
||||||
|
return JSON.stringify(obj)
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>');
|
||||||
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const code = getCode();
|
const code = getCode();
|
||||||
|
|
||||||
@@ -110,7 +117,7 @@ function getCode(): string {
|
|||||||
path: path.resolve(__dirname, '../dist/rrweb.min.css'),
|
path: path.resolve(__dirname, '../dist/rrweb.min.css'),
|
||||||
});
|
});
|
||||||
await page.evaluate(`${code}
|
await page.evaluate(`${code}
|
||||||
const events = ${JSON.stringify(events)};
|
const events = ${safeStringify(events)};
|
||||||
const replayer = new rrweb.Replayer(events);
|
const replayer = new rrweb.Replayer(events);
|
||||||
replayer.play();
|
replayer.play();
|
||||||
`);
|
`);
|
||||||
@@ -139,7 +146,7 @@ function getCode(): string {
|
|||||||
<body>
|
<body>
|
||||||
<script src="../dist/rrweb.min.js"></script>
|
<script src="../dist/rrweb.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const data = ${JSON.stringify({ events })}
|
const data = ${safeStringify({ events })}
|
||||||
const replayer = new rrweb.Replayer(data.events);
|
const replayer = new rrweb.Replayer(data.events);
|
||||||
replayer.play();
|
replayer.play();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const mitt = (mittProxy as any).default || mittProxy;
|
|||||||
const defaultConfig: playerConfig = {
|
const defaultConfig: playerConfig = {
|
||||||
speed: 1,
|
speed: 1,
|
||||||
root: document.body,
|
root: document.body,
|
||||||
|
loadTimeout: 10 * 1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Replayer {
|
export class Replayer {
|
||||||
@@ -207,6 +208,7 @@ export class Replayer {
|
|||||||
event: fullSnapshotEvent & { timestamp: number },
|
event: fullSnapshotEvent & { timestamp: number },
|
||||||
) {
|
) {
|
||||||
mirror.map = rebuild(event.data.node, this.iframe.contentDocument!)[1];
|
mirror.map = rebuild(event.data.node, this.iframe.contentDocument!)[1];
|
||||||
|
this.waitForStylesheetLoad();
|
||||||
// avoid form submit to refresh the iframe
|
// avoid form submit to refresh the iframe
|
||||||
off('submit', 'form', this.preventDefault, {
|
off('submit', 'form', this.preventDefault, {
|
||||||
document: this.iframe.contentDocument!,
|
document: this.iframe.contentDocument!,
|
||||||
@@ -223,6 +225,43 @@ export class Replayer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pause when loading style sheet, resume when loaded all timeout exceed
|
||||||
|
*/
|
||||||
|
private waitForStylesheetLoad() {
|
||||||
|
const { head } = this.iframe.contentDocument!;
|
||||||
|
if (head) {
|
||||||
|
const unloadSheets: Set<HTMLLinkElement> = new Set();
|
||||||
|
let timer: number;
|
||||||
|
head
|
||||||
|
.querySelectorAll('link[rel="stylesheet"]')
|
||||||
|
.forEach((css: HTMLLinkElement) => {
|
||||||
|
if (!css.sheet) {
|
||||||
|
if (unloadSheets.size === 0) {
|
||||||
|
this.pause();
|
||||||
|
this.emitter.emit('wait-stylesheet');
|
||||||
|
timer = window.setTimeout(() => {
|
||||||
|
this.resume();
|
||||||
|
// mark timer was called
|
||||||
|
timer = -1;
|
||||||
|
}, this.config.loadTimeout);
|
||||||
|
}
|
||||||
|
unloadSheets.add(css);
|
||||||
|
css.addEventListener('load', () => {
|
||||||
|
unloadSheets.delete(css);
|
||||||
|
if (unloadSheets.size === 0 && timer !== -1) {
|
||||||
|
this.resume();
|
||||||
|
this.emitter.emit('stylesheet-loaded');
|
||||||
|
if (timer) {
|
||||||
|
window.clearTimeout(timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private preventDefault(evt: Event) {
|
private preventDefault(evt: Event) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,6 +226,7 @@ export type hookResetter = () => void;
|
|||||||
export type playerConfig = {
|
export type playerConfig = {
|
||||||
speed: number;
|
speed: number;
|
||||||
root: Element;
|
root: Element;
|
||||||
|
loadTimeout: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type playerMetaData = {
|
export type playerMetaData = {
|
||||||
|
|||||||
Reference in New Issue
Block a user