diff --git a/client/karma.js b/client/karma.js index 97b3b62fe..c7f646963 100644 --- a/client/karma.js +++ b/client/karma.js @@ -62,12 +62,27 @@ function Karma (socket, iframe, opener, navigator, location) { childWindow.close() } childWindow = opener(url) - // run context on parent element and dynamically loading scripts + // run context on parent element (client_with_context) + // using window.__karma__.scriptUrls to get the html element strings and load them dynamically } else if (url !== 'about:blank') { var loadScript = function (idx) { if (idx < window.__karma__.scriptUrls.length) { - var ele = document.createElement('script') - ele.src = window.__karma__.scriptUrls[idx] + var parser = new DOMParser() + // Revert escaped characters with special roles in HTML before parsing + var string = window.__karma__.scriptUrls[idx] + .replace(/\\x3C/g, '<') + .replace(/\\x3E/g, '>') + var doc = parser.parseFromString(string, 'text/html') + var ele = doc.head.firstChild || doc.body.firstChild + // script elements created by DomParser are marked as unexecutable, + // create a new script element manually and copy necessary properties + // so it is executable + if (ele.tagName && ele.tagName.toLowerCase() === 'script') { + var tmp = ele + ele = document.createElement('script') + ele.src = tmp.src + ele.crossOrigin = tmp.crossOrigin + } ele.onload = function () { loadScript(idx + 1) } diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index c51c34491..cf7a93ec6 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -175,7 +175,6 @@ function createKarmaMiddleware ( common.setNoCacheHeaders(response) const scriptTags = [] - const scriptUrls = [] for (const file of files.included) { let filePath = file.path const fileType = file.type || path.extname(filePath).substring(1) @@ -192,8 +191,6 @@ function createKarmaMiddleware ( } } - scriptUrls.push(filePath) - if (fileType === 'css') { scriptTags.push(``) } else if (fileType === 'dom') { @@ -207,6 +204,20 @@ function createKarmaMiddleware ( } } + const scriptUrls = [] + // For client_with_context, html elements are not added directly through an iframe. + // Instead, scriptTags is stored to window.__karma__.scriptUrls first. Later, the + // client will read window.__karma__.scriptUrls and dynamically add them to the DOM + // using DOMParser. + if (requestUrl === '/client_with_context.html') { + for (const script of scriptTags) { + scriptUrls.push( + // Escape characters with special roles (tags) in HTML. Open angle brackets are parsed as tags + // immediately, even if it is within double quotations in browsers + script.replace(//g, '\\x3E')) + } + } + const mappings = data.includes('%MAPPINGS%') ? files.served.map((file) => { const filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath) .replace(/\\/g, '\\\\') // Windows paths contain backslashes and generate bad IDs if not escaped