armo-breadboard
Version:
Edit a live React component's source in real time.
49 lines (39 loc) • 1.74 kB
JavaScript
import hostScriptSource from '!!raw!../breadboard-host.js'
function replaceLocalNodes(nodes, attr, scheme) {
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i]
const parser = document.createElement('a')
parser.href = node[attr]
if (parser.host === window.location.host &&
parser.protocol === window.location.protocol) {
const comment = document.createComment(scheme+'://'+parser.pathname)
node.parentNode.replaceChild(comment, node)
}
}
}
export function createBreadboardHTMLTransform(hostURL) {
return source => {
const parser = new DOMParser();
const doc = parser.parseFromString(source, "text/html");
const scripts = doc.getElementsByTagName('script')
replaceLocalNodes(scripts, 'src', 'breadboardscript')
const links = doc.querySelectorAll('link[rel="stylesheet"]')
replaceLocalNodes(links, 'href', 'breadboardstyle')
const head = doc.getElementsByTagName('head')[0]
const hostScript = doc.createElement('script')
// TODO: if IE, use `hostURL`
//hostScript.src = `data:text/javascript;charset=utf-8;base64,${btoa(hostScriptSource)}`
hostScript.text = '__$BREADBOARD_HOST_SCRIPT$__'
// Insert our scripts before the first script, so that we have access to anything defined before there.
const headScripts = head.getElementsByTagName('script')
if (headScripts.length > 0) {
head.insertBefore(hostScript, headScripts[0])
}
else {
head.appendChild(hostScript)
}
head.insertBefore(document.createComment('BREADBOARD_SETTINGS'), hostScript)
const serializer = new XMLSerializer();
return serializer.serializeToString(doc).replace('__$BREADBOARD_HOST_SCRIPT$__', hostScriptSource);
}
}