@@ -18,7 +18,6 @@ import {
1818 PluginKey ,
1919 Selection ,
2020 TextSelection ,
21- type Transaction ,
2221} from "prosemirror-state" ;
2322import type { EditorView } from "prosemirror-view" ;
2423import {
@@ -52,6 +51,7 @@ import {
5251 clearMarksOnEnterPlugin ,
5352 clipboardPlugin ,
5453 clipPastePlugin ,
54+ docChangeListenerPlugin ,
5555 ensureImageTrailingParagraphs ,
5656 fileHandlerPlugin ,
5757 getSearchState ,
@@ -75,7 +75,6 @@ import {
7575 normalizeTaskContent ,
7676 type TaskSource ,
7777} from "../tasks" ;
78- import { dispatchEditorTransaction } from "../transaction-guard" ;
7978import {
8079 FormatToolbar ,
8180 type MentionConfig ,
@@ -537,26 +536,28 @@ export const NoteEditor = forwardRef<NoteEditorRef, NoteEditorProps>(
537536 [ taskSource , taskStorage ] ,
538537 ) ;
539538
540- const flushChange = useCallback ( ( ) => {
541- const view = viewRef . current ;
542- if ( ! view ) {
543- return ;
544- }
545-
546- const content = view . state . doc . toJSON ( ) as JSONContent ;
547- syncTasks ( content ) ;
548- if ( ! handleChange ) {
549- return ;
550- }
539+ const flushChange = useCallback (
540+ ( content : JSONContent ) => {
541+ syncTasks ( content ) ;
542+ if ( ! handleChange ) {
543+ return ;
544+ }
551545
552- handleChange ( content ) ;
553- } , [ handleChange , syncTasks ] ) ;
546+ handleChange ( content ) ;
547+ } ,
548+ [ handleChange , syncTasks ] ,
549+ ) ;
554550
555551 const onUpdate = useDebounceCallback ( flushChange , 500 ) ;
552+ const onUpdateRef = useRef ( onUpdate ) ;
553+ onUpdateRef . current = onUpdate ;
556554
557555 const plugins = useMemo (
558556 ( ) => [
559557 reactKeys ( ) ,
558+ docChangeListenerPlugin ( ( view ) =>
559+ onUpdateRef . current ( view . state . doc . toJSON ( ) as JSONContent ) ,
560+ ) ,
560561 buildInputRules ( ) ,
561562 ...( enforceTitleHeading ? [ titleHeadingPlugin ( ) ] : [ ] ) ,
562563 taskIdentityPlugin ( ) ,
@@ -649,12 +650,18 @@ export const NoteEditor = forwardRef<NoteEditorRef, NoteEditorProps>(
649650 doc,
650651 plugins : view . state . plugins ,
651652 } ) ;
653+ onUpdate . cancel ( ) ;
652654 view . updateState ( state ) ;
653655 previousContentRef . current = reconciledInitialContent ;
654656 } catch {
655657 // invalid content
656658 }
657- } , [ reconciledInitialContent , syncContentWhenFocused , enforceTitleHeading ] ) ;
659+ } , [
660+ reconciledInitialContent ,
661+ syncContentWhenFocused ,
662+ enforceTitleHeading ,
663+ onUpdate ,
664+ ] ) ;
658665
659666 const onViewReady = useCallback (
660667 ( view : EditorView ) => {
@@ -675,16 +682,6 @@ export const NoteEditor = forwardRef<NoteEditorRef, NoteEditorProps>(
675682 < ProseMirror
676683 defaultState = { defaultState }
677684 nodeViewComponents = { nodeViews }
678- dispatchTransaction = { function (
679- this : EditorView ,
680- tr : Transaction ,
681- ) {
682- dispatchEditorTransaction ( {
683- view : this ,
684- transaction : tr ,
685- onDocChanged : ( ) => onUpdate ( ) ,
686- } ) ;
687- } }
688685 attributes = { {
689686 spellCheck : "false" ,
690687 autoComplete : "off" ,
0 commit comments