on master help sign in
Get rid of Selection, simplifying the field API
8e2c698Evan Czaplicki
libraries/Graphics/Input/Field.elm+6−36
@@ -6,9 +6,6 @@ approach as the [`Graphics.Input`](Graphics-Input) module for describing an
6# Create Fields
6# Create Fields
7@docs field, password, email
7@docs field, password, email
8
8
9−# Field Content
10−@docs Content, Selection, Direction, noContent
11−
12# Field Style
9# Field Style
13@docs Style, Outline, noOutline, Highlight, noHighlight, Dimensions, uniformly
10@docs Style, Outline, noOutline, Highlight, noHighlight, Dimensions, uniformly
14-}
11-}
@@ -75,56 +72,29 @@ defaultStyle =
75 , style = Text.defaultStyle
72 , style = Text.defaultStyle
76 }
73 }
77
74
78−{-| Represents the current content of a text field. For example:
79−
80− Content "She sells sea shells" (Selection 0 3 Backward)
81−
82−This means the user highlighted the substring `"She"` backwards.
83−-}
84−type Content = { string:String, selection:Selection }
85−
86−{-| The selection within a text field. `start` is never greater than `end`:
87−
88− Selection 0 0 Forward -- cursor precedes all characters
89−
90− Selection 5 9 Backward -- highlighting characters starting after
91− -- the 5th and ending after the 9th
92−-}
93−type Selection = { start:Int, end:Int, direction:Direction }
94−
95−{-| The direction of selection.-}
96−data Direction = Forward | Backward
97−
98−{-| A field with no content:
99−
100− Content "" (Selection 0 0 Forward)
101−-}
102−noContent : Content
103−noContent = Content "" (Selection 0 0 Forward)
104−
105{-| Create a text field. The following example creates a time-varying element
75{-| Create a text field. The following example creates a time-varying element
106called `nameField`. As the user types their name, the field will be updated
76called `nameField`. As the user types their name, the field will be updated
107to match what they have entered.
77to match what they have entered.
108
78
109− name : Input Content
79+ name : Input String
110− name = input noContent
80+ name = input ""
111
81
112 nameField : Signal Element
82 nameField : Signal Element
113 nameField = field name.handle id defaultStyle "Name" <~ name.signal
83 nameField = field name.handle id defaultStyle "Name" <~ name.signal
114-}
84-}
115−field : Handle a -> (Content -> a) -> Style -> String -> Content -> Element
85+field : Handle a -> (String -> a) -> Style -> String -> String -> Element
116field = Native.Graphics.Input.field
86field = Native.Graphics.Input.field
117
87
118{-| Same as `field` but the UI element blocks out each characters. -}
88{-| Same as `field` but the UI element blocks out each characters. -}
119−password : Handle a -> (Content -> a) -> Style -> String -> Content -> Element
89+password : Handle a -> (String -> a) -> Style -> String -> String -> Element
120password = Native.Graphics.Input.password
90password = Native.Graphics.Input.password
121
91
122{-| Same as `field` but it adds an annotation that this field is for email
92{-| Same as `field` but it adds an annotation that this field is for email
123addresses. This is helpful for auto-complete and for mobile users who may
93addresses. This is helpful for auto-complete and for mobile users who may
124get a custom keyboard with an `@` and `.com` button.
94get a custom keyboard with an `@` and `.com` button.
125-}
95-}
126−email : Handle a -> (Content -> a) -> Style -> String -> Content -> Element
96+email : Handle a -> (String -> a) -> Style -> String -> String -> Element
127email = Native.Graphics.Input.email
97email = Native.Graphics.Input.email
128
98
129−-- area : Handle a -> (Content -> a) -> Handle b -> ((Int,Int) -> b) -> (Int,Int) -> String -> Content -> Element
99+-- area : Handle a -> (String -> a) -> Handle b -> ((Int,Int) -> b) -> (Int,Int) -> String -> String -> Element
130-- area = Native.Graphics.Input.area
100-- area = Native.Graphics.Input.area
libraries/Native/Graphics/Input.js+4−60
@@ -209,14 +209,6 @@ Elm.Native.Graphics.Input.make = function(elm) {
209 });
209 });
210 }
210 }
211
211
212− function setRange(node, start, end, dir) {
213− if (node.parentNode) {
214− node.setSelectionRange(start, end, dir);
215− } else {
216− setTimeout(function(){node.setSelectionRange(start, end, dir);}, 0);
217− }
218− }
219−
220 function updateIfNeeded(css, attribute, latestAttribute) {
212 function updateIfNeeded(css, attribute, latestAttribute) {
221 if (css[attribute] !== latestAttribute) {
213 if (css[attribute] !== latestAttribute) {
222 css[attribute] = latestAttribute;
214 css[attribute] = latestAttribute;
@@ -267,10 +259,7 @@ Elm.Native.Graphics.Input.make = function(elm) {
267
259
268 field.type = model.type;
260 field.type = model.type;
269 field.placeholder = JS.fromString(model.placeHolder);
261 field.placeholder = JS.fromString(model.placeHolder);
270− field.value = JS.fromString(model.content.string);
262+ field.value = JS.fromString(model.content);
271− var selection = model.content.selection;
272− var direction = selection.direction.ctor === 'Forward' ? 'forward' : 'backward';
273− setRange(field, selection.start, selection.end, direction);
274
263
275 field.elm_signal = model.signal;
264 field.elm_signal = model.signal;
276 field.elm_handler = model.handler;
265 field.elm_handler = model.handler;
@@ -282,15 +271,7 @@ Elm.Native.Graphics.Input.make = function(elm) {
282 String.fromCharCode(event.keyCode) +
271 String.fromCharCode(event.keyCode) +
283 curr.slice(field.selectionEnd));
272 curr.slice(field.selectionEnd));
284 var pos = field.selectionEnd + 1;
273 var pos = field.selectionEnd + 1;
285− elm.notify(field.elm_signal.id, field.elm_handler({
274+ elm.notify(field.elm_signal.id, field.elm_handler(JS.toString(next)));
286− _:{},
287− string: JS.toString(next),
288− selection: {
289− start: pos,
290− end: pos,
291− direction: { ctor:'Forward' }
292− },
293− }));
294 event.preventDefault();
275 event.preventDefault();
295 }
276 }
296
277
@@ -300,46 +281,12 @@ Elm.Native.Graphics.Input.make = function(elm) {
300 if (curr === next) {
281 if (curr === next) {
301 return;
282 return;
302 }
283 }
303−
304− var direction = field.selectionDirection === 'forward' ? 'Forward' : 'Backward';
305− var start = field.selectionStart;
306− var end = field.selectionEnd;
307 field.value = field.elm_old_value;
284 field.value = field.elm_old_value;
308−
309− elm.notify(field.elm_signal.id, field.elm_handler({
285+ elm.notify(field.elm_signal.id, field.elm_handler(JS.toString(next)));
310− _:{},
311− string: JS.toString(next),
312− selection: {
313− start: start,
314− end: end,
315− direction: { ctor: direction }
316− },
317− }));
318 }
286 }
319
287
320− function mouseUpdate(event) {
321− var direction = field.selectionDirection === 'forward' ? 'Forward' : 'Backward';
322− elm.notify(field.elm_signal.id, field.elm_handler({
323− _:{},
324− string: field.value,
325− selection: {
326− start: field.selectionStart,
327− end: field.selectionEnd,
328− direction: { ctor: direction }
329− },
330− }));
331− }
332− function mousedown(event) {
333− mouseUpdate(event);
334− elm.node.addEventListener('mouseup', mouseup);
335− }
336− function mouseup(event) {
337− mouseUpdate(event);
338− elm.node.removeEventListener('mouseup', mouseup)
339− }
340 field.addEventListener('keypress', keyUpdate);
288 field.addEventListener('keypress', keyUpdate);
341 field.addEventListener('input', inputUpdate);
289 field.addEventListener('input', inputUpdate);
342− field.addEventListener('mousedown', mousedown);
343
290
344 return field;
291 return field;
345 }
292 }
@@ -353,12 +300,9 @@ Elm.Native.Graphics.Input.make = function(elm) {
353
300
354 field.type = newModel.type;
301 field.type = newModel.type;
355 field.placeholder = JS.fromString(newModel.placeHolder);
302 field.placeholder = JS.fromString(newModel.placeHolder);
356− var value = JS.fromString(newModel.content.string);
303+ var value = JS.fromString(newModel.content);
357 field.value = value;
304 field.value = value;
358 field.elm_old_value = value;
305 field.elm_old_value = value;
359− var selection = newModel.content.selection;
360− var direction = selection.direction.ctor === 'Forward' ? 'forward' : 'backward';
361− setRange(field, selection.start, selection.end, direction);
362 }
306 }
363
307
364 function mkField(type) {
308 function mkField(type) {