Skip to content

Commit f4eba92

Browse files
committed
simplify event handling (by using 'input' instead of 'keydown')
1 parent fc10d58 commit f4eba92

File tree

1 file changed

+12
-81
lines changed

1 file changed

+12
-81
lines changed

codejar.ts

Lines changed: 12 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
4545
const listeners: [keyof HTMLElementEventMap, (event: Event) => void][] = []
4646
const history: HistoryRecord[] = []
4747
let at = -1
48-
let focus = false
4948
let onUpdate: (code: string) => void = () => { }
50-
let prev: string // code content prior keydown event
5149

5250
editor.setAttribute('contenteditable', 'plaintext-only')
5351
editor.setAttribute('spellcheck', options.spellcheck ? 'true' : 'false')
@@ -66,20 +64,7 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
6664
restore(pos)
6765
}, 30)
6866

69-
let recording = false
70-
const shouldRecord = (event: KeyboardEvent): boolean => {
71-
return !isUndo(event) && !isRedo(event)
72-
&& event.key !== 'Meta'
73-
&& event.key !== 'Control'
74-
&& event.key !== 'Alt'
75-
&& !event.key.startsWith('Arrow')
76-
}
77-
const debounceRecordHistory = debounce((event: KeyboardEvent) => {
78-
if (shouldRecord(event)) {
79-
recordHistory()
80-
recording = false
81-
}
82-
}, 300)
67+
const debounceRecordHistory = debounce(recordHistory, 300)
8368

8469
const on = <K extends keyof HTMLElementEventMap>(type: K, fn: (event: HTMLElementEventMap[K]) => void) => {
8570
listeners.push([type, fn as (event: Event) => void])
@@ -89,45 +74,25 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
8974
on('keydown', event => {
9075
if (event.defaultPrevented) return
9176

92-
prev = toString()
9377
if (options.preserveIdent) handleNewLine(event)
9478
else legacyNewLineFix(event)
9579
if (options.catchTab) handleTabCharacters(event)
9680
if (options.addClosing) handleSelfClosingCharacters(event)
97-
if (options.history) {
98-
handleUndoRedo(event)
99-
if (shouldRecord(event) && !recording) {
100-
recordHistory()
101-
recording = true
102-
}
81+
if (options.history) handleUndoRedo(event)
82+
83+
// 'defaultPrevented' means a change was made
84+
if (event.defaultPrevented) {
85+
const pos = save()
86+
highlight(editor, pos)
87+
restore(pos)
10388
}
104-
if (isLegacy && !isCopy(event)) restore(save())
10589
})
10690

107-
on('keyup', event => {
91+
on('input', event => {
10892
if (event.defaultPrevented) return
109-
if (event.isComposing) return
110-
111-
if (prev !== toString()) debounceHighlight()
112-
debounceRecordHistory(event)
113-
onUpdate(toString())
114-
})
115-
116-
on('focus', () => focus = true)
117-
on('blur', () => focus = false)
118-
119-
on('paste', event => {
120-
recordHistory()
121-
handlePaste(event)
122-
recordHistory()
123-
onUpdate(toString())
124-
})
125-
126-
on('cut', event => {
127-
recordHistory()
128-
handleCut(event)
129-
recordHistory()
130-
onUpdate(toString())
93+
if ((event as InputEvent).isComposing) return
94+
if (options.history) debounceRecordHistory()
95+
debounceHighlight()
13196
})
13297

13398
function save(): Position {
@@ -400,8 +365,6 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
400365
}
401366

402367
function recordHistory() {
403-
if (!focus) return
404-
405368
const html = editor.innerHTML
406369
const pos = save()
407370

@@ -423,34 +386,6 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
423386
}
424387
}
425388

426-
function handlePaste(event: ClipboardEvent) {
427-
if (event.defaultPrevented) return
428-
event.preventDefault()
429-
const text = event.clipboardData?.getData('text/plain').replace(/\r\n?/g, '\n') ?? ''
430-
const pos = save()
431-
insert(text)
432-
highlight(editor)
433-
restore({
434-
start: Math.min(pos.start, pos.end) + text.length,
435-
end: Math.min(pos.start, pos.end) + text.length,
436-
dir: '<-',
437-
})
438-
}
439-
440-
function handleCut(event: ClipboardEvent) {
441-
const pos = save()
442-
const selection = getSelection()
443-
event.clipboardData?.setData('text/plain', selection.toString())
444-
insert('') // deletes the selection
445-
highlight(editor)
446-
restore({
447-
start: Math.min(pos.start, pos.end),
448-
end: Math.min(pos.start, pos.end),
449-
dir: '<-',
450-
})
451-
event.preventDefault()
452-
}
453-
454389
function visit(editor: HTMLElement, visitor: (el: Node) => 'stop' | undefined) {
455390
const queue: Node[] = []
456391
if (editor.firstChild) queue.push(editor.firstChild)
@@ -475,10 +410,6 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
475410
return isCtrl(event) && event.shiftKey && getKey(event) === 'Z'
476411
}
477412

478-
function isCopy(event: KeyboardEvent) {
479-
return isCtrl(event) && getKey(event) === 'C'
480-
}
481-
482413
function getKey(event: KeyboardEvent): string | undefined {
483414
return event.key.toUpperCase()
484415
}

0 commit comments

Comments
 (0)