Created
November 28, 2016 20:24
-
-
Save javan/c287033adefde0428dd8176ba2a4e80f to your computer and use it in GitHub Desktop.
<bc-require>: Basecamp 3's lazy JavaScript loader
This file contains hidden or 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
BC.registerElement "bc-require", | |
createdCallback: -> | |
@setAttribute("pending", "") | |
attachedCallback: -> | |
BC.ready => | |
if Loader.find(@script)?.loaded | |
@activate() | |
else | |
@deactivate() | |
Loader.load(@script).then => @activate() | |
script: | |
get: -> | |
@getAttribute("script") | |
deactivate: -> | |
@placeholderStyle = getPlaceholderStyle(this, "width", "height") | |
@style[key] = value for key, value of @placeholderStyle | |
@pendingFragment = document.createDocumentFragment() | |
@pendingFragment.appendChild(child) for child in [@childNodes...] | |
activate: -> | |
@removeAttribute("pending") | |
if @pendingFragment? | |
@appendChild(@pendingFragment) | |
delete @pendingFragment | |
@style[key] = null for key of @placeholderStyle | |
delete @placeholderStyle | |
BC.triggerEvent(this, "bc-require-activate") | |
getPlaceholderStyle = (element, styles...) -> | |
computedStyle = getComputedStyle(element) | |
result = {} | |
result[key] = computedStyle[key] for key in styles | |
result | |
class Loader | |
@loaders: {} | |
@find: (script) -> | |
@loaders[script] | |
@create: (script) -> | |
@loaders[script] = new this script | |
@load: (script) -> | |
@find(script) ? @create(script) | |
constructor: (@script) -> | |
@promise = new Promise (@resolve, @reject) => | |
@load() | |
then: (callback) -> | |
@promise.then(callback) | |
load: -> | |
link = @findLinkElement() | |
script = document.createElement("script") | |
script.src = link.href | |
script.onload = @didLoad | |
link.parentNode.insertBefore(script, link) | |
didLoad: => | |
@loaded = true | |
@resolve() | |
findLinkElement: -> | |
document.head.querySelector("link[rel=subresource][data-script='#{@script}']") |
This file contains hidden or 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
<head> | |
<link rel="subresource" href="[URL for rich_text.js]" data-script="rich_text" data-turbolinks-track="reload" /> | |
</head> | |
<body> | |
<bc-require script="rich_text"> | |
This content will be removed from the DOM until rich_text.js loads | |
</bc-require> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
BC.registerElement
is a helper aroundDocument.registerElement()