-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
79 lines (64 loc) · 2.14 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
const Backspace = 8
const Enter = 13
const End = 35
const Home = 36
const Left = 37
const Up = 38
const Right = 39
const Down = 40
const Delete = 46
const LetterV = 86
const LetterA = 65
const LetterC = 67
const Buttons = [Backspace, Enter, End, Home, Left, Up, Right, Down, Delete]
const CopyCommands = [LetterA, LetterC, LetterV]
const getElemTextUntilCursorByArray = elem => elem.value.substr(0, elem.selectionStart).split("\n")
const getLineNumber = elem => getElemTextUntilCursorByArray(elem).length
const getColumn = elem => {
const lines = getElemTextUntilCursorByArray(elem)
return lines[lines.length - 1].length
}
const limitBy = limit => {
return elem => {
_limitOnKeyDown(limit, elem)
_limitOnPaste(limit, elem)
}
}
const _limitOnKeyDown = (limit, elem) => {
elem.addEventListener("keydown", e => {
const column = getColumn(elem)
const lines = elem.value.split("\n")
const index = getLineNumber(elem) - 1
const line = lines[index]
if (e.ctrlKey && CopyCommands.includes(e.keyCode)) {
return
}
if (line.length >= limit && !Buttons.includes(e.keyCode)) {
e.preventDefault()
}
if (e.keyCode === Delete && column === line.length && lines[index+1] !== undefined) {
if (line.length + lines[index+1].length > limit) {
e.preventDefault()
}
}
if (e.keyCode === Backspace && column === 0 && lines[index-1] !== undefined) {
if (line.length + lines[index-1].length > limit) {
e.preventDefault()
}
}
})
}
const _limitOnPaste = (limit, elem) => {
elem.addEventListener("paste", e => {
e.preventDefault()
const text = e.target.value
const startText = text.substring(0, elem.selectionStart)
const pastedText = e.clipboardData.getData('text')
const endText = text.substring(elem.selectionStart)
const newContent = startText + pastedText + endText
const lines = newContent.split("\n")
const newLines = lines.flatMap(line => line.length >= limit ? line.match(new RegExp(`.{1,${limit}}`, 'g')) : line)
e.target.value = newLines.join("\n")
elem.selectionStart = elem.selectionEnd = (startText + pastedText).length
})
}