2Elm.Native.Graphics.Input = function(elm) {
5 elm.Native = elm.Native || {};
6 elm.Native.Graphics = elm.Native.Graphics || {};
7 if (elm.Native.Graphics.Input) return elm.Native.Graphics.Input;
9 var Render = ElmRuntime.use(ElmRuntime.Render.Element);
10 var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
12 var Signal = Elm.Signal(elm);
13 var newElement = Elm.Graphics.Element(elm).newElement;
14 var JS = Elm.Native.JavaScript(elm);
15 var Tuple2 = Elm.Native.Utils(elm).Tuple2;
17 function dropDown(values) {
18 var entries = JS.fromList(values);
19 var events = Signal.constant(entries[0]._1);
21 var drop = newNode('select');
22 drop.style.border = '0 solid';
23 for (var i = 0; i < entries.length; ++i) {
24 var option = newNode('option');
25 var name = JS.fromString(entries[i]._0);
27 option.innerHTML = name;
28 drop.appendChild(option);
30 drop.addEventListener('change', function() {
31 elm.notify(events.id, entries[drop.selectedIndex]._1);
34 var t = drop.cloneNode(true);
35 t.style.visibility = "hidden";
37 elm.node.appendChild(t);
38 var style = window.getComputedStyle(t, null);
39 var w = Math.ceil(style.getPropertyValue("width").slice(0,-2) - 0);
40 var h = Math.ceil(style.getPropertyValue("height").slice(0,-2) - 0);
41 elm.node.removeChild(t);
44 var element = A3(newElement, w, h, {
47 render: function render(model) { return drop; },
48 update: function update(node, oldModel, newModel) {},
52 return Tuple2(Signal.constant(element), events);
55 function buttons(defaultValue) {
56 var events = Signal.constant(defaultValue);
58 function render(model) {
59 var b = newNode('button');
60 b.style.display = 'block';
61 b.elmEvent = model.event;
62 function click() { elm.notify(events.id, b.elmEvent); }
63 b.addEventListener('click', click);
64 b.innerHTML = model.text;
68 function update(node, oldModel, newModel) {
69 node.elmEvent = newModel.event;
70 var txt = newModel.text;
71 if (oldModel.text !== txt) node.innerHTML = txt;
74 function button(evnt, txt) {
75 return A3(newElement, 100, 40, {
80 model: { event:evnt, text:JS.fromString(txt) }
84 return { _:{}, button:F2(button), events:events };
87 function customButtons(defaultValue) {
88 var events = Signal.constant(defaultValue);
90 function render(model) {
91 var btn = newNode('div');
92 btn.elmEvent = model.event;
94 btn.elmUp = Render.render(model.up);
95 btn.elmHover = Render.render(model.hover);
96 btn.elmDown = Render.render(model.down);
98 function replace(node) {
99 if (node !== btn.firstChild) btn.replaceChild(node, btn.firstChild);
103 if (overCount++ > 0) return;
104 replace(btn.elmHover);
107 if (btn.contains(e.toElement || e.relatedTarget)) return;
112 replace(btn.elmHover);
113 elm.notify(events.id, btn.elmEvent);
115 function down() { replace(btn.elmDown); }
116 btn.addEventListener('mouseover', over);
117 btn.addEventListener('mouseout' , out);
118 btn.addEventListener('mousedown', down);
119 btn.addEventListener('mouseup' , up);
121 btn.appendChild(btn.elmUp);
125 function update(node, oldModel, newModel) {
126 node.elmEvent = newModel.event;
127 Render.update(node.elmUp, oldModel.up, newModel.up)
128 Render.update(node.elmHover, oldModel.hover, newModel.hover)
129 Render.update(node.elmDown, oldModel.down, newModel.down)
132 function button(evnt, up, hover, down) {
133 return A3(newElement,
134 Math.max(up.props.width, hover.props.width, down.props.width),
135 Math.max(up.props.height, hover.props.height, down.props.height),
137 type: 'CustomButton',
140 model: { event:evnt, up:up, hover:hover, down:down }
144 return { _:{}, customButton:F4(button), events:events };
148 function checkboxes(defaultValue) {
149 var events = Signal.constant(defaultValue);
151 function render(model) {
152 var b = newNode('input');
154 b.checked = model.checked;
155 b.style.display = 'block';
156 b.elmHandler = model.handler;
157 function change() { elm.notify(events.id, b.elmHandler(b.checked)); }
158 b.addEventListener('change', change);
162 function update(node, oldModel, newModel) {
163 node.elmHandler = newModel.handler;
164 node.checked = newModel.checked;
168 function box(handler, checked) {
169 return A3(newElement, 13, 13, {
174 model: { checked:checked, handler:handler }
178 return { _:{}, box:F2(box), events:events };
181 function setRange(node, start, end, dir) {
182 if (node.parentNode) {
183 node.setSelectionRange(start, end, dir);
185 setTimeout(function(){node.setSelectionRange(start, end, dir);}, 0);
189 function mkTextPool(type) { return function fields(defaultValue) {
190 var events = Signal.constant(defaultValue);
194 function render(model) {
195 var field = newNode('input');
196 field.elmHandler = model.handler;
200 field.placeholder = JS.fromString(model.placeHolder);
201 field.value = JS.fromString(model.state.string);
202 setRange(field, model.state.selectionStart, model.state.selectionEnd, 'forward');
203 field.style.border = 'none';
207 var start = field.selectionStart,
208 end = field.selectionEnd;
209 if (field.selectionDirection === 'backward') {
211 end = field.selectionStart;
214 string:JS.toString(field.value),
215 selectionStart:start,
217 elm.notify(events.id, field.elmHandler(state));
219 function mousedown() {
221 elm.node.addEventListener('mouseup', mouseup);
225 elm.node.removeEventListener('mouseup', mouseup)
227 field.addEventListener('keyup', update);
228 field.addEventListener('mousedown', mousedown);
233 function update(node, oldModel, newModel) {
234 node.elmHandler = newModel.handler;
235 if (state === newModel.state) return;
236 var newStr = JS.fromString(newModel.state.string);
237 if (node.value !== newStr) node.value = newStr;
239 var start = newModel.state.selectionStart;
240 var end = newModel.state.selectionEnd;
241 var direction = 'forward';
244 end = newModel.state.selectionStart;
245 direction = 'backward';
248 if (node.selectionStart !== start
249 || node.selectionEnd !== end
250 || node.selectionDirection !== direction) {
251 setRange(node, start, end, direction);
255 function field(handler, placeHolder, state) {
256 return A3(newElement, 200, 30,
258 type: type + 'Input',
261 model: { handler:handler,
262 placeHolder:placeHolder,
267 return { _:{}, field:F3(field), events:events };
271 return elm.Native.Graphics.Input = {
273 customButtons:customButtons,
274 checkboxes:checkboxes,
275 fields:mkTextPool('text'),
276 emails:mkTextPool('email'),
277 passwords:mkTextPool('password'),
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list