66import type { TextSnapshot , TextSnapshotNode } from '../McpContext.js' ;
77
88export class SnapshotFormatter {
9- constructor ( public snapshot ?: TextSnapshot ) { }
9+ #snapshot: TextSnapshot ;
10+
11+ constructor ( snapshot : TextSnapshot ) {
12+ this . #snapshot = snapshot ;
13+ }
1014
1115 toString ( ) : string {
12- if ( ! this . snapshot ) {
13- return '' ;
14- }
1516 const chunks : string [ ] = [ ] ;
16- const root = this . snapshot . root ;
17+ const root = this . # snapshot. root ;
1718
1819 // Top-level content of the snapshot.
1920 if (
20- this . snapshot . verbose &&
21- this . snapshot . hasSelectedElement &&
22- ! this . snapshot . selectedElementUid
21+ this . # snapshot. verbose &&
22+ this . # snapshot. hasSelectedElement &&
23+ ! this . # snapshot. selectedElementUid
2324 ) {
2425 chunks . push ( `Note: there is a selected element in the DevTools Elements panel but it is not included into the current a11y tree snapshot.
2526Get a verbose snapshot to include all elements if you are interested in the selected element.\n\n` ) ;
@@ -30,19 +31,16 @@ Get a verbose snapshot to include all elements if you are interested in the sele
3031 }
3132
3233 toJSON ( ) : object {
33- if ( ! this . snapshot ) {
34- return { } ;
35- }
36- return this . #nodeToJSON( this . snapshot . root ) ;
34+ return this . #nodeToJSON( this . #snapshot. root ) ;
3735 }
3836
39- #formatNode( node : TextSnapshotNode , depth : number ) : string {
37+ #formatNode( node : TextSnapshotNode , depth = 0 ) : string {
4038 const chunks : string [ ] = [ ] ;
4139 const attributes = this . #getAttributes( node ) ;
4240 const line =
4341 ' ' . repeat ( depth * 2 ) +
4442 attributes . join ( ' ' ) +
45- ( node . id === this . snapshot ? .selectedElementUid
43+ ( node . id === this . # snapshot. selectedElementUid
4644 ? ' [selected in the DevTools Elements panel]'
4745 : '' ) +
4846 '\n' ;
@@ -57,9 +55,7 @@ Get a verbose snapshot to include all elements if you are interested in the sele
5755 #nodeToJSON( node : TextSnapshotNode ) : object {
5856 const rawAttrs = this . #getAttributesMap( node ) ;
5957 const children = node . children . map ( child => this . #nodeToJSON( child ) ) ;
60- const result : Record < string , unknown > = {
61- ...rawAttrs ,
62- } ;
58+ const result : Record < string , unknown > = structuredClone ( rawAttrs ) ;
6359 if ( children . length > 0 ) {
6460 result . children = children ;
6561 }
@@ -113,8 +109,12 @@ Get a verbose snapshot to include all elements if you are interested in the sele
113109 const result : Record < string , unknown > = { } ;
114110 if ( ! excludeSpecial ) {
115111 result . id = node . id ;
116- if ( node . role ) result . role = node . role ;
117- if ( node . name ) result . name = node . name ;
112+ if ( node . role ) {
113+ result . role = node . role ;
114+ }
115+ if ( node . name ) {
116+ result . name = node . name ;
117+ }
118118 }
119119
120120 // Re-implementing the exact logic from original function for #getAttributes to be safe:
0 commit comments