on 104faf1 help sign in
elk/libraries/Native/Utils.js
130 lines 3.5 kB history raw
2Elm.Native.Utils = function(elm) {
3 'use strict';
5 elm.Native = elm.Native || {};
6 if (elm.Native.Utils) return elm.Native.Utils;
8 function eq(x,y) {
9 if (x === y) return true;
10 if (typeof x === "object") {
11 var c = 0;
12 for (var i in x) { ++c; if (!eq(x[i],y[i])) return false; }
13 return c === Object.keys(y).length;
14 }
15 if (typeof x === 'function') {
16 throw new Error('Equality error: general function equality is ' +
17 'undecidable, and therefore, unsupported');
18 }
19 return x === y;
20 }
22 var EQ = 0, LT = 1, GT = 2, ord = ['EQ','LT','GT'];
23 function compare(x,y) { return { ctor: ord[cmp(x,y)] } }
24 function cmp(x,y) {
25 if (typeof x !== 'object') return x === y ? EQ : x < y ? LT : GT;
27 if (x.ctor === "Cons" || x.ctor === "Nil") {
28 while (true) {
29 if (x.ctor === "Nil" && y.ctor === "Nil") return EQ;
30 if (x.ctor !== y.ctor) return {ctor: x.ctor==='Nil'?LT:GT};
31 var ord = cmp(x._0, y._0);
32 if (ord !== EQ) return ord;
33 x = x._1;
34 y = y._1;
35 }
36 }
37 if (x.ctor.slice(0,5) === 'Tuple') {
38 var n = x.ctor.slice(5) - 0;
39 var err = 'cannot compare tuples with more than 6 elements.';
40 if (n === 0) return EQ;
41 if (n >= 1) { ord = cmp(x._0, y._0); if (ord !== EQ) return ord;
42 if (n >= 2) { ord = cmp(x._1, y._1); if (ord !== EQ) return ord;
43 if (n >= 3) { ord = cmp(x._2, y._2); if (ord !== EQ) return ord;
44 if (n >= 4) { ord = cmp(x._3, y._3); if (ord !== EQ) return ord;
45 if (n >= 5) { ord = cmp(x._4, y._4); if (ord !== EQ) return ord;
46 if (n >= 6) { ord = cmp(x._5, y._5); if (ord !== EQ) return ord;
47 if (n >= 7) throw new Error('Comparison error: ' + err); } } } } } }
48 return EQ;
49 }
50 throw new Error('Comparison error: comparison is only defined on ints, ' +
51 'floats, times, chars, strings, lists of comparable values, ' +
52 'and tuples of comparable values.')
53 }
56 var Tuple0 = { ctor: "Tuple0" };
57 function Tuple2(x,y) { return { ctor:"Tuple2", _0:x, _1:y } }
59 var count = 0;
60 function guid(_) { return count++ }
62 function copy(r) {
63 var o = {};
64 for (var i in r) { o[i] = r[i]; }
65 return o;
66 }
68 function remove(x,r) {
69 var o = copy(r);
70 if (x in o._) {
71 o[x] = o._[x][0];
72 o._[x] = o._[x].slice(1);
73 if (o._[x].length === 0) { delete o._[x]; }
74 } else {
75 delete o[x];
76 }
77 return o;
78 }
80 function replace(kvs,r) {
81 var o = copy(r);
82 for (var i = kvs.length; i--; ) {
83 var kvsi = kvs[i];
84 o[kvsi[0]] = kvsi[1];
85 }
86 return o;
87 }
89 function insert(x,v,r) {
90 var o = copy(r);
91 if (x in o) o._[x] = [o[x]].concat(x in o._ ? o._[x].slice(0) : []);
92 o[x] = v;
93 return o;
94 }
96 function max(a,b) { return a > b ? a : b }
97 function min(a,b) { return a < b ? a : b }
99 function htmlHeight(width, html) {
100 var t = document.createElement('div');
101 t.innerHTML = html;
102 if (width > 0) { t.style.width = width + "px"; }
103 t.style.visibility = "hidden";
104 t.style.styleFloat = "left";
105 t.style.cssFloat = "left";
107 elm.node.appendChild(t);
108 var w = t.clientWidth;
109 var h = t.clientHeight;
110 elm.node.removeChild(t);
111 return Tuple2(w,h);
112 }
114 return elm.Native.Utils = {
115 eq:eq,
116 cmp:compare,
117 compare:F2(compare),
118 Tuple0:Tuple0,
119 Tuple2:Tuple2,
120 copy: copy,
121 remove: remove,
122 replace: replace,
123 insert: insert,
124 guid: guid,
125 max : F2(max),
126 min : F2(min),
127 htmlHeight: F2(htmlHeight),
128 toFloat: function(x){return x}
129 };
130};