@@ -15,14 +15,17 @@ import Dap from '../dap/api';
15
15
import { IDapApi } from '../dap/connection' ;
16
16
import * as errors from '../dap/errors' ;
17
17
import { ProtocolError } from '../dap/protocolError' ;
18
+ import { ClientCapabilities , IClientCapabilies } from './clientCapabilities' ;
18
19
import { IWasmVariable , IWasmVariableEvaluation , WasmScope } from './dwarf/wasmSymbolProvider' ;
20
+ import { AnsiStyles } from './messageFormat' ;
19
21
import * as objectPreview from './objectPreview' ;
20
22
import { MapPreview , SetPreview } from './objectPreview/betterTypes' ;
21
23
import { PreviewContextType } from './objectPreview/contexts' ;
22
24
import { StackFrame , StackTrace } from './stackTrace' ;
23
25
import { getSourceSuffix , RemoteException , RemoteObjectId } from './templates' ;
24
26
import { getArrayProperties } from './templates/getArrayProperties' ;
25
27
import { getArraySlots } from './templates/getArraySlots' ;
28
+ import { getNodeChildren } from './templates/getNodeChildren' ;
26
29
import {
27
30
getDescriptionSymbols ,
28
31
getStringyProps ,
@@ -204,6 +207,7 @@ class VariableContext {
204
207
public readonly locationProvider : IVariableStoreLocationProvider ,
205
208
private readonly currentRef : undefined | ( ( ) => IVariable | Scope ) ,
206
209
private readonly settings : IContextSettings ,
210
+ public readonly clientCapabilities : IClientCapabilies ,
207
211
) {
208
212
this . name = ctx . name ;
209
213
this . presentationHint = ctx . presentationHint ;
@@ -247,6 +251,7 @@ class VariableContext {
247
251
this . locationProvider ,
248
252
( ) => v ,
249
253
this . settings ,
254
+ this . clientCapabilities ,
250
255
) ,
251
256
...rest ,
252
257
) as InstanceType < T > ;
@@ -272,6 +277,8 @@ class VariableContext {
272
277
return this . createVariable ( FunctionVariable , ctx , object , customStringRepr ) ;
273
278
} else if ( object . subtype === 'map' || object . subtype === 'set' ) {
274
279
return this . createVariable ( SetOrMapVariable , ctx , object , customStringRepr ) ;
280
+ } else if ( object . subtype === 'node' ) {
281
+ return this . createVariable ( NodeVariable , ctx , object , customStringRepr ) ;
275
282
} else if ( ! objectPreview . subtypesWithoutPreview . has ( object . subtype ) ) {
276
283
return this . createVariable ( ObjectVariable , ctx , object , customStringRepr ) ;
277
284
}
@@ -851,6 +858,118 @@ class ObjectVariable extends Variable implements IMemoryReadable {
851
858
}
852
859
}
853
860
861
+ class NodeAttributes extends ObjectVariable {
862
+ public readonly id = getVariableId ( ) ;
863
+
864
+ override get accessor ( ) : string {
865
+ return ( this . context . parent as NodeVariable ) . accessor ;
866
+ }
867
+
868
+ public override async toDap (
869
+ context : PreviewContextType ,
870
+ valueFormat ?: Dap . ValueFormat ,
871
+ ) : Promise < Dap . Variable > {
872
+ return Promise . resolve ( {
873
+ ...await super . toDap ( context , valueFormat ) ,
874
+ value : '...' ,
875
+ } ) ;
876
+ }
877
+ }
878
+
879
+ class NodeVariable extends Variable {
880
+ public override async toDap (
881
+ previewContext : PreviewContextType ,
882
+ valueFormat ?: Dap . ValueFormat ,
883
+ ) : Promise < Dap . Variable > {
884
+ const description = await this . description ( ) ;
885
+ const length = description ?. node ?. childNodeCount || 0 ;
886
+ return {
887
+ ...await super . toDap ( previewContext , valueFormat ) ,
888
+ value : await this . getValuePreview ( previewContext ) ,
889
+ variablesReference : this . id ,
890
+ indexedVariables : length > 100 ? length : undefined ,
891
+ namedVariables : length > 100 ? 1 : undefined ,
892
+ } ;
893
+ }
894
+
895
+ public override async getChildren ( params ?: Dap . VariablesParamsExtended ) : Promise < Variable [ ] > {
896
+ switch ( params ?. filter ) {
897
+ case 'indexed' :
898
+ return this . getNodeChildren ( params . start , params . count ) ;
899
+ case 'named' :
900
+ return [ this . getAttributesVar ( ) ] ;
901
+ default :
902
+ return [ this . getAttributesVar ( ) , ...( await this . getNodeChildren ( ) ) ] ;
903
+ }
904
+ }
905
+
906
+ private getAttributesVar ( ) {
907
+ return this . context . createVariable (
908
+ NodeAttributes ,
909
+ {
910
+ name : l10n . t ( 'Node Attributes' ) ,
911
+ presentationHint : { visibility : 'internal' } ,
912
+ sortOrder : Number . MAX_SAFE_INTEGER ,
913
+ } ,
914
+ this . remoteObject ,
915
+ undefined ,
916
+ ) ;
917
+ }
918
+
919
+ private async getNodeChildren ( start = - 1 , count = - 1 ) {
920
+ let slotsObject : Cdp . Runtime . RemoteObject ;
921
+ try {
922
+ slotsObject = await getNodeChildren ( {
923
+ cdp : this . context . cdp ,
924
+ generatePreview : false ,
925
+ args : [ start , count ] ,
926
+ objectId : this . remoteObject . objectId ,
927
+ } ) ;
928
+ } catch ( e ) {
929
+ return [ ] ;
930
+ }
931
+
932
+ const result = await this . context . createObjectPropertyVars ( slotsObject ) ;
933
+ if ( slotsObject . objectId ) {
934
+ await this . context . cdp . Runtime . releaseObject ( { objectId : slotsObject . objectId } ) ;
935
+ }
936
+
937
+ return result ;
938
+ }
939
+
940
+ private readonly description = once ( ( ) =>
941
+ this . context . cdp . DOM . describeNode ( {
942
+ objectId : this . remoteObject . objectId ,
943
+ } )
944
+ ) ;
945
+
946
+ private async getValuePreview ( _previewContext : PreviewContextType ) {
947
+ const description = await this . description ( ) ;
948
+ if ( ! description ?. node ) {
949
+ return '' ;
950
+ }
951
+
952
+ const { localName, attributes, childNodeCount } = description . node ;
953
+ const styleCheck = this . context . clientCapabilities . value ?. supportsANSIStyling ? true : '' ;
954
+ let str = ( styleCheck && AnsiStyles . Blue ) + `<${ localName } ` ;
955
+ if ( attributes ) {
956
+ for ( let i = 0 ; i < attributes . length ; i += 2 ) {
957
+ const key = attributes [ i ] ;
958
+ const value = attributes [ i + 1 ] ;
959
+ str += ` ${ ( styleCheck && AnsiStyles . BrightBlue ) } ${ key } ${ ( styleCheck
960
+ && AnsiStyles . Dim ) } =${ ( styleCheck && AnsiStyles . Yellow ) } ${ JSON . stringify ( value ) } `;
961
+ }
962
+ }
963
+ str += ( styleCheck && AnsiStyles . Blue ) + '>' ;
964
+ if ( childNodeCount ) {
965
+ str += `${ ( styleCheck && AnsiStyles . Dim ) } ...${ ( styleCheck && AnsiStyles . Blue ) } ` ;
966
+ }
967
+ str += `</${ localName } >${ ( styleCheck && AnsiStyles . Reset ) } ` ;
968
+
969
+ return str ;
970
+ }
971
+ }
972
+
854
973
class FunctionVariable extends ObjectVariable {
855
974
private readonly baseChildren = once ( ( ) => super . getChildren ( { variablesReference : this . id } ) ) ;
856
975
@@ -1272,6 +1391,7 @@ export class VariableStore {
1272
1391
@inject ( ICdpApi ) private readonly cdp : Cdp . Api ,
1273
1392
@inject ( IDapApi ) private readonly dap : Dap . Api ,
1274
1393
@inject ( AnyLaunchConfiguration ) private readonly launchConfig : AnyLaunchConfiguration ,
1394
+ @inject ( ClientCapabilities ) private readonly clientCapabilities : ClientCapabilities ,
1275
1395
private readonly locationProvider : IVariableStoreLocationProvider ,
1276
1396
) {
1277
1397
this . contextSettings = {
@@ -1293,6 +1413,7 @@ export class VariableStore {
1293
1413
this . cdp ,
1294
1414
this . dap ,
1295
1415
this . launchConfig ,
1416
+ this . clientCapabilities ,
1296
1417
this . locationProvider ,
1297
1418
) ;
1298
1419
}
@@ -1345,6 +1466,7 @@ export class VariableStore {
1345
1466
this . locationProvider ,
1346
1467
( ) => scope ,
1347
1468
this . contextSettings ,
1469
+ this . clientCapabilities ,
1348
1470
) ,
1349
1471
scopeRef ,
1350
1472
extraProperties ,
@@ -1371,6 +1493,7 @@ export class VariableStore {
1371
1493
this . locationProvider ,
1372
1494
( ) => scope ,
1373
1495
this . contextSettings ,
1496
+ this . clientCapabilities ,
1374
1497
) ,
1375
1498
kind ,
1376
1499
variables ,
@@ -1497,6 +1620,7 @@ export class VariableStore {
1497
1620
this . locationProvider ,
1498
1621
undefined ,
1499
1622
this . contextSettings ,
1623
+ this . clientCapabilities ,
1500
1624
) ;
1501
1625
}
1502
1626
}
0 commit comments