1Elm.Native.Graphics.Input = {};
2Elm.Native.Graphics.Input.make = function(elm) {
4 elm.Native = elm.Native || {};
5 elm.Native.Graphics = elm.Native.Graphics || {};
6 elm.Native.Graphics.Input = elm.Native.Graphics.Input || {};
7 if (elm.Native.Graphics.Input.values) return elm.Native.Graphics.Input.values;
9 var Render = ElmRuntime.use(ElmRuntime.Render.Element);
10 var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
12 var Signal = Elm.Signal.make(elm);
13 var newElement = Elm.Graphics.Element.make(elm).newElement;
14 var JS = Elm.Native.JavaScript.make(elm);
15 var Utils = Elm.Native.Utils.make(elm);
16 var Tuple2 = Utils.Tuple2;
18 function input(initialValue) {
19 var signal = Signal.constant(initialValue);
20 return { _:{}, signal:signal, handle:signal };
23 function renderDropDown(signal, values) {
25 var entries = JS.fromList(values);
27 var drop = newNode('select');
28 drop.style.border = '0 solid';
29 for (var i = 0; i < entries.length; ++i) {
30 var option = newNode('option');
31 var name = JS.fromString(entries[i]._0);
33 option.innerHTML = name;
34 drop.appendChild(option);
36 drop.addEventListener('change', function() {
37 elm.notify(signal.id, entries[drop.selectedIndex]._1);
40 var t = drop.cloneNode(true);
41 t.style.visibility = "hidden";
43 elm.node.appendChild(t);
44 var style = window.getComputedStyle(t, null);
45 var w = Math.ceil(style.getPropertyValue("width").slice(0,-2) - 0);
46 var h = Math.ceil(style.getPropertyValue("height").slice(0,-2) - 0);
47 elm.node.removeChild(t);
52 function updateDropDown(node, oldModel, newModel) {
55 function dropDown(signal, values) {
56 return A3(newElement, 100, 24, {
59 render: renderDropDown(signal,values),
60 update: updateDropDown,
65 function renderButton(model) {
66 var node = newNode('button');
67 node.style.display = 'block';
68 node.elm_signal = model.signal;
69 node.elm_value = model.value;
71 elm.notify(node.elm_signal.id, node.elm_value);
73 node.addEventListener('click', click);
74 node.innerHTML = model.text;
78 function updateButton(node, oldModel, newModel) {
79 node.elm_signal = newModel.signal;
80 node.elm_value = nemModel.value;
81 var txt = newModel.text;
82 if (oldModel.text !== txt) node.innerHTML = txt;
85 function button(signal, value, text) {
86 return A3(newElement, 100, 40, {
91 model: { signal:signal, value:value, text:JS.fromString(text) }
95 function renderCustomButton(model) {
96 var btn = newNode('div');
97 btn.elm_signal = model.signal;
98 btn.elm_value = model.value;
100 btn.elm_up = Render.render(model.up);
101 btn.elm_hover = Render.render(model.hover);
102 btn.elm_down = Render.render(model.down);
104 function replace(node) {
105 if (node !== btn.firstChild) {
106 btn.replaceChild(node, btn.firstChild);
111 if (overCount++ > 0) return;
112 replace(btn.elm_hover);
115 if (btn.contains(e.toElement || e.relatedTarget)) return;
120 replace(btn.elm_hover);
121 elm.notify(btn.elm_signal.id, btn.elm_value);
124 replace(btn.elm_down);
126 btn.addEventListener('mouseover', over);
127 btn.addEventListener('mouseout' , out);
128 btn.addEventListener('mousedown', down);
129 btn.addEventListener('mouseup' , up);
131 btn.appendChild(btn.elm_up);
133 var clicker = newNode('div');
134 clicker.style.width = btn.elm_up.style.width;
135 clicker.style.height = btn.elm_up.style.height;
136 clicker.style.position = 'absolute';
137 clicker.style.top = 0;
138 btn.appendChild(clicker);
143 function updateCustomButton(node, oldModel, newModel) {
144 var signal = newModel.signal;
145 node.elm_up.elm_signal = signal;
146 node.elm_hover.elm_signal = signal;
147 node.elm_down.elm_signal = signal;
149 var value = newModel.value;
150 node.elm_up.elm_value = value;
151 node.elm_hover.elm_value = value;
152 node.elm_down.elm_value = value;
154 Render.update(node.elm_up, oldModel.up, newModel.up)
155 Render.update(node.elm_hover, oldModel.hover, newModel.hover)
156 Render.update(node.elm_down, oldModel.down, newModel.down)
159 function max3(a,b,c) {
160 var ab = a > b ? a : b;
161 return ab > c ? ab : c;
164 function customButton(signal, value, up, hover, down) {
165 return A3(newElement,
166 max3(up.props.width, hover.props.width, down.props.width),
167 max3(up.props.height, hover.props.height, down.props.height),
169 type: 'CustomButton',
170 render: renderCustomButton,
171 update: updateCustomButton,
172 model: { signal:signal, value:value, up:up, hover:hover, down:down }
176 function renderCheckbox(model) {
177 var node = newNode('input');
178 node.type = 'checkbox';
179 node.checked = model.checked;
180 node.style.display = 'block';
181 node.elm_signal = model.signal;
182 node.elm_handler = model.handler;
184 elm.notify(node.elm_signal.id, node.elm_handler(node.checked));
186 node.addEventListener('change', change);
190 function updateCheckbox(node, oldModel, newModel) {
191 node.elm_signal = newModel.signal;
192 node.elm_handler = newModel.handler;
193 node.checked = newModel.checked;
197 function checkbox(signal, handler, checked) {
198 return A3(newElement, 13, 13, {
201 render: renderCheckbox,
202 update: updateCheckbox,
203 model: { signal:signal, handler:handler, checked:checked }
207 function setRange(node, start, end, dir) {
208 if (node.parentNode) {
209 node.setSelectionRange(start, end, dir);
211 setTimeout(function(){node.setSelectionRange(start, end, dir);}, 0);
215 function renderField(model) {
216 var field = newNode('input');
217 field.elm_signal = model.signal;
218 field.elm_handler = model.handler;
220 field.type = model.type;
221 field.placeholder = JS.fromString(model.placeHolder);
222 field.value = JS.fromString(model.content.string);
223 var selection = model.content.selection;
224 var direction = selection.direction.ctor === 'Forward' ? 'forward' : 'backward';
225 setRange(field, selection.start, selection.end, direction);
226 field.style.border = 'none';
229 var direction = field.selectionDirection === 'backward' ? 'Backward' : 'Forward';
230 elm.notify(field.elm_signal.id, field.elm_handler({
232 string:JS.toString(field.value),
234 start:field.selectionStart,
235 end:field.selectionEnd,
236 direction: { ctor:direction }
240 function mousedown() {
242 elm.node.addEventListener('mouseup', mouseup);
246 elm.node.removeEventListener('mouseup', mouseup)
248 field.addEventListener('keyup', update);
249 field.addEventListener('mousedown', mousedown);
254 function updateField(node, oldModel, newModel) {
255 node.elmHandler = newModel.handler;
256 var newStr = JS.fromString(newModel.content.string);
257 if (node.value !== newStr) node.value = newStr;
259 var selection = newModel.content.selection;
260 var start = selection.start;
261 var end = selection.end;
262 var direction = selection.direction.ctor === 'Forward' ? 'forward' : 'backward';
265 end = selection.start;
268 if (node.selectionStart !== start
269 || node.selectionEnd !== end
270 || node.selectionDirection !== direction) {
271 setRange(node, start, end, direction);
275 function mkField(type) {
276 function field(signal, handler, placeHolder, content) {
277 return A3(newElement, 200, 30, {
279 type: type + 'Input',
285 placeHolder:placeHolder,
295 function hoverable(signal, handler, element) {
296 function onHover(bool) {
297 elm.notify(signal.id, handler(bool));
299 var props = Utils.replace([['hover',onHover]], elem.props);
300 return { props:props, element:elem.element };
303 function clickable(signal, value, element) {
304 function onClick(bool) {
305 elm.notify(signal.id, value);
307 var props = Utils.replace([['click',onClick]], elem.props);
308 return { props:props, element:elem.element };
311 return elm.Native.Graphics.Input.values = {
314 customButton:F5(customButton),
315 checkbox:F3(checkbox),
316 dropDown:F2(dropDown),
317 field:mkField('text'),
318 email:mkField('email'),
319 password:mkField('password'),
320 hoverable:F3(hoverable),
321 clickable:F3(clickable)
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