@@ -52,7 +52,7 @@ const placeholderNeeded = (node: Node) => {
5252} ;
5353
5454const addDecoration = (
55- decorationsMap : Record < number , Decoration | PluginKey > ,
55+ widgetsMap : WidgetsMap ,
5656 node : Node ,
5757 pos : number ,
5858 parent : Node | null ,
@@ -63,10 +63,10 @@ const addDecoration = (
6363 const decorationPosition = pos + node . childCount + 1 ;
6464
6565 // Не добавляем декорацию если на этой позиции уже есть плейсхолдер
66- if ( ! placeholderSpec || decorationsMap [ decorationPosition ] ) return ;
66+ if ( ! placeholderSpec || widgetsMap [ decorationPosition ] ) return ;
6767
6868 if ( placeholderSpec . customPlugin ) {
69- decorationsMap [ decorationPosition ] = placeholderSpec . customPlugin ;
69+ widgetsMap [ decorationPosition ] = placeholderSpec . customPlugin ;
7070
7171 return ;
7272 }
@@ -76,19 +76,28 @@ const addDecoration = (
7676 globalState . hasFocus = true ;
7777 }
7878
79- decorationsMap [ decorationPosition ] = Decoration . widget (
80- decorationPosition ,
81- createPlaceholder ( node , parent , focus ) ,
82- ) ;
79+ widgetsMap [ decorationPosition ] = {
80+ pos : decorationPosition ,
81+ toDOM : createPlaceholder ( node , parent , focus ) ,
82+ } ;
8383} ;
8484
8585type ApplyGlobalState = { hasFocus : boolean } ;
8686
87+ type DecoWidgetParameters = Parameters < typeof Decoration . widget > ;
88+ type WidgetSpec = {
89+ pos : DecoWidgetParameters [ 0 ] ;
90+ toDOM : DecoWidgetParameters [ 1 ] ;
91+ spec ?: DecoWidgetParameters [ 2 ] ;
92+ } ;
93+
8794type PlaceholderPluginState = {
88- decorations : Decoration [ ] ;
95+ widgets : WidgetSpec [ ] ;
8996 hasFocus : boolean ;
9097} ;
9198
99+ type WidgetsMap = Record < number , WidgetSpec | PluginKey > ;
100+
92101const pluginKey = new PluginKey < PlaceholderPluginState > ( 'placeholder_plugin' ) ;
93102
94103export const Placeholder : ExtensionAuto = ( builder ) => {
@@ -106,8 +115,13 @@ export const Placeholder: ExtensionAuto = (builder) => {
106115 return attrs ;
107116 } ,
108117 decorations ( state ) {
109- const { decorations} = pluginKey . getState ( state ) ! ;
110- return DecorationSet . create ( state . doc , decorations ) ;
118+ const { widgets} = pluginKey . getState ( state ) ! ;
119+ return DecorationSet . create (
120+ state . doc ,
121+ widgets . map ( ( widget ) =>
122+ Decoration . widget ( widget . pos , widget . toDOM , widget . spec ) ,
123+ ) ,
124+ ) ;
111125 } ,
112126 } ,
113127 state : {
@@ -120,15 +134,14 @@ export const Placeholder: ExtensionAuto = (builder) => {
120134
121135function applyState ( state : EditorState ) : PlaceholderPluginState {
122136 const globalState : ApplyGlobalState = { hasFocus : false } ;
123- const decorationsMap : Record < number , Decoration | PluginKey > = { } ;
137+ const widgetsMap : WidgetsMap = { } ;
124138 const { selection} = state ;
125139 const cursorPos = isTextSelection ( selection ) ? selection . $cursor ?. pos : null ;
126140
127141 getPlaceholderPluginKeys ( state . schema ) . forEach ( ( f ) => {
128142 // Используем find потому что при помощи него можно проитерировать по DecorationSet.
129143 f . getState ( state ) ?. find ( undefined , undefined , ( spec ) => {
130- decorationsMap [ spec . pos ] = f ;
131-
144+ widgetsMap [ spec . pos ] = f ;
132145 return false ;
133146 } ) ;
134147 } ) ;
@@ -138,7 +151,7 @@ function applyState(state: EditorState): PlaceholderPluginState {
138151 const placeholderSpec = node . type . spec . placeholder ;
139152
140153 if ( placeholderSpec && placeholderSpec . alwaysVisible && placeholderNeeded ( node ) ) {
141- addDecoration ( decorationsMap , node , pos , parent , cursorPos , globalState ) ;
154+ addDecoration ( widgetsMap , node , pos , parent , cursorPos , globalState ) ;
142155 }
143156 } ;
144157
@@ -159,14 +172,14 @@ function applyState(state: EditorState): PlaceholderPluginState {
159172 ) {
160173 const { node, pos, depth} = parentNode ;
161174 const parent = depth > 0 ? state . selection . $from . node ( depth - 1 ) : null ;
162- addDecoration ( decorationsMap , node , pos , parent , cursorPos , globalState ) ;
175+ addDecoration ( widgetsMap , node , pos , parent , cursorPos , globalState ) ;
163176 }
164177
165- const decorations = Object . values ( decorationsMap ) . filter (
178+ const widgets = Object . values ( widgetsMap ) . filter (
166179 ( decoration ) => ! ( decoration instanceof PluginKey ) ,
167- ) as Decoration [ ] ;
180+ ) as WidgetSpec [ ] ;
168181
169- return { decorations , hasFocus : globalState . hasFocus } ;
182+ return { widgets , hasFocus : globalState . hasFocus } ;
170183}
171184
172185declare module 'prosemirror-model' {
0 commit comments