You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An isomorphic `TextCursor`type for selections in DOM elements (`<input>` and `<textarea>`). Provides shared DOM methods and TextCursor manipulations.
2
+
An `TextCursor`isomorphism for selections in DOM elements (`<input>` and `<textarea>`). Provides shared DOM methods and TextCursor manipulations.
3
3
4
-
## Supported elements
5
-
All `<textarea>` elements and `<input>` elements with the `type` attribute set to one of the following:
6
-
- input (default)
7
-
- email
8
-
- search
9
-
- url
4
+
## The problem
5
+
In the DOM, selections within input elements are represented by a starting and ending index, and the value of the element. If the value is changed, the selection is reset, so the user loses their place in the field. The selection can be added back to the element, but accurately predicting the indices is near impossible with complex operations. This library provides a sane way of dealing with selections.
It represents a selection in an element in three regions: the text `before` the cursor/selection, the text inside the `selection` (empty if there is just a cursor), and the text `after`.
22
18
23
-
What this does is allow transformations to occur (such as replacements, white-space simplification) while preserving the relative location of the cursor or selection.
19
+
This allows transformations to occur (such as replacements, white-space simplification) while preserving the relative location of the cursor or selection.
20
+
21
+
A simple replacement that matches on single characters in each field of a `TextCursor` will have the same content as replacing the entire string, but it will also preserve the locations of the cursor or selection within the field:
22
+
23
+
```purescript
24
+
replacement = toUpper
25
+
tc = TextCursor
26
+
{ before: "Hello, "
27
+
, selected: "World"
28
+
, after: "! Hi!"
29
+
}
30
+
tcreplaced = over _all replacement tc
31
+
content tcreplaced == replacement (content tc)
32
+
```
33
+
34
+
Note that certain transformations will depend on the position of the text cursor or selection within the field, particularly if they rely on matching a string of characters versus single characters. For example, a replacement `s/''/"/g` depends on two characters being adjacent and will not match if the cursor or edge of a selection lies in between the two single quotes. But for a simple case like this, checks can be added to handle edge cases, if desired:
24
35
25
-
Note that certain transformations will depend on the position of the text cursor or selection within the field, particularly if they rely on a string of characters versus single characters (e.g. a replacement ` ``|'' -> "`, which depends on quote characters being adjacent, as opposed to `[A-Z] -> [a-z]`, which does not care where the cursor falls as it selects a single character without context).
36
+
```purescript
37
+
q = "'"
38
+
q2 = q <> q
39
+
qq = "\""
40
+
replaceQuote = replaceAll (wrap q2) (wrap qq)
41
+
replaceLast s =
42
+
case stripSuffix (wrap q) of
43
+
Nothing -> s
44
+
Just s' -> s' <> qq
45
+
-- left biased for quotes matched across an edge
46
+
stitch left right
47
+
| endsWith q left
48
+
&& startsWith q right
49
+
= Tuple (replaceLast left) (drop 1 right)
50
+
| otherwise = Tuple left right
51
+
replaceAcross left right =
52
+
stitch (replaceQuote left) right
53
+
<#> replaceQuote
54
+
replaceQuotes = case _ of
55
+
TextCursor { before, selected: "", after } ->
56
+
let
57
+
Tuple before' after' =
58
+
replaceAcross before after
59
+
in TextCursor
60
+
{ before: before'
61
+
, selected: ""
62
+
, after: after'
63
+
}
64
+
TextCursor { before, selected, after } ->
65
+
let
66
+
Tuple before' (Tuple selected' after') =
67
+
replaceAcross before selected
68
+
<#> flip replaceAcross after
69
+
in TextCursor
70
+
{ before: before'
71
+
, selected: selected'
72
+
, after: after'
73
+
}
74
+
```
75
+
76
+
## Supported DOM elements
77
+
All `<textarea>` elements and `<input>` elements with the `type` attribute set to one of the following:
0 commit comments