fix(client): parse learner code with DOMParser (#55763)
parent
7410ed0aa7
commit
bde209bbba
|
@ -213,13 +213,11 @@ export const embedFilesInHtml = async function (challengeFiles) {
|
|||
script.removeAttribute('src');
|
||||
script.setAttribute('data-src', 'script.js');
|
||||
}
|
||||
return {
|
||||
contents: documentElement.innerHTML
|
||||
};
|
||||
return documentElement.innerHTML;
|
||||
};
|
||||
|
||||
if (indexHtml) {
|
||||
const { contents } = await transformWithFrame(
|
||||
const contents = await parseAndTransform(
|
||||
embedStylesAndScript,
|
||||
indexHtml.contents
|
||||
);
|
||||
|
@ -243,32 +241,11 @@ function challengeFilesToObject(challengeFiles) {
|
|||
return { indexHtml, indexJsx, stylesCss, scriptJs };
|
||||
}
|
||||
|
||||
const transformWithFrame = async function (transform, contents) {
|
||||
// we use iframe here since file.contents is destined to be be inserted into
|
||||
// the root of an iframe.
|
||||
const frame = document.createElement('iframe');
|
||||
frame.style = 'display: none';
|
||||
let out = { contents };
|
||||
try {
|
||||
// the frame needs to be inserted into the document to create the html
|
||||
// element
|
||||
document.body.appendChild(frame);
|
||||
// replace the root element with user code
|
||||
frame.contentDocument.documentElement.innerHTML = contents;
|
||||
// grab the contents now, in case the transformation fails
|
||||
out = { contents: frame.contentDocument.documentElement.innerHTML };
|
||||
// it's important to pass around the documentElement and NOT the frame
|
||||
// itself. It appears that the frame's documentElement can get replaced by a
|
||||
// blank documentElement without the contents. This seems only to happen on
|
||||
// Firefox.
|
||||
out = await transform(
|
||||
frame.contentDocument.documentElement,
|
||||
frame.contentDocument
|
||||
);
|
||||
} finally {
|
||||
document.body.removeChild(frame);
|
||||
}
|
||||
return out;
|
||||
const parseAndTransform = async function (transform, contents) {
|
||||
const parser = new DOMParser();
|
||||
const newDoc = parser.parseFromString(contents, 'text/html');
|
||||
|
||||
return await transform(newDoc.documentElement, newDoc);
|
||||
};
|
||||
|
||||
const transformHtml = async function (file) {
|
||||
|
@ -277,10 +254,10 @@ const transformHtml = async function (file) {
|
|||
transformSASS(documentElement),
|
||||
transformScript(documentElement)
|
||||
]);
|
||||
return { contents: documentElement.innerHTML };
|
||||
return documentElement.innerHTML;
|
||||
};
|
||||
|
||||
const { contents } = await transformWithFrame(transform, file.contents);
|
||||
const contents = await parseAndTransform(transform, file.contents);
|
||||
return transformContents(() => contents, file);
|
||||
};
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ const handleRejection = err => {
|
|||
|
||||
const dom = new jsdom.JSDOM('');
|
||||
global.document = dom.window.document;
|
||||
global.DOMParser = dom.window.DOMParser;
|
||||
|
||||
const oldRunnerFail = Mocha.Runner.prototype.fail;
|
||||
Mocha.Runner.prototype.fail = function (test, err) {
|
||||
|
|
Loading…
Reference in New Issue