var Signal = function() { function toElmString(str) { var out = ["Nil"]; for (var i = str.length; i--; ) { out = ["Cons", str[i], out]; } return out; } var addListener = function() { if(document.addEventListener) { return function(element, event, handler) { element.addEventListener(event, handler, false); }; } else { return function(element, event, handler) { element.attachEvent('on' + event, handler); }; } }(); var Mouse = function() { var position = Elm.Input(Value.Tuple(0,0)); var isDown = Elm.Input(false); var isClicked = Elm.Input(false); function getXY(e) { var posx = 0; var posy = 0; if (!e) var e = window.event; if (e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; } else if (e.clientX || e.clientY) { posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } return Value.Tuple(posx, posy); } addListener(document, 'click', function(e) { Dispatcher.notify(isClicked.id, true); Dispatcher.notify(isClicked.id, false); }); addListener(document, 'mousedown', function(e) { Dispatcher.notify(isDown.id, true); }); addListener(document, 'mouseup', function(e) { Dispatcher.notify(isDown.id, false); }); addListener(document, 'mousemove', function(e) { Dispatcher.notify(position.id, getXY(e)); }); var clickedOn = function(elem) { var click = Elm.Input(false); addListener(elem, 'click', function(e) { Dispatcher.notify(click.id, true); Dispatcher.notify(click.id, false); }); return Value.Tuple(elem, click); }; return {position: position, x: Elm.Lift(function(p){return p[1];},[position]), y: Elm.Lift(function(p){return p[2];},[position]), isClicked: isClicked, isDown: isDown, clickedOn: clickedOn }; }(); var Time = function() { var every = function(t) { t *= 1000; var clock = Elm.Input(0); var time = 0; setInterval(function() { time += t; Dispatcher.notify(clock.id, time/1000); }, t); return clock; }; var after = function(t) { t *= 1000; var thread = Elm.Input(false); setTimeout(function() { Dispatcher.notify(thread.id, true); }, t); return thread; }; var before = function(t) { t *= 1000; var thread = Elm.Input(true); setTimeout(function() { Dispatcher.notify(thread.id, false); }, t); return thread; }; return {every:every,after:after,before:before}; }(); var Window = function() { var dimensions = Elm.Input(Value.Tuple(window.innerWidth,window.innerHeight)); addListener(window, 'resize', function(e) { var w = document.getElementById('widthChecker').offsetWidth; Dispatcher.notify(dimensions.id, Value.Tuple(w, window.innerHeight)); }); return {dimensions:dimensions, width : Elm.Lift(function(p){return p[1];},[dimensions]), height: Elm.Lift(function(p){return p[2];},[dimensions]) }; }(); var Keyboard = { Raw : function() { var keysDown = Elm.Input(["Nil"]); var charPressed = Elm.Input(["Nothing"]); function remove(x,xs) { if (xs[0] === "Nil") return xs; if (xs[1] === x) return xs[2]; return ["Cons", xs[1], remove(x,xs[2])]; } function has(x,xs) { while (xs[0] !== "Nil") { if (xs[1] === x) return true; xs = xs[2]; } return false; } addListener(document, 'keydown', function(e) { if (has(e.keyCode, keysDown.value)) return; Dispatcher.notify(keysDown.id, ["Cons", e.keyCode, keysDown.value]); }); addListener(document, 'keyup', function(e) { var codes = remove(e.keyCode, keysDown.value) Dispatcher.notify(keysDown.id, codes); }); addListener(window, 'blur', function(e) { Dispatcher.notify(keysDown.id, ["Nil"]); }); addListener(document, 'keypress', function(e) { Dispatcher.notify(charPressed.id, ["Just",e.charCode || e.keyCode]); Dispatcher.notify(charPressed.id, ["Nothing"]); }); return {keysDown:keysDown, charPressed:charPressed}; }() }; var HTTP = function() { var fetch = function(how) { return function(url) { var thread = Elm.Input(["Waiting"]); var request = {}; if (window.XMLHttpRequest) { request = new XMLHttpRequest(); } else if (window.ActiveXObject) { request = new ActiveXObject("Microsoft.XMLHTTP"); } request.onreadystatechange = function(e) { if (request.readyState === 4) { Dispatcher.notify(thread.id, request.status === 200 ? ["Success", toElmString(request.responseText)] : ["Failure", request.status, toElmString(request.statusText)]); } }; request.open(how, Data.String.toText(url), true); request.send(null); return thread; }; }; var fetches = function(how) { return function(input) { var output = Elm.Input(["Nothing"]); var fetcher = Elm.Lift(update, [input]); var combine = Elm.Lift(function(x) { return function(y) { return x; } }, [output,fetcher]); function update(strOpt) { if (strOpt[0] !== "Just") { try { Dispatcher.notify(output.id, ["Nothing"]); } catch(e) {} return []; } try { Dispatcher.notify(output.id, ["Just", ["Waiting"]]); } catch(e) { output.value = ["Just", ["Waiting"]]; } var request = {}; if (window.XMLHttpRequest) { request = new XMLHttpRequest(); } else if (window.ActiveXObject) { request = new ActiveXObject("Microsoft.XMLHTTP"); } request.onreadystatechange = function(e) { if (request.readyState === 4) { Dispatcher.notify(output.id, ["Just", request.status === 200 ? ["Success", toElmString(request.responseText)] : ["Failure", request.status, toElmString(request.statusText)]]); } }; request.open(how, Data.String.toText(strOpt[1]), true); request.send(null); return []; } return combine; }; }; return {get : fetch("GET"), post : fetch("POST"), gets : fetches("GET"), posts : fetches("POST") }; }(); var Random = function() { var inRange = function(min) { return function(max) { return Elm.Input(Math.floor(Math.random() * (max-min+1)) + min); }; }; var randomize = function(min) { return function(max) { return function(signal) { return Elm.Lift(function(x) { return Math.floor(Math.random() * (max-min+1)) + min;},[signal]); }; }; }; return { inRange:inRange, randomize:randomize }; }(); var Input = function() { var newTextInput = function(elem, ghostText) { elem.isElmLeaf = true; var str = Elm.Input(["Nil"]); addListener(elem, 'keyup', function(e) { Dispatcher.notify(str.id, toElmString(elem.value)); elem.focus(); }); return Value.Tuple(elem, str); }; var newElement = function(name) { var e = document.createElement(name); e.id = Guid.guid(); return e; }; var textArea = function(cols) { return function(rows) { var textarea = newElement('textarea'); textarea.rows = rows; textarea.cols = cols; return newTextInput(textarea, ""); }; }; var textField = function(ghostText) { var field = newElement('input'); field.type = 'text'; return newTextInput(field, ghostText); }; var password = function(ghostText) { var field = newElement('input'); field.type = 'password'; return newTextInput(field, ghostText); }; var checkbox = function(checked) { var box = newElement('input'); box.type = 'checkbox'; box.checked = checked; var status = Elm.Input(checked); addListener(box, 'change', function(e) { Dispatcher.notify(status.id, box.checked); }); return Value.Tuple(box, status); }; var dropDown = function(options) { var slct = newElement('select'); var opts = []; while (options[0] === "Cons") { var opt = newElement('option'); var str = Text.toText(options[1][1]); opt.value = str; opt.innerHTML = str; slct.appendChild(opt); opts.push(options[1][2]); options = options[2]; } var status = Elm.Input(opts[0]); addListener(slct, 'change', function(e) { Dispatcher.notify(status.id, opts[slct.selectedIndex]); }); return Value.Tuple(slct, status); }; var stringDropDown = function(opts) { return dropDown(List.map (function(x) {return Value.Tuple(x,x);}) (opts)); }; var button = function(name) { var b = newElement('input'); b.type = "button"; b.value = Text.toText(name); var press = Elm.Input(false); addListener(b, 'click', function(e) { Dispatcher.notify(press.id, true); Dispatcher.notify(press.id, false); }); return Value.Tuple(b,press); }; return {textArea:textArea, textField:textField, password:password, checkbox:checkbox, dropDown:dropDown, stringDropDown:stringDropDown, button:button}; }(); return {Mouse:Mouse, Keyboard:Keyboard, Time:Time, Window:Window, HTTP:HTTP, Random:Random, Input:Input, constant : function(v) { return Elm.Input(v); }, lift : function(f){return function(e){return Elm.Lift(f,[e]);};}, lift2 : function(f) { return function(e1) { return function(e2) { return Elm.Lift(f, [e1,e2]); }; }; }, lift3 : function(f) { return function(e1) { return function(e2) { return function(e3){return Elm.Lift(f,[e1,e2,e3]);};};};}, lift4 : function(f) { return function(e1) { return function(e2) { return function(e3) { return function(e4) { return Elm.Lift(f, [e1,e2,e3,e4]); }; }; }; }; }, foldp : function(f) { return function(b) { return function(e) { return Elm.Fold(f,b,e); }; }; } }; }();