@@ -101,7 +101,7 @@ function parseTagAttributes(source: string): Record<string, string> {
101101}
102102
103103function parseWidgetData ( value : string ) : unknown {
104- const candidates = [ value , value . replace ( / \\ " / g , '"' ) . replace ( / \\ ' / g , "'" ) ] ;
104+ const candidates = expandWidgetDataCandidates ( value ) ;
105105
106106 for ( const candidate of candidates ) {
107107 try {
@@ -118,6 +118,60 @@ function parseWidgetData(value: string): unknown {
118118 throw new Error ( 'Invalid widget data' ) ;
119119}
120120
121+ function expandWidgetDataCandidates ( value : string ) : string [ ] {
122+ const normalized = value . replace ( / \\ " / g, '"' ) . replace ( / \\ ' / g, "'" ) ;
123+ return Array . from (
124+ new Set ( [
125+ value ,
126+ normalized ,
127+ repairJsonLikeWidgetData ( value ) ,
128+ repairJsonLikeWidgetData ( normalized ) ,
129+ ] )
130+ ) . filter ( Boolean ) ;
131+ }
132+
133+ function repairJsonLikeWidgetData ( value : string ) : string {
134+ let repaired = value . trim ( ) ;
135+ if ( ! repaired ) return repaired ;
136+
137+ const stack : string [ ] = [ ] ;
138+ let inString = false ;
139+ let escaped = false ;
140+
141+ for ( const char of repaired ) {
142+ if ( inString ) {
143+ if ( escaped ) {
144+ escaped = false ;
145+ } else if ( char === '\\' ) {
146+ escaped = true ;
147+ } else if ( char === '"' ) {
148+ inString = false ;
149+ }
150+ continue ;
151+ }
152+
153+ if ( char === '"' ) {
154+ inString = true ;
155+ } else if ( char === '{' ) {
156+ stack . push ( '}' ) ;
157+ } else if ( char === '[' ) {
158+ stack . push ( ']' ) ;
159+ } else if ( ( char === '}' || char === ']' ) && stack [ stack . length - 1 ] === char ) {
160+ stack . pop ( ) ;
161+ }
162+ }
163+
164+ if ( escaped ) repaired = repaired . slice ( 0 , - 1 ) ;
165+ if ( inString ) repaired += '"' ;
166+
167+ while ( stack . length > 0 ) {
168+ repaired = repaired . replace ( / , \s * $ / , '' ) ;
169+ repaired += stack . pop ( ) ;
170+ }
171+
172+ return repaired . replace ( / , \s * ( [ } \] ] ) / g, '$1' ) ;
173+ }
174+
121175function decodeJsonString ( value : string ) : string {
122176 try {
123177 return JSON . parse ( `"${ value . replace ( / " / g, '\\"' ) } "` ) as string ;
0 commit comments