Skip to content

Commit

Permalink
fix: iframe load to ensure images are loaded (niklasvh#2577)
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasvh authored Jul 14, 2021
1 parent 52a03c7 commit eeb5a3e
Showing 1 changed file with 32 additions and 12 deletions.
44 changes: 32 additions & 12 deletions src/dom/document-cloner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ export class DocumentCloner {
await documentClone.fonts.ready;
}

if (/(AppleWebKit)/g.test(navigator.userAgent)) {
await imagesReady(documentClone);
}

if (typeof onclone === 'function') {
return Promise.resolve()
.then(() => onclone(documentClone))
Expand Down Expand Up @@ -462,6 +466,25 @@ const createIFrameContainer = (ownerDocument: Document, bounds: Bounds): HTMLIFr
return cloneIframeContainer;
};

const imageReady = (img: HTMLImageElement): Promise<Event | void | string> => {
return new Promise((resolve) => {
if (img.complete) {
resolve();
return;
}
if (!img.src) {
resolve();
return;
}
img.onload = resolve;
img.onerror = resolve;
});
};

const imagesReady = (document: HTMLDocument): Promise<unknown[]> => {
return Promise.all([].slice.call(document.images, 0).map(imageReady));
};

const iframeLoader = (iframe: HTMLIFrameElement): Promise<HTMLIFrameElement> => {
return new Promise((resolve, reject) => {
const cloneWindow = iframe.contentWindow;
Expand All @@ -472,18 +495,15 @@ const iframeLoader = (iframe: HTMLIFrameElement): Promise<HTMLIFrameElement> =>

const documentClone = cloneWindow.document;

cloneWindow.onload =
iframe.onload =
documentClone.onreadystatechange =
() => {
cloneWindow.onload = iframe.onload = documentClone.onreadystatechange = null;
const interval = setInterval(() => {
if (documentClone.body.childNodes.length > 0 && documentClone.readyState === 'complete') {
clearInterval(interval);
resolve(iframe);
}
}, 50);
};
cloneWindow.onload = iframe.onload = () => {
cloneWindow.onload = iframe.onload = null;
const interval = setInterval(() => {
if (documentClone.body.childNodes.length > 0 && documentClone.readyState === 'complete') {
clearInterval(interval);
resolve(iframe);
}
}, 50);
};
});
};

Expand Down

0 comments on commit eeb5a3e

Please sign in to comment.