"use strict" ;
Object . defineProperty ( exports , "__esModule" , {
value : true
} ) ;
exports . parseFuncIRI = parseFuncIRI ;
exports . default = collectDependencies ;
function _posthtml ( ) {
const data = _interopRequireDefault ( require ( "posthtml" ) ) ;
_posthtml = function ( ) {
return data ;
} ;
return data ;
}
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { default : obj } ; }
// A list of all attributes that may produce a dependency
// Based on https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
// See also https://www.w3.org/TR/SVG/attindex.html and https://www.w3.org/TR/SVG11/attindex.html
// SVG animation elements are excluded because they may only reference elements in the same document: https://www.w3.org/TR/SVG/linking.html#processingURL-fetch
const HREF _ATTRS = [ 'a' , 'use' , 'feImage' , 'image' , 'linearGradient' , 'radialGradient' , 'pattern' , 'mpath' , 'textPath' , 'script' ] ;
const ATTRS = {
href : HREF _ATTRS ,
'xlink:href' : [ ... HREF _ATTRS , 'altGlyph' , 'cursor' , 'filter' , 'font-face-uri' , 'glyphRef' , 'tref' , 'color-profile' ]
} ; // Attributes that allow url() to reference another element, either in the same document or a different one.
// https://www.w3.org/TR/SVG11/linking.html#processingIRI
const FUNC _IRI _ATTRS = new Set ( [ 'fill' , 'stroke' , 'clip-path' , 'color-profile' , 'cursor' , 'filter' , 'marker' , 'marker-start' , 'marker-mid' , 'marker-end' , 'mask' , // SVG2 - https://www.w3.org/TR/SVG/linking.html#processingURL-validity
'shape-inside' , 'shape-subtract' , 'mask-image' ] ) ; // https://www.w3.org/TR/css3-values/#urls
const FUNC _IRI _RE = /^url\((?:((['"])(.*?)\2(\s+.*)?)|((?:\\[\s'"]|[^\s'"])+))\)$/ ;
const ESCAPE _RE = /\\(.|\n|\r|\u2028|\u2029)/ ;
function parseFuncIRI ( value ) {
let m = value . match ( FUNC _IRI _RE ) ;
if ( m ) {
var _m$ ;
let url = ( m [ 3 ] || m [ 5 ] ) . replace ( ESCAPE _RE , '$1' ) ;
let modifier = ( _m$ = m [ 4 ] ) !== null && _m$ !== void 0 ? _m$ : '' ;
return [ url , modifier ] ;
}
} // Options to be passed to `addDependency` for certain tags + attributes
const OPTIONS = {
a : {
href : {
needsStableName : true
} ,
'xlink:href' : {
needsStableName : true
}
}
} ;
function collectDependencies ( asset , ast ) {
let isDirty = false ;
( 0 , _posthtml ( ) . default ) ( ) . walk . call ( ast . program , node => {
// Ideally we'd have location information for specific attributes...
let getLoc = ( ) => node . location ? {
filePath : asset . filePath ,
start : node . location . start ,
end : node . location . end
} : undefined ;
if ( typeof node === 'string' && node . startsWith ( '<?xml-stylesheet' ) ) {
return node . replace ( /(?<=(?:^|\s)href\s*=\s*")(.+?)(?=")/i , href => {
isDirty = true ;
return asset . addURLDependency ( href , {
priority : 'parallel'
} ) ;
} ) ;
}
const {
tag ,
attrs
} = node ;
if ( ! attrs ) {
return node ;
}
for ( const attr in attrs ) {
// Check for id references
if ( attrs [ attr ] [ 0 ] === '#' ) {
continue ;
}
const elements = ATTRS [ attr ] ;
if ( elements && elements . includes ( node . tag ) ) {
var _OPTIONS$tag ;
let options = ( _OPTIONS$tag = OPTIONS [ tag ] ) === null || _OPTIONS$tag === void 0 ? void 0 : _OPTIONS$tag [ attr ] ;
if ( node . tag === 'script' ) {
options = {
priority : 'parallel' ,
env : {
sourceType : attrs . type === 'module' ? 'module' : 'script' ,
// SVG script elements do not support type="module" natively yet.
outputFormat : 'global' ,
loc : getLoc ( )
}
} ;
delete attrs . type ;
}
attrs [ attr ] = asset . addURLDependency ( attrs [ attr ] , { ... options ,
loc : getLoc ( )
} ) ;
isDirty = true ;
}
if ( FUNC _IRI _ATTRS . has ( attr ) ) {
let parsed = parseFuncIRI ( attrs [ attr ] ) ;
if ( parsed ) {
let depId = asset . addURLDependency ( parsed [ 0 ] , {
loc : getLoc ( )
} ) ;
attrs [ attr ] = ` url(' ${ depId } ' ${ parsed [ 1 ] } ) ` ;
isDirty = true ;
}
}
}
return node ;
} ) ;
if ( isDirty ) {
asset . setAST ( ast ) ;
}
}