Created
June 5, 2017 06:43
-
-
Save joeltg/6cb283d2545662a0ef718d7b3303d527 to your computer and use it in GitHub Desktop.
Dynamically embed a GitHub Gist with shadow roots and black magic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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