@@ -120,8 +120,38 @@ export default function normalizeUrl(urlString, options) {
120
120
}
121
121
122
122
// Remove duplicate slashes if not preceded by a protocol
123
+ // NOTE: This could be implemented using a single negative lookbehind
124
+ // regex, but we avoid that to maintain compatibility with older js engines
125
+ // which do not have support for that feature.
123
126
if ( urlObject . pathname ) {
124
- urlObject . pathname = urlObject . pathname . replace ( / (?< ! \b [ a - z ] [ a - z \d + \- . ] { 1 , 50 } : ) \/ { 2 , } / g, '/' ) ;
127
+ // TODO: Replace everything below with `urlObject.pathname = urlObject.pathname.replace(/(?<!\b[a-z][a-z\d+\-.]{1,50}:)\/{2,}/g, '/');` when Safari supports negative lookbehind.
128
+
129
+ // Split the string by occurrences of this protocol regex, and perform
130
+ // duplicate-slash replacement on the strings between those occurrences
131
+ // (if any).
132
+ const protocolRegex = / \b [ a - z ] [ a - z \d + \- . ] { 1 , 50 } : \/ \/ / g;
133
+
134
+ let lastIndex = 0 ;
135
+ let result = '' ;
136
+ for ( ; ; ) {
137
+ const match = protocolRegex . exec ( urlObject . pathname ) ;
138
+ if ( ! match ) {
139
+ break ;
140
+ }
141
+
142
+ const protocol = match [ 0 ] ;
143
+ const protocolAtIndex = match . index ;
144
+ const intermediate = urlObject . pathname . slice ( lastIndex , protocolAtIndex ) ;
145
+
146
+ result += intermediate . replace ( / \/ { 2 , } / g, '/' ) ;
147
+ result += protocol ;
148
+ lastIndex = protocolAtIndex + protocol . length ;
149
+ }
150
+
151
+ const remnant = urlObject . pathname . slice ( lastIndex , urlObject . pathname . length ) ;
152
+ result += remnant . replace ( / \/ { 2 , } / g, '/' ) ;
153
+
154
+ urlObject . pathname = result ;
125
155
}
126
156
127
157
// Decode URI octets
0 commit comments