@@ -4,129 +4,104 @@ import {
44 getFilter ,
55 normalizeUrl ,
66 requestify ,
7- isUrlRequestable ,
87 stringifyRequest ,
9- typeSrc ,
10- typeSrcset ,
118} from '../utils' ;
129
1310export default ( options ) =>
1411 function process ( html ) {
15- const { list, urlFilter : maybeUrlFilter } = options . sources ;
16- const sources = [ ] ;
17- const urlFilter = getFilter ( maybeUrlFilter , ( value ) =>
18- isUrlRequestable ( value )
19- ) ;
20- const getAttribute = ( tag , attribute , attributes , resourcePath ) => {
21- const foundTag = list . get ( tag . toLowerCase ( ) ) || list . get ( '*' ) ;
22-
23- if ( ! foundTag ) {
24- return false ;
25- }
26-
27- const foundAttribute = foundTag . get ( attribute . toLowerCase ( ) ) ;
28-
29- if ( ! foundAttribute ) {
30- return false ;
31- }
32-
33- const result = foundAttribute . filter
34- ? foundAttribute . filter ( tag , attribute , attributes , resourcePath )
35- : true ;
36-
37- return result ? foundAttribute : false ;
38- } ;
39-
40- const { resourcePath } = options ;
4112 const parser5 = new SAXParser ( { sourceCodeLocationInfo : true } ) ;
13+ const sources = [ ] ;
4214
4315 parser5 . on ( 'startTag' , ( node ) => {
44- const { tagName, attrs, sourceCodeLocation } = node ;
16+ const { tagName, attrs : attributes , sourceCodeLocation } = node ;
4517
46- attrs . forEach ( ( attribute ) => {
47- const { prefix } = attribute ;
18+ attributes . forEach ( ( attribute ) => {
4819 let { name } = attribute ;
4920
50- name = prefix ? `${ prefix } :${ name } ` : name ;
21+ name = attribute . prefix ? `${ attribute . prefix } :${ name } ` : name ;
5122
52- if ( ! sourceCodeLocation . attrs [ name ] ) {
23+ const handlers =
24+ options . sources . list . get ( tagName . toLowerCase ( ) ) ||
25+ options . sources . list . get ( '*' ) ;
26+
27+ if ( ! handlers ) {
5328 return ;
5429 }
5530
56- const foundAttribute = getAttribute ( tagName , name , attrs , resourcePath ) ;
31+ const handler = handlers . get ( name . toLowerCase ( ) ) ;
5732
58- if ( ! foundAttribute ) {
33+ if ( ! handler ) {
5934 return ;
6035 }
6136
62- const { type } = foundAttribute ;
37+ if (
38+ handler . filter &&
39+ ! handler . filter ( tagName , name , attributes , options . resourcePath )
40+ ) {
41+ return ;
42+ }
6343
64- const target = html . slice (
44+ const attributeAndValue = html . slice (
6545 sourceCodeLocation . attrs [ name ] . startOffset ,
6646 sourceCodeLocation . attrs [ name ] . endOffset
6747 ) ;
48+ const isValueQuoted =
49+ attributeAndValue [ attributeAndValue . length - 1 ] === '"' ||
50+ attributeAndValue [ attributeAndValue . length - 1 ] === "'" ;
51+ const valueStartOffset =
52+ sourceCodeLocation . attrs [ name ] . startOffset +
53+ attributeAndValue . indexOf ( attribute . value ) ;
54+ const valueEndOffset =
55+ sourceCodeLocation . attrs [ name ] . endOffset - ( isValueQuoted ? 1 : 0 ) ;
56+ const optionsForTypeFn = {
57+ tag : tagName ,
58+ isSelfClosing : node . selfClosing ,
59+ tagStartOffset : sourceCodeLocation . startOffset ,
60+ tagEndOffset : sourceCodeLocation . endOffset ,
61+ attributes,
62+ attribute : name ,
63+ attributePrefix : attribute . prefix ,
64+ attributeNamespace : attribute . namespace ,
65+ attributeStartOffset : sourceCodeLocation . attrs [ name ] . startOffset ,
66+ attributeEndOffset : sourceCodeLocation . attrs [ name ] . endOffset ,
67+ value : attribute . value ,
68+ isValueQuoted,
69+ valueEndOffset,
70+ valueStartOffset,
71+ html,
72+ } ;
73+
74+ let result ;
75+
76+ try {
77+ result = handler . type ( optionsForTypeFn ) ;
78+ } catch ( error ) {
79+ options . errors . push ( error ) ;
80+ }
6881
69- const unquoted =
70- target [ target . length - 1 ] !== '"' &&
71- target [ target . length - 1 ] !== "'" ;
72-
73- const result = [ ] ;
74-
75- // eslint-disable-next-line default-case
76- switch ( type ) {
77- case 'src' : {
78- typeSrc ( { name, attribute, node, target, html, options } ) . forEach (
79- ( i ) => {
80- result . push ( i ) ;
81- }
82- ) ;
83- break ;
84- }
85-
86- case 'srcset' : {
87- typeSrcset ( {
88- name,
89- attribute,
90- node,
91- target,
92- html,
93- options,
94- } ) . forEach ( ( i ) => {
95- result . push ( i ) ;
96- } ) ;
97- break ;
98- }
82+ result = Array . isArray ( result ) ? result : [ result ] ;
9983
100- default : {
101- type ( { name, attribute, node, target, html, options } ) . forEach (
102- ( i ) => {
103- result . push ( i ) ;
104- }
105- ) ;
84+ for ( const source of result ) {
85+ if ( ! source ) {
86+ // eslint-disable-next-line no-continue
87+ continue ;
10688 }
107- }
10889
109- for ( const i of result ) {
110- if ( i ) {
111- sources . push ( {
112- ...i ,
113- name,
114- unquoted,
115- } ) ;
116- }
90+ sources . push ( { ...source , name, isValueQuoted } ) ;
11791 }
11892 } ) ;
11993 } ) ;
12094
12195 parser5 . end ( html ) ;
12296
97+ const urlFilter = getFilter ( options . sources . urlFilter ) ;
12398 const imports = new Map ( ) ;
12499 const replacements = new Map ( ) ;
125100
126101 let offset = 0 ;
127102
128103 for ( const source of sources ) {
129- const { name, value, unquoted , startIndex , endIndex } = source ;
104+ const { name, value, isValueQuoted , startOffset , endOffset } = source ;
130105
131106 let normalizedUrl = value ;
132107 let prefix = '' ;
@@ -140,7 +115,7 @@ export default (options) =>
140115
141116 normalizedUrl = normalizeUrl ( normalizedUrl ) ;
142117
143- if ( ! urlFilter ( name , value , resourcePath ) ) {
118+ if ( ! urlFilter ( name , value , options . resourcePath ) ) {
144119 // eslint-disable-next-line no-continue
145120 continue ;
146121 }
@@ -168,7 +143,7 @@ export default (options) =>
168143 } ) ;
169144 }
170145
171- const replacementKey = JSON . stringify ( { newUrl, unquoted , hash } ) ;
146+ const replacementKey = JSON . stringify ( { newUrl, isValueQuoted , hash } ) ;
172147 let replacementName = replacements . get ( replacementKey ) ;
173148
174149 if ( ! replacementName ) {
@@ -179,17 +154,17 @@ export default (options) =>
179154 replacementName,
180155 importName,
181156 hash,
182- unquoted ,
157+ isValueQuoted ,
183158 } ) ;
184159 }
185160
186161 // eslint-disable-next-line no-param-reassign
187162 html =
188- html . slice ( 0 , startIndex + offset ) +
163+ html . slice ( 0 , startOffset + offset ) +
189164 replacementName +
190- html . slice ( endIndex + offset ) ;
165+ html . slice ( endOffset + offset ) ;
191166
192- offset += startIndex + replacementName . length - endIndex ;
167+ offset += startOffset + replacementName . length - endOffset ;
193168 }
194169
195170 return html ;
0 commit comments