fix(client): handle missing document in preview frame (#44833)

This commit is contained in:
Oliver Eyton-Williams
2022-01-20 14:22:25 +01:00
committed by GitHub
parent 5aaf8677d4
commit f88473f994

View File

@ -9,6 +9,8 @@ const testId = 'fcc-test-frame';
// the project preview frame demos the finished project
export const projectPreviewId = 'fcc-project-preview-frame';
const DOCUMENT_NOT_FOUND_ERROR = 'document not found';
// base tag here will force relative links
// within iframe to point to '' instead of
// append to the current challenge url
@ -103,7 +105,8 @@ const buildProxyConsole = proxyLogger => ctx => {
};
const initTestFrame = frameReady => ctx => {
waitForFrame(ctx).then(async () => {
waitForFrame(ctx)
.then(async () => {
const { sources, loadEnzyme } = ctx;
// default for classic challenges
// should not be used for modern
@ -115,12 +118,14 @@ const initTestFrame = frameReady => ctx => {
const getUserInput = fileName => toString(sources[fileName]);
await ctx.document.__initTestFrame({ code, getUserInput, loadEnzyme });
frameReady();
});
})
.catch(handleDocumentNotFound);
return ctx;
};
const initMainFrame = (_, proxyLogger) => ctx => {
waitForFrame(ctx).then(() => {
waitForFrame(ctx)
.then(() => {
// Overwriting the onerror added by createHeader to catch any errors thrown
// after the frame is ready. It has to be overwritten, as proxyLogger cannot
// be added as part of createHeader.
@ -136,15 +141,24 @@ const initMainFrame = (_, proxyLogger) => ctx => {
// an error from a cross origin script just appears as 'Script error.'
return false;
};
});
})
.catch(handleDocumentNotFound);
return ctx;
};
function handleDocumentNotFound(err) {
if (err !== DOCUMENT_NOT_FOUND_ERROR) {
console.log(err);
}
}
const initPreviewFrame = () => ctx => ctx;
const waitForFrame = ctx => {
return new Promise(resolve => {
if (ctx.document.readyState === 'loading') {
return new Promise((resolve, reject) => {
if (!ctx.document) {
reject(DOCUMENT_NOT_FOUND_ERROR);
} else if (ctx.document.readyState === 'loading') {
ctx.document.addEventListener('DOMContentLoaded', resolve);
} else {
resolve();
@ -153,10 +167,13 @@ const waitForFrame = ctx => {
};
function writeToFrame(content, frame) {
// it's possible, if the preview is rapidly opened and closed, for the frame
// to be null at this point.
if (frame) {
frame.open();
frame.write(content);
frame.close();
return frame;
}
}
const writeContentToFrame = ctx => {