@@ -19,6 +19,7 @@ import {
19
19
} from '../../plugin-renderer-dom-object/src/DomObjectRenderingEngine' ;
20
20
import { VElement } from '../../core/src/VNodes/VElement' ;
21
21
import { flat } from '../../utils/src/utils' ;
22
+ import { AbstractNode } from '../../core/src/VNodes/AbstractNode' ;
22
23
23
24
export type DomPoint = [ Node , number ] ;
24
25
export type DomLayoutLocation = [ Node , DomZonePosition ] ;
@@ -116,44 +117,71 @@ export class DomLayoutEngine extends LayoutEngine {
116
117
return this . _domReconciliationEngine . toDom ( node ) ;
117
118
}
118
119
async redraw ( nodes ?: VNode [ ] ) : Promise < void > {
119
- if (
120
- ! this . editor . enableRender ||
121
- ( this . editor . preventRenders && this . editor . preventRenders . size )
122
- ) {
123
- return ;
124
- }
125
120
if ( this . _currentlyRedrawing ) {
126
121
throw new Error ( 'Double redraw detected' ) ;
127
122
}
128
123
this . _currentlyRedrawing = true ;
129
124
130
125
if ( nodes ) {
126
+ nodes = nodes . filter ( node => {
127
+ return node . ancestors ( ) . pop ( ) === this . root ;
128
+ } ) ;
129
+
130
+ const nodeIds : Record < number , VNode > = { } ;
131
131
for ( let node of nodes ) {
132
+ nodeIds [ node . id ] = node ;
132
133
while (
134
+ node . parent &&
135
+ ! nodeIds [ node . parent . id ] &&
133
136
( this . _domReconciliationEngine . getRenderedWith ( node ) . length !== 1 ||
134
- ! this . _domReconciliationEngine . toDom ( node ) . length ) &&
135
- node . parent
137
+ ! this . _domReconciliationEngine . toDom ( node ) . length )
136
138
) {
137
139
// If the node are redererd with some other nodes then redraw parent.
138
140
// If not in layout then redraw the parent.
139
141
node = node . parent ;
140
- if ( ! nodes . includes ( node ) ) {
141
- nodes . push ( node ) ;
142
- }
142
+ nodeIds [ node . id ] = node ;
143
143
}
144
144
}
145
- for ( const node of [ ...nodes ] ) {
145
+
146
+ const parents : VNode [ ] = [ ] ;
147
+ for ( const node of nodes ) {
146
148
// Add direct siblings nodes for batched nodes with format.
149
+ const next = node . next ( ) ;
150
+ if ( next && next . parent === node . parent ) {
151
+ nodeIds [ next . id ] = next ;
152
+ }
147
153
const previous = node . previous ( ) ;
148
- if ( previous && ! nodes . includes ( previous ) ) {
149
- nodes . push ( previous ) ;
154
+ if ( previous && previous . parent === node . parent ) {
155
+ nodeIds [ previous . id ] = previous ;
150
156
}
151
- const next = node . next ( ) ;
152
- if ( next && ! nodes . includes ( next ) ) {
153
- nodes . push ( next ) ;
157
+ }
158
+
159
+ // Add grouped node for rendering.
160
+ const nearests : Record < number , VNode > = { } ;
161
+ for ( const id in nodeIds ) {
162
+ if ( ! nearests [ id ] ) {
163
+ const node = nodeIds [ id ] ;
164
+ for ( const nearest of this . _domReconciliationEngine . getRenderedWith ( node ) ) {
165
+ if ( nearest instanceof AbstractNode ) {
166
+ const id = nearest . id ;
167
+ nodeIds [ id ] = nearests [ id ] = nearest ;
168
+ }
169
+ }
170
+ // Add parent for wrap/unwrapped node list formatted charNodes.
171
+ const parent = node . parent ;
172
+ if ( parent && ! parents . includes ( parent ) ) {
173
+ parents . push ( parent ) ;
174
+ }
154
175
}
155
176
}
177
+
178
+ for ( const parent of parents ) {
179
+ nodeIds [ parent . id ] = parent ;
180
+ }
181
+
182
+ nodes = Object . values ( nodeIds ) ;
156
183
} else {
184
+ nodes = [ ] ;
157
185
// Redraw all.
158
186
for ( const componentId in this . locations ) {
159
187
nodes . push ( ...this . components . get ( componentId ) ) ;
@@ -165,18 +193,15 @@ export class DomLayoutEngine extends LayoutEngine {
165
193
}
166
194
}
167
195
168
- nodes = nodes . filter ( node => {
169
- const ancestor = node . ancestors ( ZoneNode ) . pop ( ) ;
170
- return ancestor ?. managedZones . includes ( 'root' ) ;
171
- } ) ;
172
-
173
196
// Render nodes.
174
197
const renderer = this . editor . plugins . get ( Renderer ) ;
175
- const domObjects = await renderer . render < DomObject > ( 'dom/object' , nodes ) ;
198
+ let domObjects = ( await renderer . render < DomObject > ( 'dom/object' , nodes ) ) || [ ] ;
176
199
const engine = renderer . engines [ 'dom/object' ] as DomObjectRenderingEngine ;
177
200
201
+ domObjects = domObjects . filter ( ( node , index ) => domObjects . indexOf ( node ) === index ) ;
202
+
178
203
this . _domReconciliationEngine . update (
179
- domObjects || [ ] ,
204
+ domObjects ,
180
205
engine . locations ,
181
206
engine . from ,
182
207
this . _markedForRedraw ,
0 commit comments