@@ -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