@@ -43,6 +43,8 @@ const STYLE_PROPS = [
43
43
'strokeLinejoin' ,
44
44
'strokeLinecap' ,
45
45
'strokeDasharray' ,
46
+ 'gradientUnits' ,
47
+ 'gradientTransform' ,
46
48
] ;
47
49
48
50
const VERTICAL_PROPS = [ 'y' , 'y1' , 'y2' , 'height' , 'cy' , 'ry' ] ;
@@ -106,6 +108,7 @@ const parseProps =
106
108
stopOpacity : parsePercent ,
107
109
stopColor : transformColor ,
108
110
transform : parseTransform ( container ) ,
111
+ gradientTransform : parseTransform ( container ) ,
109
112
} ,
110
113
props ,
111
114
) ;
@@ -203,6 +206,48 @@ const resolveChildren =
203
206
return Object . assign ( { } , node , { children } ) ;
204
207
} ;
205
208
209
+ const buildXLinksIndex = ( node : SafeSvgNode ) => {
210
+ const idIndex : Record < string , SafeNode > = { } ;
211
+ const listToExplore : SafeNode [ ] = node . children ?. slice ( 0 ) || [ ] ;
212
+
213
+ while ( listToExplore . length > 0 ) {
214
+ const child = listToExplore . shift ( ) ;
215
+
216
+ if ( child . props && 'id' in child . props ) {
217
+ idIndex [ child . props . id ] = child ;
218
+ }
219
+
220
+ if ( child . children ) listToExplore . push ( ...child . children ) ;
221
+ }
222
+
223
+ return idIndex ;
224
+ } ;
225
+
226
+ const replaceXLinks = ( node : SafeNode , idIndex : Record < string , SafeNode > ) => {
227
+ if ( node . props && 'xlinkHref' in node . props ) {
228
+ const linkedNode = idIndex [ node . props . xlinkHref . replace ( / ^ # / , '' ) ] ;
229
+
230
+ // No node to extend from
231
+ if ( ! linkedNode ) return node ;
232
+
233
+ const newProps = Object . assign ( { } , linkedNode . props , node . props ) ;
234
+
235
+ delete newProps . xlinkHref ;
236
+
237
+ return Object . assign ( { } , linkedNode , { props : newProps } ) ;
238
+ }
239
+
240
+ const children = node . children ?. map ( ( child ) => replaceXLinks ( child , idIndex ) ) ;
241
+
242
+ return Object . assign ( { } , node , { children } ) ;
243
+ } ;
244
+
245
+ export const resolveXLinks = ( node : SafeSvgNode ) : SafeSvgNode => {
246
+ const idIndex = buildXLinksIndex ( node ) ;
247
+
248
+ return replaceXLinks ( node , idIndex ) ;
249
+ } ;
250
+
206
251
const resolveSvgRoot = ( node : SafeSvgNode , fontStore : FontStore ) => {
207
252
const container = getContainer ( node ) ;
208
253
@@ -213,6 +258,7 @@ const resolveSvgRoot = (node: SafeSvgNode, fontStore: FontStore) => {
213
258
pickStyleProps ,
214
259
inheritProps ,
215
260
resolveChildren ( container ) ,
261
+ resolveXLinks ,
216
262
) ( node ) ;
217
263
} ;
218
264
0 commit comments