Skip to content

Commit d51cb50

Browse files
frebensindresorhus
andauthored
Fix Safari compatibility (#148)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 3fb24bb commit d51cb50

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

index.js

+31-1
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,38 @@ export default function normalizeUrl(urlString, options) {
120120
}
121121

122122
// 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.
123126
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;
125155
}
126156

127157
// Decode URI octets

0 commit comments

Comments
 (0)