Skip to content

Instantly share code, notes, and snippets.

@javan
Created November 28, 2016 20:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save javan/c287033adefde0428dd8176ba2a4e80f to your computer and use it in GitHub Desktop.
Save javan/c287033adefde0428dd8176ba2a4e80f to your computer and use it in GitHub Desktop.
<bc-require>: Basecamp 3's lazy JavaScript loader
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}']")
<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>
@javan
Copy link
Author

javan commented Nov 28, 2016

BC.registerElement is a helper around Document.registerElement()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment