on 6134ed5 help sign in
elk/runtime/Init.js
110 lines 3.6 kB history raw
2(function() {
3'use strict';
5Elm.fullscreen = function(module) {
6 var style = document.createElement('style');
7 style.type = 'text/css';
8 style.innerHTML = "html,head,body { padding:0; margin:0; }" +
9 "body { font-family: calibri, helvetica, arial, sans-serif; }";
10 document.head.appendChild(style);
11 return init(ElmRuntime.Display.FULLSCREEN, document.body, module);
12};
14Elm.node = function(width, height, module) {
15 var container = document.createElement('div');
16 container.style.width = width + 'px';
17 container.style.height = height + 'px';
18 return init(ElmRuntime.Display.COMPONENT, container, module);
19};
21Elm.worker = function(module) {
22 return init(ElmRuntime.Display.NONE, {}, module);
23};
25function init(display, container, module) {
26 // defining state needed for an instance of the Elm RTS
27 var signalGraph = null;
28 var inputs = [];
29 var visualModel = null;
31 function notify(id, v) {
32 var timestep = Date.now();
33 var hasListener = false;
34 for (var i = inputs.length; i--; ) {
35 // must maintain the order of this stmt to avoid having the ||
36 // short-circuiting the necessary work of recv
37 hasListener = inputs[i].recv(timestep, id, v) || hasListener;
38 }
39 return hasListener;
40 }
42 container.offsetX = 0;
43 container.offsetY = 0;
45 // create the actual RTS. Any impure modules will attach themselves to this
46 // object. This permits many Elm programs to be embedded per document.
47 var elm = { notify:notify,
48 node:container,
49 display:display,
50 id:ElmRuntime.guid(),
51 inputs:inputs
52 };
54 // Set up methods to communicate with Elm program from JS.
55 function send(name, value) {
56 if (typeof value === 'undefined') return function(v) { return send(name,v); };
57 var e = document.createEvent('Event');
58 e.initEvent(name + '_' + elm.id, true, true);
59 e.value = value;
60 document.dispatchEvent(e);
61 }
62 function recv(name, handler) {
63 document.addEventListener(name + '_' + elm.id, handler);
64 }
66 recv('log', function(e) {console.log(e.value)});
67 recv('title', function(e) {document.title = e.value});
68 recv('redirect', function(e) {
69 if (e.value.length > 0) { window.location = e.value; }
70 });
72 // If graphics are not enabled, escape early, skip over setting up DOM stuff.
73 if (display === ElmRuntime.Display.NONE) {
74 return { send : send, recv : recv };
75 }
77 var Render = ElmRuntime.use(ElmRuntime.Render.Element);
79 // evaluate the given module and extract its 'main' value.
80 signalGraph = module(elm).main;
82 // make sure the signal graph is actually a signal, extract the visual model,
83 // and filter out any unused inputs.
84 var Signal = Elm.Signal(elm);
85 if (!('recv' in signalGraph)) signalGraph = Signal.constant(signalGraph);
86 visualModel = signalGraph.value;
87 inputs = ElmRuntime.filterDeadInputs(inputs);
89 // Add the visualModel to the DOM
90 var renderNode = Render.render(visualModel)
91 container.appendChild(renderNode);
92 if (elm.Native.Window) elm.Native.Window.resizeIfNeeded();
94 // set up updates so that the DOM is adjusted as necessary.
95 var update = Render.update;
96 function domUpdate(value) {
97 ElmRuntime.draw(function(_) {
98 update(renderNode, visualModel, value);
99 visualModel = value;
100 if (elm.Native.Window) elm.Native.Window.resizeIfNeeded();
101 });
102 return value;
103 }
105 signalGraph = A2(Signal.lift, domUpdate, signalGraph);
107 return { send : send, recv : recv, node : container };
108};
110}());