@@ -20,6 +20,7 @@ import type {
20
20
UpdatableBlock ,
21
21
} from '@glimmer/interfaces' ;
22
22
import { destroy , registerDestructor } from '@glimmer/destroyable' ;
23
+ import { createUnboundRef , REFERENCE } from '@glimmer/reference' ;
23
24
import { assert , expect , Stack } from '@glimmer/util' ;
24
25
25
26
import type { DynamicAttribute } from './attributes/dynamic' ;
@@ -83,6 +84,7 @@ export class NewElementBuilder implements ElementBuilder {
83
84
[ CURSOR_STACK ] = new Stack < Cursor > ( ) ;
84
85
private modifierStack = new Stack < Nullable < ModifierInstance [ ] > > ( ) ;
85
86
private blockStack = new Stack < LiveBlock > ( ) ;
87
+ private htmlElementsState : { shouldAddHtmlElement ?: boolean } [ ] ;
86
88
87
89
static forInitialRender ( env : Environment , cursor : CursorImpl ) {
88
90
return new this ( env , cursor . element , cursor . nextSibling ) . initialize ( ) ;
@@ -104,6 +106,7 @@ export class NewElementBuilder implements ElementBuilder {
104
106
this . env = env ;
105
107
this . dom = env . getAppendOperations ( ) ;
106
108
this . updateOperations = env . getDOM ( ) ;
109
+ this . htmlElementsState = [ ] ;
107
110
}
108
111
109
112
protected initialize ( ) : this {
@@ -195,8 +198,8 @@ export class NewElementBuilder implements ElementBuilder {
195
198
this . constructing = null ;
196
199
this . operations = null ;
197
200
198
- this . pushModifiers ( modifiers ) ;
199
201
this . pushElement ( element , null ) ;
202
+ this . pushModifiers ( modifiers ) ;
200
203
this . didOpenElement ( element ) ;
201
204
}
202
205
@@ -205,6 +208,15 @@ export class NewElementBuilder implements ElementBuilder {
205
208
}
206
209
207
210
closeElement ( ) : Nullable < ModifierInstance [ ] > {
211
+ const htmlState = this . htmlElementsState . pop ( ) ;
212
+ if ( htmlState ?. shouldAddHtmlElement ) {
213
+ const element = this . element ;
214
+ this . env . debugRenderTree ?. didRender ( htmlState , {
215
+ parentElement : ( ) => ( element as any ) . parentElement ,
216
+ firstNode : ( ) => element ,
217
+ lastNode : ( ) => element ,
218
+ } ) ;
219
+ }
208
220
this . willCloseElement ( ) ;
209
221
this . popElement ( ) ;
210
222
return this . popModifiers ( ) ;
@@ -247,6 +259,56 @@ export class NewElementBuilder implements ElementBuilder {
247
259
248
260
private pushModifiers ( modifiers : Nullable < ModifierInstance [ ] > ) : void {
249
261
this . modifierStack . push ( modifiers ) ;
262
+ if ( this . env . debugRenderTree ) {
263
+ modifiers = modifiers || [ ] ;
264
+ const htmlState = {
265
+ shouldAddHtmlElement :
266
+ modifiers . length || ( globalThis as any ) . ENV_DEBUG_RENDER_TREE_ALL_ELEMENTS ,
267
+ } ;
268
+ this . htmlElementsState . push ( htmlState ) ;
269
+ if ( htmlState . shouldAddHtmlElement ) {
270
+ this . env . debugRenderTree ?. create ( htmlState , {
271
+ type : 'html-element' ,
272
+ name : this . element . tagName . toLowerCase ( ) ,
273
+ args : {
274
+ named : { } ,
275
+ positional : [ ] ,
276
+ } as any ,
277
+ instance : this . element ,
278
+ } ) ;
279
+ }
280
+ for ( const modifier of modifiers ) {
281
+ const state = { } ;
282
+ const name = modifier . definition . resolvedName || 'unknown-modifier' ;
283
+ const instance = ( modifier . state as any ) . instance || ( modifier . state as any ) . delegate ;
284
+ const element = this . element ;
285
+ const args : any = {
286
+ positional : [ ] ,
287
+ named : { } ,
288
+ } ;
289
+ for ( const value of ( modifier . state as any ) . args . positional ) {
290
+ if ( value && value [ REFERENCE ] ) {
291
+ args . positional . push ( value ) ;
292
+ } else {
293
+ args . positional . push ( createUnboundRef ( value , false ) ) ;
294
+ }
295
+ }
296
+ for ( const [ key , value ] of Object . entries ( ( modifier . state as any ) ?. args . named ) ) {
297
+ args . named [ key ] = createUnboundRef ( value , false ) ;
298
+ }
299
+ this . env . debugRenderTree ?. create ( state , {
300
+ type : 'modifier' ,
301
+ name,
302
+ args : args ,
303
+ instance,
304
+ } ) ;
305
+ this . env . debugRenderTree ?. didRender ( state , {
306
+ parentElement : ( ) => ( element as any ) . parentElement ,
307
+ firstNode : ( ) => element ,
308
+ lastNode : ( ) => element ,
309
+ } ) ;
310
+ }
311
+ }
250
312
}
251
313
252
314
private popModifiers ( ) : Nullable < ModifierInstance [ ] > {
0 commit comments