simov / markdown-viewer

Markdown Viewer / Browser Extension
MIT License
1.07k stars 135 forks source link

<script> execution #217

Open disfated opened 1 year ago

disfated commented 1 year ago

Can we have <script> tags execution inside md?

## Header

These should be executed:

<script>console.log('Hi from js')</script>
<script src="external.js"></script>

Here's the hack that I've come up with to make it work. Just place this <img> at the end of your md

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" onload="this.remove(); for (const script of document.querySelectorAll('#_html script')) { const clone = document.createElement('script'); for (const attr of script.attributes) clone.setAttribute(attr.name, attr.value); clone.appendChild(document.createTextNode(script.innerHTML)); script.parentNode.replaceChild(clone, script); }">

How does it work?

<img src="data:image/png;base64,... is just a transparent pixel

Onload event handler:

this.remove(); // removes <img>
for (const script of document.querySelectorAll('#_html script')) {
    // Replace all <script> tags inside #_html with their clones.
    // jQuery does this inside it's .html() method.
    // Somehow this works 🥴
    const clone = document.createElement('script')
    for (const attr of script.attributes) {
        clone.setAttribute(attr.name, attr.value)
    }
    clone.appendChild(document.createTextNode(script.innerHTML))
    script.parentNode.replaceChild(clone, script)
}

Would be nice to have this out of the box.