on master help sign in
Add the Init module which exports Elm.init, creating a self-contained RTS. It can be used as follows:
505b1e3evancz
runtime/Init.jsnew file+92
@@ -0,0 +1,92 @@
1+
2+Elm.init = function(module, baseNode) {
3+ 'use strict';
4+
5+ // defining state needed for an instance of the Elm RTS
6+ var signalGraph = null;
7+ var inputs = [];
8+ var visualModel = null;
9+
10+ function notify(id, v) {
11+ var timestep = Date.now();
12+ var hasListener = false;
13+ for (var i = inputs.length; i--; ) {
14+ // must maintain the order of this stmt to avoid having the ||
15+ // short-circuiting the necessary work of recv
16+ hasListener = inputs[i].recv(timestep, id, v) || hasListener;
17+ }
18+ return hasListener;
19+ }
20+
21+ // ensure that baseNode exists and is properly formatted.
22+ var Render = ElmRuntime.Render;
23+ if (typeof baseNode === 'undefined') {
24+ baseNode = Render.newElement('div');
25+ document.appendChild(baseNode);
26+ window.addEventListener('resize', function() {
27+ console.log('resize the base node');
28+ baseNode.style.width = document.documentElement.clientWidth + 'px';
29+ baseNode.style.height = document.documentElement.clientHeight + 'px';
30+ }, true);
31+ }
32+ baseNode.style.overflow = 'scroll';
33+
34+ // create the actuall RTS. Any impure modules will attach themselves to this
35+ // object. This permits many Elm programs to be embedded per document.
36+ var elm = { notify: notify, node: baseNode };
37+
38+ // evaluate the given module and extract its 'main' value.
39+ signalGraph = module(elm).main;
40+
41+ // make sure the signal graph is actually a signal, extract the visual model,
42+ // and filter out any unused inputs.
43+ var Signal = Elm.Signal(elm);
44+ if (!('recv' in signalGraph)) signalGraph = Signal.constant(signalGraph);
45+ visualModel = signalGraph.value;
46+ inputs = ElmRuntime.filterDeadInputs(inputs);
47+
48+ // Add the visualModel to the DOM
49+ baseNode.appendChild(Render.render(visualModel));
50+
51+ if (p'Window' in elm) {
52+ var w = baseNode.clientWidth;
53+ if (w !== elm.Window.dimensions.value._0) {
54+ notify(elm.Window.dimensions.id,
55+ Elm.Native.Utils(elm).Tuple2(w, baseNode.clientHeight));
56+ }
57+ }
58+
59+ // set up updates so that the DOM is adjusted as necessary.
60+ var update = Render.update;
61+ function domUpdate(value) {
62+ update(baseNode.firstChild, visualModel, value);
63+ visualModel = value;
64+ return value;
65+ }
66+
67+ signalGraph = A2(Signal.lift, domUpdate, signalGraph);
68+};
69+
70+// Helper function to filter dead inputs. Not specific to initialization.
71+ElmRuntime = ElmRuntime || {};
72+ElmRuntime.filterDeadInputs = function() {
73+ 'use strict';
74+ function isAlive(input) {
75+ if (!('defaultNumberOfKids' in input)) return true;
76+ var len = input.kids.length;
77+ if (len == 0) return false;
78+ if (len > input.defaultNumberOfKids) return true;
79+ var alive = false;
80+ for (var i = len; i--; ) {
81+ alive = alive || isAlive(input.kids[i]);
82+ }
83+ return alive;
84+ }
85+ return function filterDeadInputs(inputs) {
86+ var temp = [];
87+ for (var i = inputs.length; i--; ) {
88+ if (isAlive(inputs[i])) temp.push(inputs[i]);
89+ }
90+ return temp;
91+ };
92+}();
runtime/Render.js+4−4
@@ -1,5 +1,5 @@
1−
1+ElmRuntime = ElmRuntime || {};
2−(function() {
2+ElmRuntime.Render = function() {
3'use strict';
3'use strict';
4
4
5function newElement(elementType) {
5function newElement(elementType) {
@@ -277,11 +277,11 @@ function update(node, curr, next) {
277 }
277 }
278}
278}
279
279
280−Elm.Runtime = {
280+return {
281 render:render,
281 render:render,
282 update:update,
282 update:update,
283 addTo:addTo,
283 addTo:addTo,
284 newElement:newElement
284 newElement:newElement
285};
285};
286
286
287−}())
287+}();