on dcbe2fc help sign in
elk/libraries/Native/Utils.js
164 lines 5.2 kB history raw
2Elm.Native.Utils = {};
3Elm.Native.Utils.make = function(elm) {
4 'use strict';
6 elm.Native = elm.Native || {};
7 if (elm.Native.Utils) return elm.Native.Utils;
9 function eq(x,y) {
10 if (x === y) return true;
11 if (typeof x === "object") {
12 var c = 0;
13 for (var i in x) { ++c; if (!eq(x[i],y[i])) return false; }
14 return c === Object.keys(y).length;
15 }
16 if (typeof x === 'function') {
17 throw new Error('Equality error: general function equality is ' +
18 'undecidable, and therefore, unsupported');
19 }
20 return x === y;
21 }
23 // code in Generate/JavaScript.hs depends on the particular
24 // integer values assigned to LT, EQ, and GT
25 var LT = -1, EQ = 0, GT = 1, ord = ['LT','EQ','GT'];
26 function compare(x,y) { return { ctor: ord[cmp(x,y)+1] } }
27 function cmp(x,y) {
28 var ord;
29 if (typeof x !== 'object') return x === y ? EQ : x < y ? LT : GT;
31 if (x.ctor === "::" || x.ctor === "[]") {
32 while (true) {
33 if (x.ctor === "[]" && y.ctor === "[]") return EQ;
34 if (x.ctor !== y.ctor) return x.ctor === '[]' ? LT : GT;
35 ord = cmp(x._0, y._0);
36 if (ord !== EQ) return ord;
37 x = x._1;
38 y = y._1;
39 }
40 }
42 if (x.ctor.slice(0,6) === '_Tuple') {
43 var n = x.ctor.slice(6) - 0;
44 var err = 'cannot compare tuples with more than 6 elements.';
45 if (n === 0) return EQ;
46 if (n >= 1) { ord = cmp(x._0, y._0); if (ord !== EQ) return ord;
47 if (n >= 2) { ord = cmp(x._1, y._1); if (ord !== EQ) return ord;
48 if (n >= 3) { ord = cmp(x._2, y._2); if (ord !== EQ) return ord;
49 if (n >= 4) { ord = cmp(x._3, y._3); if (ord !== EQ) return ord;
50 if (n >= 5) { ord = cmp(x._4, y._4); if (ord !== EQ) return ord;
51 if (n >= 6) { ord = cmp(x._5, y._5); if (ord !== EQ) return ord;
52 if (n >= 7) throw new Error('Comparison error: ' + err); } } } } } }
53 return EQ;
54 }
55 throw new Error('Comparison error: comparison is only defined on ints, ' +
56 'floats, times, chars, strings, lists of comparable values, ' +
57 'and tuples of comparable values.')
58 }
61 var Tuple0 = { ctor: "_Tuple0" };
62 function Tuple2(x,y) { return { ctor:"_Tuple2", _0:x, _1:y } }
64 var count = 0;
65 function guid(_) { return count++ }
67 function copy(r) {
68 var o = {};
69 for (var i in r) { o[i] = r[i]; }
70 return o;
71 }
73 function remove(x,r) {
74 var o = copy(r);
75 if (x in o._) {
76 o[x] = o._[x][0];
77 o._[x] = o._[x].slice(1);
78 if (o._[x].length === 0) { delete o._[x]; }
79 } else {
80 delete o[x];
81 }
82 return o;
83 }
85 function replace(kvs,r) {
86 var o = copy(r);
87 for (var i = kvs.length; i--; ) {
88 var kvsi = kvs[i];
89 o[kvsi[0]] = kvsi[1];
90 }
91 return o;
92 }
94 function insert(x,v,r) {
95 var o = copy(r);
96 if (x in o) o._[x] = [o[x]].concat(x in o._ ? o._[x].slice(0) : []);
97 o[x] = v;
98 return o;
99 }
101 function max(a,b) { return a > b ? a : b }
102 function min(a,b) { return a < b ? a : b }
104 function mod(a,b) {
105 if (b === 0) {
106 throw new Error("Cannot perform mod 0. Division by zero error.");
107 }
108 var r = a % b;
109 var m = a === 0 ? 0 : (b > 0 ? (a >= 0 ? r : r+b) : -mod(-a,-b));
111 return m === b ? 0 : m;
112 }
114 function htmlHeight(width, html) {
115 var t = document.createElement('div');
116 t.innerHTML = html;
117 if (width > 0) { t.style.width = width + "px"; }
118 t.style.visibility = "hidden";
119 t.style.styleFloat = "left";
120 t.style.cssFloat = "left";
122 document.body.appendChild(t);
123 var style = window.getComputedStyle(t, null);
124 var w = Math.ceil(style.getPropertyValue("width").slice(0,-2) - 0);
125 var h = Math.ceil(style.getPropertyValue("height").slice(0,-2) - 0);
126 document.body.removeChild(t);
127 return Tuple2(w,h);
128 }
130 function adjustOffset() {
131 var node = elm.node;
132 var offsetX = 0, offsetY = 0;
133 if (node.offsetParent) {
134 do {
135 offsetX += node.offsetLeft;
136 offsetY += node.offsetTop;
137 } while (node = node.offsetParent);
138 }
139 elm.node.offsetX = offsetX;
140 elm.node.offsetY = offsetY;
141 }
143 if (elm.display === ElmRuntime.Display.COMPONENT) {
144 elm.addListener(elm.inputs, elm.node, 'mouseover', adjustOffset);
145 }
147 return elm.Native.Utils = {
148 eq:eq,
149 cmp:cmp,
150 compare:F2(compare),
151 Tuple0:Tuple0,
152 Tuple2:Tuple2,
153 copy: copy,
154 remove: remove,
155 replace: replace,
156 insert: insert,
157 guid: guid,
158 max : F2(max),
159 min : F2(min),
160 mod : F2(mod),
161 htmlHeight: F2(htmlHeight),
162 toFloat: function(x){return x}
163 };
164};