fix(client): handle missing document in preview frame (#44833)
This commit is contained in:
committed by
GitHub
parent
5aaf8677d4
commit
f88473f994
@ -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,48 +105,60 @@ const buildProxyConsole = proxyLogger => ctx => {
|
||||
};
|
||||
|
||||
const initTestFrame = frameReady => ctx => {
|
||||
waitForFrame(ctx).then(async () => {
|
||||
const { sources, loadEnzyme } = ctx;
|
||||
// default for classic challenges
|
||||
// should not be used for modern
|
||||
const code = {
|
||||
contents: sources.index,
|
||||
editableContents: sources.editableContents
|
||||
};
|
||||
// provide the file name and get the original source
|
||||
const getUserInput = fileName => toString(sources[fileName]);
|
||||
await ctx.document.__initTestFrame({ code, getUserInput, loadEnzyme });
|
||||
frameReady();
|
||||
});
|
||||
waitForFrame(ctx)
|
||||
.then(async () => {
|
||||
const { sources, loadEnzyme } = ctx;
|
||||
// default for classic challenges
|
||||
// should not be used for modern
|
||||
const code = {
|
||||
contents: sources.index,
|
||||
editableContents: sources.editableContents
|
||||
};
|
||||
// provide the file name and get the original source
|
||||
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(() => {
|
||||
// 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.
|
||||
ctx.window.onerror = function (msg) {
|
||||
var string = msg.toLowerCase();
|
||||
if (string.includes('script error')) {
|
||||
msg = 'Error, open your browser console to learn more.';
|
||||
}
|
||||
if (proxyLogger) {
|
||||
proxyLogger(msg);
|
||||
}
|
||||
// let the error propagate so it appears in the browser console, otherwise
|
||||
// an error from a cross origin script just appears as 'Script error.'
|
||||
return false;
|
||||
};
|
||||
});
|
||||
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.
|
||||
ctx.window.onerror = function (msg) {
|
||||
var string = msg.toLowerCase();
|
||||
if (string.includes('script error')) {
|
||||
msg = 'Error, open your browser console to learn more.';
|
||||
}
|
||||
if (proxyLogger) {
|
||||
proxyLogger(msg);
|
||||
}
|
||||
// let the error propagate so it appears in the browser console, otherwise
|
||||
// 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) {
|
||||
frame.open();
|
||||
frame.write(content);
|
||||
frame.close();
|
||||
return 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();
|
||||
}
|
||||
}
|
||||
|
||||
const writeContentToFrame = ctx => {
|
||||
|
Reference in New Issue
Block a user