Created
February 22, 2023 05:26
-
-
Save jweir/fdd827d649730dcf556fec4f94a67874 to your computer and use it in GitHub Desktop.
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
# helper function to embed Elm applications | |
# This does not support defining ports | |
module ElmHelper | |
def elm(element_id, elm_app, **flags) | |
tag.div('', data: { turbo: 'false' }) do | |
add_elm_global_flags + | |
tag.div('', id: element_id) + | |
embed_elm_app(element_id, elm_app, **flags).html_safe | |
end | |
end | |
# Define, just once on a page, any common fields that can be passed to | |
# an app. See App.Flags in the Elm code | |
def add_elm_global_flags | |
return ''.html_safe if @elm_global_flags_added | |
tag.script do | |
"window.elmGlobals = {environment: '#{Rails.env}'}".html_safe | |
end | |
ensure | |
@elm_global_flags_added = true | |
end | |
def embed_elm_app(element_id, elm_app, **flags) | |
<<~JS | |
<script> | |
(function(){ | |
// Some safety to minimize possible errors | |
window.elmGlobals = window.elmGlobals || {environment: 'development'}; | |
function isEmpty(obj) { | |
return Object.keys(obj).length === 0; | |
} | |
function bootElmApp() { | |
var flags = #{flags.to_json} | |
, node = document.getElementById(#{element_id.to_json}) | |
, initParams; | |
if ( flags === null || isEmpty(flags)) { | |
initParams = {node: node}; | |
} else { | |
initParams = {node: node, flags: flags}; | |
} | |
// merge the global flags with the app specific flags | |
Object | |
.keys(window.elmGlobals) | |
.reduce(function(agg, key){ agg[key] = window.elmGlobals[key]; return agg}, initParams.flags || {}); | |
try { | |
var app = Elm.#{elm_app}.init(initParams); | |
ElmPorts(app); | |
} catch(err) { | |
throw(console.log("Error", '#{elm_app}', err, "; Elm params: ", initParams)); | |
} | |
} | |
if ( | |
document.readyState === "complete" || | |
(document.readyState !== "loading" && !document.documentElement.doScroll) | |
) { | |
bootElmApp(); | |
} else { | |
document.addEventListener("DOMContentLoaded", bootElmApp); | |
} | |
})(); | |
</script> | |
JS | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment