@@ -4,129 +4,104 @@ import {
4
4
getFilter ,
5
5
normalizeUrl ,
6
6
requestify ,
7
- isUrlRequestable ,
8
7
stringifyRequest ,
9
- typeSrc ,
10
- typeSrcset ,
11
8
} from '../utils' ;
12
9
13
10
export default ( options ) =>
14
11
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 ;
41
12
const parser5 = new SAXParser ( { sourceCodeLocationInfo : true } ) ;
13
+ const sources = [ ] ;
42
14
43
15
parser5 . on ( 'startTag' , ( node ) => {
44
- const { tagName, attrs, sourceCodeLocation } = node ;
16
+ const { tagName, attrs : attributes , sourceCodeLocation } = node ;
45
17
46
- attrs . forEach ( ( attribute ) => {
47
- const { prefix } = attribute ;
18
+ attributes . forEach ( ( attribute ) => {
48
19
let { name } = attribute ;
49
20
50
- name = prefix ? `${ prefix } :${ name } ` : name ;
21
+ name = attribute . prefix ? `${ attribute . prefix } :${ name } ` : name ;
51
22
52
- if ( ! sourceCodeLocation . attrs [ name ] ) {
23
+ const handlers =
24
+ options . sources . list . get ( tagName . toLowerCase ( ) ) ||
25
+ options . sources . list . get ( '*' ) ;
26
+
27
+ if ( ! handlers ) {
53
28
return ;
54
29
}
55
30
56
- const foundAttribute = getAttribute ( tagName , name , attrs , resourcePath ) ;
31
+ const handler = handlers . get ( name . toLowerCase ( ) ) ;
57
32
58
- if ( ! foundAttribute ) {
33
+ if ( ! handler ) {
59
34
return ;
60
35
}
61
36
62
- const { type } = foundAttribute ;
37
+ if (
38
+ handler . filter &&
39
+ ! handler . filter ( tagName , name , attributes , options . resourcePath )
40
+ ) {
41
+ return ;
42
+ }
63
43
64
- const target = html . slice (
44
+ const attributeAndValue = html . slice (
65
45
sourceCodeLocation . attrs [ name ] . startOffset ,
66
46
sourceCodeLocation . attrs [ name ] . endOffset
67
47
) ;
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
+ }
68
81
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 ] ;
99
83
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 ;
106
88
}
107
- }
108
89
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 } ) ;
117
91
}
118
92
} ) ;
119
93
} ) ;
120
94
121
95
parser5 . end ( html ) ;
122
96
97
+ const urlFilter = getFilter ( options . sources . urlFilter ) ;
123
98
const imports = new Map ( ) ;
124
99
const replacements = new Map ( ) ;
125
100
126
101
let offset = 0 ;
127
102
128
103
for ( const source of sources ) {
129
- const { name, value, unquoted , startIndex , endIndex } = source ;
104
+ const { name, value, isValueQuoted , startOffset , endOffset } = source ;
130
105
131
106
let normalizedUrl = value ;
132
107
let prefix = '' ;
@@ -140,7 +115,7 @@ export default (options) =>
140
115
141
116
normalizedUrl = normalizeUrl ( normalizedUrl ) ;
142
117
143
- if ( ! urlFilter ( name , value , resourcePath ) ) {
118
+ if ( ! urlFilter ( name , value , options . resourcePath ) ) {
144
119
// eslint-disable-next-line no-continue
145
120
continue ;
146
121
}
@@ -168,7 +143,7 @@ export default (options) =>
168
143
} ) ;
169
144
}
170
145
171
- const replacementKey = JSON . stringify ( { newUrl, unquoted , hash } ) ;
146
+ const replacementKey = JSON . stringify ( { newUrl, isValueQuoted , hash } ) ;
172
147
let replacementName = replacements . get ( replacementKey ) ;
173
148
174
149
if ( ! replacementName ) {
@@ -179,17 +154,17 @@ export default (options) =>
179
154
replacementName,
180
155
importName,
181
156
hash,
182
- unquoted ,
157
+ isValueQuoted ,
183
158
} ) ;
184
159
}
185
160
186
161
// eslint-disable-next-line no-param-reassign
187
162
html =
188
- html . slice ( 0 , startIndex + offset ) +
163
+ html . slice ( 0 , startOffset + offset ) +
189
164
replacementName +
190
- html . slice ( endIndex + offset ) ;
165
+ html . slice ( endOffset + offset ) ;
191
166
192
- offset += startIndex + replacementName . length - endIndex ;
167
+ offset += startOffset + replacementName . length - endOffset ;
193
168
}
194
169
195
170
return html ;
0 commit comments