@@ -1,303 +1,303 @@
1Elm.Native.Graphics.Input = {};
1Elm.Native.Graphics.Input = {};
2Elm.Native.Graphics.Input.make = function(elm) {
2Elm.Native.Graphics.Input.make = function(elm) {
4− elm.Native = elm.Native || {};
4+ elm.Native = elm.Native || {};
5− elm.Native.Graphics = elm.Native.Graphics || {};
5+ elm.Native.Graphics = elm.Native.Graphics || {};
6− elm.Native.Graphics.Input = elm.Native.Graphics.Input || {};
6+ elm.Native.Graphics.Input = elm.Native.Graphics.Input || {};
7− if (elm.Native.Graphics.Input.values) return elm.Native.Graphics.Input.values;
7+ if (elm.Native.Graphics.Input.values) return elm.Native.Graphics.Input.values;
9− var Render = ElmRuntime.use(ElmRuntime.Render.Element);
9+ var Render = ElmRuntime.use(ElmRuntime.Render.Element);
10− var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
10+ var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
12− var Signal = Elm.Signal.make(elm);
12+ var Signal = Elm.Signal.make(elm);
13− var newElement = Elm.Graphics.Element.make(elm).newElement;
13+ var newElement = Elm.Graphics.Element.make(elm).newElement;
14− var JS = Elm.Native.JavaScript.make(elm);
14+ var JS = Elm.Native.JavaScript.make(elm);
15− var Utils = Elm.Native.Utils.make(elm);
15+ var Utils = Elm.Native.Utils.make(elm);
16− var Tuple2 = Utils.Tuple2;
16+ var Tuple2 = Utils.Tuple2;
18− function dropDown(values) {
18+ function dropDown(values) {
19− var entries = JS.fromList(values);
19+ var entries = JS.fromList(values);
20− var events = Signal.constant(entries[0]._1);
20+ var events = Signal.constant(entries[0]._1);
22− var drop = newNode('select');
22+ var drop = newNode('select');
23− drop.style.border = '0 solid';
23+ drop.style.border = '0 solid';
24− for (var i = 0; i < entries.length; ++i) {
24+ for (var i = 0; i < entries.length; ++i) {
25− var option = newNode('option');
25+ var option = newNode('option');
26− var name = JS.fromString(entries[i]._0);
26+ var name = JS.fromString(entries[i]._0);
27− option.value = name;
27+ option.value = name;
28− option.innerHTML = name;
28+ option.innerHTML = name;
29− drop.appendChild(option);
29+ drop.appendChild(option);
31− drop.addEventListener('change', function() {
31+ drop.addEventListener('change', function() {
32− elm.notify(events.id, entries[drop.selectedIndex]._1);
32+ elm.notify(events.id, entries[drop.selectedIndex]._1);
35− var t = drop.cloneNode(true);
35+ var t = drop.cloneNode(true);
36− t.style.visibility = "hidden";
36+ t.style.visibility = "hidden";
38− elm.node.appendChild(t);
38+ elm.node.appendChild(t);
39− var style = window.getComputedStyle(t, null);
39+ var style = window.getComputedStyle(t, null);
40− var w = Math.ceil(style.getPropertyValue("width").slice(0,-2) - 0);
40+ var w = Math.ceil(style.getPropertyValue("width").slice(0,-2) - 0);
41− var h = Math.ceil(style.getPropertyValue("height").slice(0,-2) - 0);
41+ var h = Math.ceil(style.getPropertyValue("height").slice(0,-2) - 0);
42− elm.node.removeChild(t);
42+ elm.node.removeChild(t);
44− var element = A3(newElement, w, h, {
44+ var element = A3(newElement, w, h, {
45− ctor: 'Custom',
45+ ctor: 'Custom',
46− type: 'DropDown',
46+ type: 'DropDown',
47− render: function render(model) { return drop; },
47+ render: function render(model) { return drop; },
48− update: function update(node, oldModel, newModel) {},
48+ update: function update(node, oldModel, newModel) {},
49− model: {}
49+ model: {}
52− return Tuple2(Signal.constant(element), events);
52+ return Tuple2(Signal.constant(element), events);
55− function buttons(defaultValue) {
55+ function buttons(defaultValue) {
56− var events = Signal.constant(defaultValue);
56+ var events = Signal.constant(defaultValue);
58− function render(model) {
58+ function render(model) {
59− var b = newNode('button');
59+ var b = newNode('button');
60− b.style.display = 'block';
60+ b.style.display = 'block';
61− b.elmEvent = model.event;
61+ b.elmEvent = model.event;
62− function click() { elm.notify(events.id, b.elmEvent); }
62+ function click() { elm.notify(events.id, b.elmEvent); }
63− b.addEventListener('click', click);
63+ b.addEventListener('click', click);
64− b.innerHTML = model.text;
64+ b.innerHTML = model.text;
65− return b;
65+ return b;
68− function update(node, oldModel, newModel) {
68+ function update(node, oldModel, newModel) {
69− node.elmEvent = newModel.event;
69+ node.elmEvent = newModel.event;
70− var txt = newModel.text;
70+ var txt = newModel.text;
71− if (oldModel.text !== txt) node.innerHTML = txt;
71+ if (oldModel.text !== txt) node.innerHTML = txt;
74− function button(evnt, txt) {
74+ function button(evnt, txt) {
75− return A3(newElement, 100, 40, {
75+ return A3(newElement, 100, 40, {
76− ctor: 'Custom',
76+ ctor: 'Custom',
77− type: 'Button',
77+ type: 'Button',
78− render: render,
78+ render: render,
79− update: update,
79+ update: update,
80− model: { event:evnt, text:JS.fromString(txt) }
80+ model: { event:evnt, text:JS.fromString(txt) }
84− return { _:{}, button:F2(button), events:events };
84+ return { _:{}, button:F2(button), events:events };
87− function customButtons(defaultValue) {
87+ function customButtons(defaultValue) {
88− var events = Signal.constant(defaultValue);
88+ var events = Signal.constant(defaultValue);
90− function render(model) {
90+ function render(model) {
91− var btn = newNode('div');
91+ var btn = newNode('div');
92− btn.elmEvent = model.event;
92+ btn.elmEvent = model.event;
94− btn.elmUp = Render.render(model.up);
94+ btn.elmUp = Render.render(model.up);
95− btn.elmHover = Render.render(model.hover);
95+ btn.elmHover = Render.render(model.hover);
96− btn.elmDown = Render.render(model.down);
96+ btn.elmDown = Render.render(model.down);
98− function replace(node) {
98+ function replace(node) {
99− if (node !== btn.firstChild) btn.replaceChild(node, btn.firstChild);
99+ if (node !== btn.firstChild) btn.replaceChild(node, btn.firstChild);
101− var overCount = 0;
101+ var overCount = 0;
102− function over(e) {
102+ function over(e) {
103− if (overCount++ > 0) return;
103+ if (overCount++ > 0) return;
104− replace(btn.elmHover);
104+ replace(btn.elmHover);
106− function out(e) {
106+ function out(e) {
107− if (btn.contains(e.toElement || e.relatedTarget)) return;
107+ if (btn.contains(e.toElement || e.relatedTarget)) return;
108− overCount = 0;
108+ overCount = 0;
109− replace(btn.elmUp);
109+ replace(btn.elmUp);
111− function up() {
111+ function up() {
112− replace(btn.elmHover);
112+ replace(btn.elmHover);
113− elm.notify(events.id, btn.elmEvent);
113+ elm.notify(events.id, btn.elmEvent);
115− function down() { replace(btn.elmDown); }
115+ function down() { replace(btn.elmDown); }
116− btn.addEventListener('mouseover', over);
116+ btn.addEventListener('mouseover', over);
117− btn.addEventListener('mouseout' , out);
117+ btn.addEventListener('mouseout' , out);
118− btn.addEventListener('mousedown', down);
118+ btn.addEventListener('mousedown', down);
119− btn.addEventListener('mouseup' , up);
119+ btn.addEventListener('mouseup' , up);
121− btn.appendChild(btn.elmUp);
121+ btn.appendChild(btn.elmUp);
123− var clicker = newNode('div');
123+ var clicker = newNode('div');
124− clicker.style.width = btn.elmUp.style.width;
124+ clicker.style.width = btn.elmUp.style.width;
125− clicker.style.height = btn.elmUp.style.height;
125+ clicker.style.height = btn.elmUp.style.height;
126− clicker.style.position = 'absolute';
126+ clicker.style.position = 'absolute';
127− clicker.style.top = 0;
127+ clicker.style.top = 0;
128− btn.appendChild(clicker);
128+ btn.appendChild(clicker);
130− return btn;
130+ return btn;
133− function update(node, oldModel, newModel) {
133+ function update(node, oldModel, newModel) {
134− node.elmEvent = newModel.event;
134+ node.elmEvent = newModel.event;
135− Render.update(node.elmUp, oldModel.up, newModel.up)
135+ Render.update(node.elmUp, oldModel.up, newModel.up)
136− Render.update(node.elmHover, oldModel.hover, newModel.hover)
136+ Render.update(node.elmHover, oldModel.hover, newModel.hover)
137− Render.update(node.elmDown, oldModel.down, newModel.down)
137+ Render.update(node.elmDown, oldModel.down, newModel.down)
140− function button(evnt, up, hover, down) {
140+ function button(evnt, up, hover, down) {
141− return A3(newElement,
141+ return A3(newElement,
142− Math.max(up.props.width, hover.props.width, down.props.width),
142+ Math.max(up.props.width, hover.props.width, down.props.width),
143− Math.max(up.props.height, hover.props.height, down.props.height),
143+ Math.max(up.props.height, hover.props.height, down.props.height),
144− { ctor: 'Custom',
144+ { ctor: 'Custom',
145− type: 'CustomButton',
145+ type: 'CustomButton',
146− render: render,
146+ render: render,
147− update: update,
147+ update: update,
148− model: { event:evnt, up:up, hover:hover, down:down }
148+ model: { event:evnt, up:up, hover:hover, down:down }
152− return { _:{}, customButton:F4(button), events:events };
152+ return { _:{}, customButton:F4(button), events:events };
156− function hoverables(defaultValue) {
156+ function hoverables(defaultValue) {
157− var events = Signal.constant(defaultValue);
157+ var events = Signal.constant(defaultValue);
158− function hoverable(handler, elem) {
158+ function hoverable(handler, elem) {
159− function onHover(bool) {
159+ function onHover(bool) {
160− elm.notify(events.id, handler(bool));
160+ elm.notify(events.id, handler(bool));
162− var props = Utils.replace([['hover',onHover]], elem.props);
162+ var props = Utils.replace([['hover',onHover]], elem.props);
163− return { props:props, element:elem.element };
163+ return { props:props, element:elem.element };
165− return { _:{}, hoverable:F2(hoverable), events:events };
165+ return { _:{}, hoverable:F2(hoverable), events:events };
169− function checkboxes(defaultValue) {
169+ function checkboxes(defaultValue) {
170− var events = Signal.constant(defaultValue);
170+ var events = Signal.constant(defaultValue);
172− function render(model) {
172+ function render(model) {
173− var b = newNode('input');
173+ var b = newNode('input');
174− b.type = 'checkbox';
174+ b.type = 'checkbox';
175− b.checked = model.checked;
175+ b.checked = model.checked;
176− b.style.display = 'block';
176+ b.style.display = 'block';
177− b.elmHandler = model.handler;
177+ b.elmHandler = model.handler;
178− function change() { elm.notify(events.id, b.elmHandler(b.checked)); }
178+ function change() { elm.notify(events.id, b.elmHandler(b.checked)); }
179− b.addEventListener('change', change);
179+ b.addEventListener('change', change);
180− return b;
180+ return b;
183− function update(node, oldModel, newModel) {
183+ function update(node, oldModel, newModel) {
184− node.elmHandler = newModel.handler;
184+ node.elmHandler = newModel.handler;
185− node.checked = newModel.checked;
185+ node.checked = newModel.checked;
186− return true;
186+ return true;
189− function box(handler, checked) {
189+ function box(handler, checked) {
190− return A3(newElement, 13, 13, {
190+ return A3(newElement, 13, 13, {
191− ctor: 'Custom',
191+ ctor: 'Custom',
192− type: 'CheckBox',
192+ type: 'CheckBox',
193− render: render,
193+ render: render,
194− update: update,
194+ update: update,
195− model: { checked:checked, handler:handler }
195+ model: { checked:checked, handler:handler }
199− return { _:{}, checkbox:F2(box), events:events };
199+ return { _:{}, checkbox:F2(box), events:events };
202− function setRange(node, start, end, dir) {
202+ function setRange(node, start, end, dir) {
203− if (node.parentNode) {
203+ if (node.parentNode) {
204− node.setSelectionRange(start, end, dir);
204+ node.setSelectionRange(start, end, dir);
205− } else {
205+ } else {
206− setTimeout(function(){node.setSelectionRange(start, end, dir);}, 0);
206+ setTimeout(function(){node.setSelectionRange(start, end, dir);}, 0);
210− function mkTextPool(type) { return function fields(defaultValue) {
210+ function mkTextPool(type) { return function fields(defaultValue) {
211− var events = Signal.constant(defaultValue);
211+ var events = Signal.constant(defaultValue);
213− var state = null;
213+ var state = null;
215− function render(model) {
215+ function render(model) {
216− var field = newNode('input');
216+ var field = newNode('input');
217− field.elmHandler = model.handler;
217+ field.elmHandler = model.handler;
219− field.id = 'test';
219+ field.id = 'test';
220− field.type = type;
220+ field.type = type;
221− field.placeholder = JS.fromString(model.placeHolder);
221+ field.placeholder = JS.fromString(model.placeHolder);
222− field.value = JS.fromString(model.state.string);
222+ field.value = JS.fromString(model.state.string);
223− setRange(field, model.state.selectionStart, model.state.selectionEnd, 'forward');
223+ setRange(field, model.state.selectionStart, model.state.selectionEnd, 'forward');
224− field.style.border = 'none';
224+ field.style.border = 'none';
225− state = model.state;
225+ state = model.state;
227− function update() {
227+ function update() {
228− var start = field.selectionStart,
228+ var start = field.selectionStart,
229− end = field.selectionEnd;
229+ end = field.selectionEnd;
230− if (field.selectionDirection === 'backward') {
230+ if (field.selectionDirection === 'backward') {
231− start = end;
231+ start = end;
232− end = field.selectionStart;
232+ end = field.selectionStart;
234− state = { _:{},
234+ state = { _:{},
235− string:JS.toString(field.value),
235+ string:JS.toString(field.value),
236− selectionStart:start,
236+ selectionStart:start,
237− selectionEnd:end };
237+ selectionEnd:end };
238− elm.notify(events.id, field.elmHandler(state));
238+ elm.notify(events.id, field.elmHandler(state));
240− function mousedown() {
240+ function mousedown() {
241− update();
241+ update();
242− elm.node.addEventListener('mouseup', mouseup);
242+ elm.node.addEventListener('mouseup', mouseup);
244− function mouseup() {
244+ function mouseup() {
245− update();
245+ update();
246− elm.node.removeEventListener('mouseup', mouseup)
246+ elm.node.removeEventListener('mouseup', mouseup)
248− field.addEventListener('keyup', update);
248+ field.addEventListener('keyup', update);
249− field.addEventListener('mousedown', mousedown);
249+ field.addEventListener('mousedown', mousedown);
251− return field;
251+ return field;
254− function update(node, oldModel, newModel) {
254+ function update(node, oldModel, newModel) {
255− node.elmHandler = newModel.handler;
255+ node.elmHandler = newModel.handler;
256− if (state === newModel.state) return;
256+ if (state === newModel.state) return;
257− var newStr = JS.fromString(newModel.state.string);
257+ var newStr = JS.fromString(newModel.state.string);
258− if (node.value !== newStr) node.value = newStr;
258+ if (node.value !== newStr) node.value = newStr;
260− var start = newModel.state.selectionStart;
260+ var start = newModel.state.selectionStart;
261− var end = newModel.state.selectionEnd;
261+ var end = newModel.state.selectionEnd;
262− var direction = 'forward';
262+ var direction = 'forward';
263− if (end < start) {
263+ if (end < start) {
264− start = end;
264+ start = end;
265− end = newModel.state.selectionStart;
265+ end = newModel.state.selectionStart;
266− direction = 'backward';
266+ direction = 'backward';
269− if (node.selectionStart !== start
269+ if (node.selectionStart !== start
270− || node.selectionEnd !== end
270+ || node.selectionEnd !== end
271− || node.selectionDirection !== direction) {
271+ || node.selectionDirection !== direction) {
272− setRange(node, start, end, direction);
272+ setRange(node, start, end, direction);
276− function field(handler, placeHolder, state) {
276+ function field(handler, placeHolder, state) {
277− return A3(newElement, 200, 30,
277+ return A3(newElement, 200, 30,
278− { ctor: 'Custom',
278+ { ctor: 'Custom',
279− type: type + 'Input',
279+ type: type + 'Input',
280− render: render,
280+ render: render,
281− update: update,
281+ update: update,
282− model: { handler:handler,
282+ model: { handler:handler,
283− placeHolder:placeHolder,
283+ placeHolder:placeHolder,
284− state:state }
284+ state:state }
288− return { _:{}, field:F3(field), events:events };
288+ return { _:{}, field:F3(field), events:events };
292− return elm.Native.Graphics.Input.values = {
292+ return elm.Native.Graphics.Input.values = {
293− buttons:buttons,
293+ buttons:buttons,
294− customButtons:customButtons,
294+ customButtons:customButtons,
295− hoverables:hoverables,
295+ hoverables:hoverables,
296− checkboxes:checkboxes,
296+ checkboxes:checkboxes,
297− fields:mkTextPool('text'),
297+ fields:mkTextPool('text'),
298− emails:mkTextPool('email'),
298+ emails:mkTextPool('email'),
299− passwords:mkTextPool('password'),
299+ passwords:mkTextPool('password'),
300− dropDown:dropDown
300+ dropDown:dropDown