@@ -111,74 +111,80 @@ export const blockComponentWidget = ({
111
111
const decorate = ( state : EditorState ) => {
112
112
const widgets : Range < Decoration > [ ] = [ ] ;
113
113
114
+ const onAddBlockComponent = ( from : number , to : number , text : string ) => {
115
+ const blockComponentPropsRegex =
116
+ / (? ! \< B l o c k C o m p o n e n t [ \s \S \n ] * ) ( [ \s \S \n ] * ?) (? = \/ \> ) / ;
117
+ const propsString = blockComponentPropsRegex
118
+ . exec ( text ) ?. [ 0 ]
119
+ . split ( "BlockComponent" ) [ 1 ] ;
120
+ if ( ! propsString ) return ;
121
+ let props = { } ;
122
+ const propsArray = propsString . split ( "=" ) ;
123
+ let runningLastPropKey = "" ;
124
+ propsArray . forEach ( ( prop , index ) => {
125
+ const lastWordInString =
126
+ prop . split ( / \s + / ) [ prop . split ( / \s + / ) . length - 1 ] ;
127
+ const key = runningLastPropKey ;
128
+ runningLastPropKey = lastWordInString ;
129
+ // slice lastWordInString from end
130
+ const valueString = prop . slice (
131
+ 0 ,
132
+ prop . length - lastWordInString . length
133
+ ) ;
134
+ if ( ! key || ! valueString ) return ;
135
+
136
+ // TODO: extract props from string in a more robust way
137
+ try {
138
+ eval (
139
+ `window.parsedValue = ${ valueString
140
+ . trim ( )
141
+ // remove start and end curly braces
142
+ . replace ( / ^ \{ | \} $ / g, "" ) } `
143
+ ) ;
144
+ props [ key ] = window . parsedValue ;
145
+ } catch ( e ) {
146
+ props [ key ] = valueString ;
147
+ }
148
+ } ) ;
149
+
150
+ const onChangeProps = ( newProps : any ) => {
151
+ const newString = `<BlockComponent
152
+ ${ Object . keys ( newProps )
153
+ . map ( ( key ) => `${ key } ={${ JSON . stringify ( newProps [ key ] ) } }` )
154
+ . join ( "\n" ) }
155
+ />` ;
156
+
157
+ onDispatchChanges ( {
158
+ changes : {
159
+ from,
160
+ to,
161
+ insert : Text . of ( [ newString ] ) ,
162
+ } ,
163
+ } ) ;
164
+ } ;
165
+ const newDecoration = blockComponentDecoration ( {
166
+ parentProps,
167
+ props,
168
+ onChangeProps,
169
+ } ) ;
170
+ widgets . push ( newDecoration . range ( from , to ) ) ;
171
+ } ;
172
+
114
173
syntaxTree ( state ) . iterate ( {
115
174
enter : ( { type, from, to } ) => {
116
175
let text = state . doc . sliceString ( from , to ) ;
117
176
if ( type . name === "Document" ) return ;
118
177
119
- const locationOfCloseTag = text . indexOf ( "/>" ) ;
120
- to = from + locationOfCloseTag + 2 ;
121
-
122
- const blockComponentRegex = / \< B l o c k C o m p o n e n t [ \s \S \n ] / ;
123
- const isBlockComponent = blockComponentRegex . test ( text ) ;
124
- if ( isBlockComponent ) {
125
- const blockComponentPropsRegex =
126
- / (? ! \< B l o c k C o m p o n e n t [ \s \S \n ] * ) ( [ \s \S \n ] * ?) (? = \/ \> ) / ;
127
- const propsString = blockComponentPropsRegex
128
- . exec ( text ) ?. [ 0 ]
129
- . split ( "BlockComponent" ) [ 1 ] ;
130
- if ( ! propsString ) return ;
131
- let props = { } ;
132
- const propsArray = propsString . split ( "=" ) ;
133
- let runningLastPropKey = "" ;
134
- propsArray . forEach ( ( prop , index ) => {
135
- const lastWordInString =
136
- prop . split ( / \s + / ) [ prop . split ( / \s + / ) . length - 1 ] ;
137
- const key = runningLastPropKey ;
138
- runningLastPropKey = lastWordInString ;
139
- // slice lastWordInString from end
140
- const valueString = prop . slice (
141
- 0 ,
142
- prop . length - lastWordInString . length
143
- ) ;
144
- if ( ! key || ! valueString ) return ;
145
-
146
- // TODO: extract props from string in a more robust way
147
- try {
148
- eval (
149
- `window.parsedValue = ${ valueString
150
- . trim ( )
151
- // remove start and end curly braces
152
- . replace ( / ^ \{ | \} $ / g, "" ) } `
153
- ) ;
154
- props [ key ] = window . parsedValue ;
155
- } catch ( e ) {
156
- props [ key ] = valueString ;
157
- }
158
- } ) ;
159
-
160
- const onChangeProps = ( newProps : any ) => {
161
- const newString = `<BlockComponent
162
- ${ Object . keys ( newProps )
163
- . map ( ( key ) => `${ key } ={${ JSON . stringify ( newProps [ key ] ) } }` )
164
- . join ( "\n" ) }
165
- />` ;
166
-
167
- onDispatchChanges ( {
168
- changes : {
169
- from,
170
- to,
171
- insert : Text . of ( [ newString ] ) ,
172
- } ,
173
- } ) ;
174
- } ;
175
- const newDecoration = blockComponentDecoration ( {
176
- parentProps,
177
- props,
178
- onChangeProps,
179
- } ) ;
180
- widgets . push ( newDecoration . range ( from , to ) ) ;
181
- }
178
+ const blockComponentRegex = / \< B l o c k C o m p o n e n t [ \s \S ] * ?\/ \> / gm;
179
+ const blockComponentMatches = text . match ( blockComponentRegex ) ;
180
+ blockComponentMatches ?. forEach ( ( match ) => {
181
+ const locationOfOpenTag = text . indexOf ( match ) ;
182
+ onAddBlockComponent (
183
+ from + locationOfOpenTag ,
184
+ from + locationOfOpenTag + match . length ,
185
+ match
186
+ ) ;
187
+ } ) ;
182
188
} ,
183
189
} ) ;
184
190
0 commit comments