11/**
22 * Helpers
33 */
4+ const escapeTest = / [ & < > " ' ] / ;
5+ const escapeReplace = / [ & < > " ' ] / g;
6+ const escapeTestNoEncode = / [ < > " ' ] | & (? ! # ? \w + ; ) / ;
7+ const escapeReplaceNoEncode = / [ < > " ' ] | & (? ! # ? \w + ; ) / g;
8+ const escapeReplacements = {
9+ '&' : '&' ,
10+ '<' : '<' ,
11+ '>' : '>' ,
12+ '"' : '"' ,
13+ "'" : '''
14+ } ;
15+ const getEscapeReplacement = ( ch ) => escapeReplacements [ ch ] ;
416function escape ( html , encode ) {
517 if ( encode ) {
6- if ( escape . escapeTest . test ( html ) ) {
7- return html . replace ( escape . escapeReplace , escape . getReplacement ) ;
18+ if ( escapeTest . test ( html ) ) {
19+ return html . replace ( escapeReplace , getEscapeReplacement ) ;
820 }
921 } else {
10- if ( escape . escapeTestNoEncode . test ( html ) ) {
11- return html . replace ( escape . escapeReplaceNoEncode , escape . getReplacement ) ;
22+ if ( escapeTestNoEncode . test ( html ) ) {
23+ return html . replace ( escapeReplaceNoEncode , getEscapeReplacement ) ;
1224 }
1325 }
1426
1527 return html ;
1628}
17- escape . escapeTest = / [ & < > " ' ] / ;
18- escape . escapeReplace = / [ & < > " ' ] / g;
19- escape . escapeTestNoEncode = / [ < > " ' ] | & (? ! # ? \w + ; ) / ;
20- escape . escapeReplaceNoEncode = / [ < > " ' ] | & (? ! # ? \w + ; ) / g;
21- escape . replacements = {
22- '&' : '&' ,
23- '<' : '<' ,
24- '>' : '>' ,
25- '"' : '"' ,
26- "'" : '''
27- } ;
28- escape . getReplacement = ( ch ) => escape . replacements [ ch ] ;
29+
30+ const unescapeTest = / & ( # (?: \d + ) | (?: # x [ 0 - 9 A - F a - f ] + ) | (?: \w + ) ) ; ? / ig;
2931
3032function unescape ( html ) {
3133 // explicitly match decimal, hex, and named HTML entities
32- return html . replace ( unescape . unescapeTest , ( _ , n ) => {
34+ return html . replace ( unescapeTest , ( _ , n ) => {
3335 n = n . toLowerCase ( ) ;
3436 if ( n === 'colon' ) return ':' ;
3537 if ( n . charAt ( 0 ) === '#' ) {
@@ -40,15 +42,15 @@ function unescape(html) {
4042 return '' ;
4143 } ) ;
4244}
43- unescape . unescapeTest = / & ( # (?: \d + ) | (?: # x [ 0 - 9 A - F a - f ] + ) | (?: \w + ) ) ; ? / ig;
4445
46+ const caret = / ( ^ | [ ^ \[ ] ) \^ / g;
4547function edit ( regex , opt ) {
4648 regex = regex . source || regex ;
4749 opt = opt || '' ;
4850 const obj = {
4951 replace : ( name , val ) => {
5052 val = val . source || val ;
51- val = val . replace ( edit . caret , '$1' ) ;
53+ val = val . replace ( caret , '$1' ) ;
5254 regex = regex . replace ( name , val ) ;
5355 return obj ;
5456 } ,
@@ -58,14 +60,15 @@ function edit(regex, opt) {
5860 } ;
5961 return obj ;
6062}
61- edit . caret = / ( ^ | [ ^ \[ ] ) \^ / g;
6263
64+ const nonWordAndColonTest = / [ ^ \w : ] / g;
65+ const originIndependentUrl = / ^ $ | ^ [ a - z ] [ a - z 0 - 9 + . - ] * : | ^ [ ? # ] / i;
6366function cleanUrl ( sanitize , base , href ) {
6467 if ( sanitize ) {
6568 let prot ;
6669 try {
6770 prot = decodeURIComponent ( unescape ( href ) )
68- . replace ( cleanUrl . protocol , '' )
71+ . replace ( nonWordAndColonTest , '' )
6972 . toLowerCase ( ) ;
7073 } catch ( e ) {
7174 return null ;
@@ -74,7 +77,7 @@ function cleanUrl(sanitize, base, href) {
7477 return null ;
7578 }
7679 }
77- if ( base && ! cleanUrl . originIndependentUrl . test ( href ) ) {
80+ if ( base && ! originIndependentUrl . test ( href ) ) {
7881 href = resolveUrl ( base , href ) ;
7982 }
8083 try {
@@ -84,44 +87,42 @@ function cleanUrl(sanitize, base, href) {
8487 }
8588 return href ;
8689}
87- cleanUrl . protocol = / [ ^ \w : ] / g;
88- cleanUrl . originIndependentUrl = / ^ $ | ^ [ a - z ] [ a - z 0 - 9 + . - ] * : | ^ [ ? # ] / i;
90+
91+ const baseUrls = { } ;
92+ const justDomain = / ^ [ ^ : ] + : \/ * [ ^ / ] * $ / ;
93+ const protocol = / ^ ( [ ^ : ] + : ) [ \s \S ] * $ / ;
94+ const domain = / ^ ( [ ^ : ] + : \/ * [ ^ / ] * ) [ \s \S ] * $ / ;
8995
9096function resolveUrl ( base , href ) {
91- if ( ! resolveUrl . baseUrls [ ' ' + base ] ) {
97+ if ( ! baseUrls [ ' ' + base ] ) {
9298 // we can ignore everything in base after the last slash of its path component,
9399 // but we might need to add _that_
94100 // https://tools.ietf.org/html/rfc3986#section-3
95- if ( resolveUrl . justDomain . test ( base ) ) {
96- resolveUrl . baseUrls [ ' ' + base ] = base + '/' ;
101+ if ( justDomain . test ( base ) ) {
102+ baseUrls [ ' ' + base ] = base + '/' ;
97103 } else {
98- resolveUrl . baseUrls [ ' ' + base ] = rtrim ( base , '/' , true ) ;
104+ baseUrls [ ' ' + base ] = rtrim ( base , '/' , true ) ;
99105 }
100106 }
101- base = resolveUrl . baseUrls [ ' ' + base ] ;
107+ base = baseUrls [ ' ' + base ] ;
102108 const relativeBase = base . indexOf ( ':' ) === - 1 ;
103109
104110 if ( href . substring ( 0 , 2 ) === '//' ) {
105111 if ( relativeBase ) {
106112 return href ;
107113 }
108- return base . replace ( resolveUrl . protocol , '$1' ) + href ;
114+ return base . replace ( protocol , '$1' ) + href ;
109115 } else if ( href . charAt ( 0 ) === '/' ) {
110116 if ( relativeBase ) {
111117 return href ;
112118 }
113- return base . replace ( resolveUrl . domain , '$1' ) + href ;
119+ return base . replace ( domain , '$1' ) + href ;
114120 } else {
115121 return base + href ;
116122 }
117123}
118- resolveUrl . baseUrls = { } ;
119- resolveUrl . justDomain = / ^ [ ^ : ] + : \/ * [ ^ / ] * $ / ;
120- resolveUrl . protocol = / ^ ( [ ^ : ] + : ) [ \s \S ] * $ / ;
121- resolveUrl . domain = / ^ ( [ ^ : ] + : \/ * [ ^ / ] * ) [ \s \S ] * $ / ;
122124
123- function noop ( ) { }
124- noop . exec = noop ;
125+ const noopTest = { exec : function noopTest ( ) { } } ;
125126
126127function merge ( obj ) {
127128 let i = 1 ,
@@ -233,7 +234,7 @@ module.exports = {
233234 edit,
234235 cleanUrl,
235236 resolveUrl,
236- noop ,
237+ noopTest ,
237238 merge,
238239 splitCells,
239240 rtrim,
0 commit comments