Skip to content

Commit d2979b5

Browse files
authored
[fix] Special case the file: protocol (#204)
Fixes #203
1 parent 9f43f43 commit d2979b5

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

index.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var rules = [
3333
['#', 'hash'], // Extract from the back.
3434
['?', 'query'], // Extract from the back.
3535
function sanitize(address) { // Sanitize what is left of the address
36-
return address.replace('\\', '/');
36+
return address.replace(/\\/g, '/');
3737
},
3838
['/', 'pathname'], // Extract from the back.
3939
['@', 'auth', 1], // Extract from the front.
@@ -224,7 +224,9 @@ function Url(address, location, parser) {
224224
// When the authority component is absent the URL starts with a path
225225
// component.
226226
//
227-
if (!extracted.slashes) instructions[3] = [/(.*)/, 'pathname'];
227+
if (!extracted.slashes || url.protocol === 'file:') {
228+
instructions[3] = [/(.*)/, 'pathname'];
229+
}
228230

229231
for (; i < instructions.length; i++) {
230232
instruction = instructions[i];
@@ -288,7 +290,10 @@ function Url(address, location, parser) {
288290
// Default to a / for pathname if none exists. This normalizes the URL
289291
// to always have a /
290292
//
291-
if (url.pathname.charAt(0) !== '/' && url.hostname) {
293+
if (
294+
url.pathname.charAt(0) !== '/'
295+
&& (url.hostname || url.protocol === 'file:')
296+
) {
292297
url.pathname = '/' + url.pathname;
293298
}
294299

@@ -430,7 +435,7 @@ function toString(stringify) {
430435

431436
if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':';
432437

433-
var result = protocol + (url.slashes ? '//' : '');
438+
var result = protocol + (url.slashes || url.protocol === 'file:' ? '//' : '');
434439

435440
if (url.username) {
436441
result += url.username;

test/test.js

+42
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,48 @@ describe('url-parse', function () {
438438
data.set('protocol', 'https:');
439439
assume(data.href).equals('https://google.com/foo');
440440
});
441+
442+
it('handles the file: protocol', function () {
443+
var slashes = ['', '/', '//', '///', '////', '/////'];
444+
var data;
445+
var url;
446+
447+
for (var i = 0; i < slashes.length; i++) {
448+
data = parse('file:' + slashes[i]);
449+
assume(data.protocol).equals('file:');
450+
assume(data.pathname).equals('/');
451+
assume(data.href).equals('file:///');
452+
}
453+
454+
url = 'file:///Users/foo/BAR/baz.pdf';
455+
data = parse(url);
456+
assume(data.protocol).equals('file:');
457+
assume(data.pathname).equals('/Users/foo/BAR/baz.pdf');
458+
assume(data.href).equals(url);
459+
460+
url = 'file:///foo/bar?baz=qux#hash';
461+
data = parse(url);
462+
assume(data.protocol).equals('file:');
463+
assume(data.hash).equals('#hash');
464+
assume(data.query).equals('?baz=qux');
465+
assume(data.pathname).equals('/foo/bar');
466+
assume(data.href).equals(url);
467+
468+
data = parse('file://c:\\foo\\bar\\');
469+
assume(data.protocol).equals('file:');
470+
assume(data.pathname).equals('/c:/foo/bar/');
471+
assume(data.href).equals('file:///c:/foo/bar/');
472+
473+
data = parse('foo/bar', 'file:///baz');
474+
assume(data.protocol).equals('file:');
475+
assume(data.pathname).equals('/foo/bar');
476+
assume(data.href).equals('file:///foo/bar');
477+
478+
data = parse('foo/bar', 'file:///baz/');
479+
assume(data.protocol).equals('file:');
480+
assume(data.pathname).equals('/baz/foo/bar');
481+
assume(data.href).equals('file:///baz/foo/bar');
482+
});
441483
});
442484

443485
describe('ip', function () {

0 commit comments

Comments
 (0)