@@ -0,0 +1,287 @@
1+
2+(function() {
3+'use strict';
4+
5+function newElement(elementType) {
6+ var e = document.createElement(elementType);
7+ e.style.padding = "0";
8+ e.style.margin = "0";
9+ return e;
10+}
11+
12+function addTo(container, elem) {
13+ container.appendChild(elem);
14+}
15+
16+function makeText(pos,txt) {
17+ var e = newElement('div');
18+ e.innerHTML = txt;
19+ e.style.textAlign = pos;
20+ return e;
21+}
22+
23+function setProps(props, e) {
24+ e.style.width = (props.width |0) + 'px';
25+ e.style.height = (props.height|0) + 'px';
26+ if (props.opacity !== 1) { e.style.opacity = props.opacity; }
27+ if (props.color.ctor === 'Just') {
28+ e.style.backgroundColor = Elm.Color.extract(props.color._0);
29+ }
30+ if (props.tag !== '') { e.id = props.tag; }
31+ if (props.href !== '') {
32+ var a = newElement('a');
33+ a.href = props.href;
34+ addTo(a,e);
35+ return a;
36+ }
37+ return e;
38+}
39+
40+function image(props, img) {
41+ switch (img._0.ctor) {
42+ case 'Plain': return plainImage(img._3);
43+ case 'Fitted': return fittedImage(props.width, props.height, img._3);
44+ case 'Cropped': return croppedImage(img._0._0,props.width,props.height,img._3);
45+ }
46+}
47+
48+function plainImage(src) {
49+ var img = newElement('img');
50+ img.src = src;
51+ img.name = src;
52+ img.style.display = "block";
53+ return img;
54+}
55+
56+function fittedImage(w, h, src) {
57+ var e = newElement('div');
58+ e.style.position = "relative";
59+ e.style.overflow = "hidden";
60+
61+ var img = newElement('img');
62+ img.onload = function() {
63+ img.style.position = 'absolute';
64+ img.style.margin = 'auto';
65+
66+ var sw = w, sh = h;
67+ if (w / h > this.width / this.height) {
68+ sh = Math.round(this.height * w / this.width);
69+ } else {
70+ sw = Math.round(this.width * h / this.height);
71+ }
72+ img.style.width = sw + 'px';
73+ img.style.height = sh + 'px';
74+ img.style.left = ((w - sw) / 2) + 'px';
75+ img.style.top = ((h - sh) / 2) + 'px';
76+ };
77+ img.src = src;
78+ img.name = src;
79+ addTo(e,img);
80+ return e;
81+}
82+
83+function croppedImage(pos, w, h, src) {
84+ var e = newElement('div');
85+ e.style.position = "relative";
86+ e.style.overflow = "hidden";
87+
88+ var img = newElement('img');
89+ img.onload = function() {
90+ img.style.position = 'absolute';
91+ img.style.margin = 'auto';
92+ var sw = dimensions.width / w, sh = dimensions.height / h;
93+ img.style.width = (this.width * sw) + 'px';
94+ img.style.height = (this.height * sh) + 'px';
95+ img.style.left = (- pos._0 * sw) + 'px';
96+ img.style.top = (- pos._1 * sh) + 'px';
97+ };
98+ img.src = src;
99+ img.name = src;
100+ addTo(e,img);
101+ return e;
102+}
103+
104+function goIn(e) { e.style.position = 'absolute'; return e; }
105+function goDown(e) { return e }
106+function goRight(e) { e.style.styleFloat = e.style.cssFloat = "left"; return e; }
107+function flowWith(f, array) {
108+ var container = newElement('div');
109+ for (var i = array.length; i--; ) {
110+ addTo(container, f(render(array[i])));
111+ }
112+ return container;
113+}
114+
115+function flow(dir,elist) {
116+ var array = JS.fromList(elist);
117+ switch(dir) {
118+ case "DDown": array.reverse();
119+ case "DUp": return flowWith(goDown,array);
120+ case "DRight": array.reverse();
121+ case "DLeft": return flowWith(goRight,array);
122+ case "DOut": array.reverse();
123+ case "DIn": return flowWith(goIn,array);
124+ }
125+}
126+
127+function toPos(pos) {
128+ switch(pos[0]) {
129+ case "Absolute": return pos[1] + "px";
130+ case "Relative": return (pos[1] * 100) + "%";
131+ }
132+}
133+
134+function addTransform(style, trans) {
135+ style.transform = trans;
136+ style.msTransform = trans;
137+ style.MozTransform = trans;
138+ style.webkitTransform = trans;
139+ style.OTransform = trans;
140+}
141+
142+function removeTransform(style) {
143+ style.transform = 'none';
144+ style.msTransform = 'none';
145+ style.MozTransform = 'none';
146+ style.webkitTransform = 'none';
147+ style.OTransform = 'none';
148+}
149+
150+function setPos(pos,w,h,e) {
151+ e.style.position = 'absolute';
152+ e.style.margin = 'auto';
153+ var transform = '';
154+ switch(pos.horizontal) {
155+ case 'P': e.style.right = toPos(pos.x); break;
156+ case 'Z': transform = 'translateX(' + ((-w/2)|0) + 'px) ';
157+ case 'N': e.style.left = toPos(pos.x); break;
158+ }
159+ switch(pos.vertical) {
160+ case 'N': e.style.bottom = toPos(pos.x); break;
161+ case 'Z': transform += 'translateY(' + ((-h/2)|0) + 'px)';
162+ case 'P': e.style.top = toPos(pos.x); break;
163+ }
164+ if (transform !== '') addTransform(e.style, transform);
165+ return e;
166+}
167+
168+function container(pos,elem) {
169+ var e = render(elem);
170+ setPos(pos, elem.props.width, elem.props.height, e);
171+ var div = newElement('div');
172+ div.style.position = 'relative';
173+ div.style.overflow = 'hidden';
174+ addTo(div,e);
175+ return div;
176+}
177+
178+function rawHtml(html) {
179+ var e = newElement('div');
180+ e.innerHTML = html;
181+ return e;
182+}
183+
184+function render(elem) { return setProps(elem.props, makeElement(elem)); }
185+function makeElement(e) {
186+ switch(e.element.ctor) {
187+ case 'Image': return image(e.props, e.element);
188+ case 'Flow': return flow(e.element._0, e.element._1);
189+ case 'Container': return container(e.element._0, e.element._1);
190+ case 'Spacer': return newElement('div');
191+ case 'RawHtml': return rawHtml(e.element._0);
192+ case 'DomNode': return e.element._0;
193+ }
194+}
195+
196+function update(node, curr, next) {
197+ if (node.tagName === 'A') { node = node.firstChild; }
198+ if (curr.props.id === next.props.id) return false;
199+ if (curr.element.ctor !== next.element.ctor) {
200+ node.parentNode.replaceChild(render(next),node);
201+ return true;
202+ }
203+ var nextE = next.element, currE = curr.element;
204+ switch(nextE.ctor) {
205+ case "Spacer": break;
206+ case "RawHtml": if (nextE._0 !== currE._0) node.innerHTML = nextE._0; break;
207+ case "Image":
208+ if (nextE._0.ctor === 'Plain') {
209+ if (nextE._3 !== currE._3) node.src = nextE._3;
210+ } else if (!Value.eq(nextE,currE) ||
211+ next.props.width !== curr.props.width ||
212+ next.props.height !== curr.props.height) {
213+ node.parentNode.replaceChild(render(next),node);
214+ return true;
215+ }
216+ break;
217+ case "Flow":
218+ if (nextE._0.ctor !== currE._0.ctor) {
219+ node.parentNode.replaceChild(render(next),node);
220+ return true;
221+ }
222+ var nexts = nextE._1;
223+ var kids = node.childNodes;
224+ if (nexts.length !== kids.length) {
225+ node.parentNode.replaceChild(render(next),node);
226+ return true;
227+ }
228+ var currs = currE._1;
229+ var goDir = function(x) { return x; };
230+ switch(nextE[1][0]) {
231+ case "DDown": case "DUp": goDir = goDown; break;
232+ case "DRight": case "DLeft": goDir = goRight; break;
233+ case "DOut": case "DIn": goDir = goIn; break;
234+ }
235+ for (var i = kids.length; i-- ;) {
236+ update(kids[i],currs[i],nexts[i]);
237+ goDir(kids[i]);
238+ }
239+ break;
240+ case "Container":
241+ var inner = node.firstChild;
242+ if (!update(inner, currE._1, nextE._1)) {
243+ if (nextE._0.horizontal.ctor !== currE._0.horizontal.ctor) {
244+ inner.style.left = inner.style.right = 'none';
245+ removeTransform(inner.style);
246+ }
247+ if (nextE._0.vertical.ctor !== currE._0.vertical.ctor) {
248+ inner.style.top = inner.style.bottom = 'none';
249+ removeTransform(inner.style);
250+ }
251+ }
252+ setPos(nextE._0, next.props.width, next.props.height, node.firstChild);
253+ break;
254+ case "DomNode":
255+ if (next._0 !== curr._0) node.parentNode.replaceChild(render(next),node);
256+ break;
257+ }
258+ var props = next.props, currP = curr.props;
259+ if (props.width !== currP.width) e.style.width = (props.width |0) + 'px';
260+ if (props.height !== currP.height) e.style.height = (props.height|0) + 'px';
261+ if (props.opacity !== 1 && props.opacity !== currP.opacity) {
262+ e.style.opacity = props.opacity;
263+ }
264+ var nextColor = (props.color.ctor === 'Just' ?
265+ Elm.Color.extract(props.color._0) : 'transparent');
266+ if (e.style.backgroundColor !== nextColor) e.style.backgroundColor = nextColor;
267+ if (props.tag !== currP.tag) { e.id = props.tag; }
268+ if (props.href !== currP.href) {
269+ if (currP.href === '') {
270+ var a = newElement('a');
271+ a.href = props.href;
272+ addTo(a,e);
273+ e.parentNode.replaceChild(a,e);
274+ } else {
275+ node.parentNode.href = props.href;
276+ }
277+ }
278+}
279+
280+Elm.Runtime = {
281+ render:render,
282+ update:update,
283+ addTo:addTo,
284+ newElement:newElement
285+};
286+
287+}())