|
|
|
@ -1,3 +1,32 @@ |
|
|
|
const frameHtml = `<!doctype html>
|
|
|
|
<html> |
|
|
|
<head> |
|
|
|
<title>Frame</title> |
|
|
|
<style> |
|
|
|
html, body, iframe { |
|
|
|
margin: 0; |
|
|
|
padding: 0; |
|
|
|
width: 100%; |
|
|
|
height: 100%; |
|
|
|
} |
|
|
|
</style> |
|
|
|
</head> |
|
|
|
<body> |
|
|
|
<iframe srcdoc="" sandbox="allow-scripts"></iframe> |
|
|
|
<script type="module"> |
|
|
|
const frame = document.getElementsByTagName('iframe')[0] |
|
|
|
addEventListener('message', event => { |
|
|
|
const d = event.data |
|
|
|
if (Array.isArray(d) && d[0] === 'srcdoc') { |
|
|
|
frame.srcdoc = d |
|
|
|
} else { |
|
|
|
frame.postMessage(event.data) |
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
|
</body> |
|
|
|
</html>` |
|
|
|
|
|
|
|
export class Page extends HTMLElement { |
|
|
|
constructor() { |
|
|
|
super() |
|
|
|
@ -31,5 +60,31 @@ export class Page extends HTMLElement { |
|
|
|
} |
|
|
|
` |
|
|
|
this.shadowRoot.append(style) |
|
|
|
if (path.startsWith('/sandbox/')) { |
|
|
|
this.initFrame() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
initFrame() { |
|
|
|
const tmp = document.createElement('iframe') |
|
|
|
tmp.sandbox = "allow-same-origin allow-scripts" |
|
|
|
const url = new URL( |
|
|
|
'/-/frame', location.href |
|
|
|
) |
|
|
|
url.searchParams.set( |
|
|
|
'csp', |
|
|
|
"default-src 'self'" |
|
|
|
) |
|
|
|
url.searchParams.set('html', frameHtml) |
|
|
|
tmp.src = url.href |
|
|
|
this.shadowRoot.insertAdjacentHTML( |
|
|
|
'beforeend', tmp.outerHTML |
|
|
|
) |
|
|
|
const frames = this.shadowRoot.getElementsByTagName('iframe') |
|
|
|
this.frame = frames[frames.length - 1] |
|
|
|
this.textArea.addEventListener('blur', e => { |
|
|
|
const msg = ['srcdoc', e.target.value] |
|
|
|
this.frame.contentWindow.postMessage(msg) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |