Skip to content

Instantly share code, notes, and snippets.

@joeltg
Created June 5, 2017 06:43
Show Gist options
  • Save joeltg/6cb283d2545662a0ef718d7b3303d527 to your computer and use it in GitHub Desktop.
Save joeltg/6cb283d2545662a0ef718d7b3303d527 to your computer and use it in GitHub Desktop.
Dynamically embed a GitHub Gist with shadow roots and black magic
// GitHub expects us to embed Gists by including a script like this:
// <script src="https://gist.github.com/hash.js"></script>
// But this only works if included at parse timue because the script uses
// document.write() so it can't be dynamically inserted afterwards.
// Google recomments creating an iframe and using contentDocument.writeln()
// with skeleton html that loads the script and writes to the iframe document,
// but then if we ever move the element (or clone it for ghosting) the iframe
// will reload.
// SO instead, we make a shadow root, attach an invisible iframe to the
// shadow root that loads the GitHub embed script for ths gist, and then
// in the onload handler of the iframe we set shadowRoot's innerHTML to be
// the iframe's innerHTML, which removes the iframe and leaves us with
// a single shadow root with all the html that the embed script wrote while
// inside executing the iframe. The only drawback is that this ends up requesting
// GitHub's Gist CSS twice, but with caching that shouldn't actually hit the network.
function attachGist(gistId, element) {
// gistURL is a Gist ID e.g. "6cb283d2545662a0ef718d7b3303d527"
// element is a DOM element to hold the Gist
element.innerHTML = ""
element.id = gistId
const root = element.attachShadow({ mode: "open" })
const iframe = document.createElement("iframe")
iframe.style.display = "none"
root.appendChild(iframe)
const script = `<script src="https://gist.github.com/${gistId}.js"></script>`
const onload = `parent.document.getElementById('${gistId}').shadowRoot.innerHTML = document.body.innerHTML`
iframe.contentDocument.open()
iframe.contentDocument.writeln(`<html><body onload="${onload}">${script}</body></html>`)
iframe.contentDocument.close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment