Skip to content

Instantly share code, notes, and snippets.

@jweir
Created February 22, 2023 05:26
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jweir/fdd827d649730dcf556fec4f94a67874 to your computer and use it in GitHub Desktop.
Save jweir/fdd827d649730dcf556fec4f94a67874 to your computer and use it in GitHub Desktop.
# 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