Elm.init = function(module, baseNode) { 'use strict'; // defining state needed for an instance of the Elm RTS var signalGraph = null; var inputs = []; var visualModel = null; function notify(id, v) { var timestep = Date.now(); var hasListener = false; for (var i = inputs.length; i--; ) { // must maintain the order of this stmt to avoid having the || // short-circuiting the necessary work of recv hasListener = inputs[i].recv(timestep, id, v) || hasListener; } return hasListener; } // ensure that baseNode exists and is properly formatted. var Render = ElmRuntime.Render; if (typeof baseNode === 'undefined') { baseNode = Render.newElement('div'); document.appendChild(baseNode); window.addEventListener('resize', function() { console.log('resize the base node'); baseNode.style.width = document.documentElement.clientWidth + 'px'; baseNode.style.height = document.documentElement.clientHeight + 'px'; }, true); } baseNode.style.overflow = 'scroll'; // create the actuall RTS. Any impure modules will attach themselves to this // object. This permits many Elm programs to be embedded per document. var elm = { notify: notify, node: baseNode }; // evaluate the given module and extract its 'main' value. signalGraph = module(elm).main; // make sure the signal graph is actually a signal, extract the visual model, // and filter out any unused inputs. var Signal = Elm.Signal(elm); if (!('recv' in signalGraph)) signalGraph = Signal.constant(signalGraph); visualModel = signalGraph.value; inputs = ElmRuntime.filterDeadInputs(inputs); // Add the visualModel to the DOM baseNode.appendChild(Render.render(visualModel)); if (p'Window' in elm) { var w = baseNode.clientWidth; if (w !== elm.Window.dimensions.value._0) { notify(elm.Window.dimensions.id, Elm.Native.Utils(elm).Tuple2(w, baseNode.clientHeight)); } } // set up updates so that the DOM is adjusted as necessary. var update = Render.update; function domUpdate(value) { update(baseNode.firstChild, visualModel, value); visualModel = value; return value; } signalGraph = A2(Signal.lift, domUpdate, signalGraph); }; // Helper function to filter dead inputs. Not specific to initialization. ElmRuntime = ElmRuntime || {}; ElmRuntime.filterDeadInputs = function() { 'use strict'; function isAlive(input) { if (!('defaultNumberOfKids' in input)) return true; var len = input.kids.length; if (len == 0) return false; if (len > input.defaultNumberOfKids) return true; var alive = false; for (var i = len; i--; ) { alive = alive || isAlive(input.kids[i]); } return alive; } return function filterDeadInputs(inputs) { var temp = []; for (var i = inputs.length; i--; ) { if (isAlive(inputs[i])) temp.push(inputs[i]); } return temp; }; }();