Skip to content

Commit 94f6fc6

Browse files
author
James Halliday
committed
initial piece ripped out of browser-builtins
0 parents  commit 94f6fc6

File tree

1 file changed

+209
-0
lines changed

1 file changed

+209
-0
lines changed

index.js

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
var util = require('util');
23+
var shims = require('_shims');
24+
25+
// resolves . and .. elements in a path array with directory names there
26+
// must be no slashes, empty elements, or device names (c:\) in the array
27+
// (so also no leading and trailing slashes - it does not distinguish
28+
// relative and absolute paths)
29+
function normalizeArray(parts, allowAboveRoot) {
30+
// if the path tries to go above the root, `up` ends up > 0
31+
var up = 0;
32+
for (var i = parts.length - 1; i >= 0; i--) {
33+
var last = parts[i];
34+
if (last === '.') {
35+
parts.splice(i, 1);
36+
} else if (last === '..') {
37+
parts.splice(i, 1);
38+
up++;
39+
} else if (up) {
40+
parts.splice(i, 1);
41+
up--;
42+
}
43+
}
44+
45+
// if the path is allowed to go above the root, restore leading ..s
46+
if (allowAboveRoot) {
47+
for (; up--; up) {
48+
parts.unshift('..');
49+
}
50+
}
51+
52+
return parts;
53+
}
54+
55+
// Split a filename into [root, dir, basename, ext], unix version
56+
// 'root' is just a slash, or nothing.
57+
var splitPathRe =
58+
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
59+
var splitPath = function(filename) {
60+
return splitPathRe.exec(filename).slice(1);
61+
};
62+
63+
// path.resolve([from ...], to)
64+
// posix version
65+
exports.resolve = function() {
66+
var resolvedPath = '',
67+
resolvedAbsolute = false;
68+
69+
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
70+
var path = (i >= 0) ? arguments[i] : process.cwd();
71+
72+
// Skip empty and invalid entries
73+
if (!util.isString(path)) {
74+
throw new TypeError('Arguments to path.resolve must be strings');
75+
} else if (!path) {
76+
continue;
77+
}
78+
79+
resolvedPath = path + '/' + resolvedPath;
80+
resolvedAbsolute = path.charAt(0) === '/';
81+
}
82+
83+
// At this point the path should be resolved to a full absolute path, but
84+
// handle relative paths to be safe (might happen when process.cwd() fails)
85+
86+
// Normalize the path
87+
resolvedPath = normalizeArray(shims.filter(resolvedPath.split('/'), function(p) {
88+
return !!p;
89+
}), !resolvedAbsolute).join('/');
90+
91+
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
92+
};
93+
94+
// path.normalize(path)
95+
// posix version
96+
exports.normalize = function(path) {
97+
var isAbsolute = exports.isAbsolute(path),
98+
trailingSlash = shims.substr(path, -1) === '/';
99+
100+
// Normalize the path
101+
path = normalizeArray(shims.filter(path.split('/'), function(p) {
102+
return !!p;
103+
}), !isAbsolute).join('/');
104+
105+
if (!path && !isAbsolute) {
106+
path = '.';
107+
}
108+
if (path && trailingSlash) {
109+
path += '/';
110+
}
111+
112+
return (isAbsolute ? '/' : '') + path;
113+
};
114+
115+
// posix version
116+
exports.isAbsolute = function(path) {
117+
return path.charAt(0) === '/';
118+
};
119+
120+
// posix version
121+
exports.join = function() {
122+
var paths = Array.prototype.slice.call(arguments, 0);
123+
return exports.normalize(shims.filter(paths, function(p, index) {
124+
if (!util.isString(p)) {
125+
throw new TypeError('Arguments to path.join must be strings');
126+
}
127+
return p;
128+
}).join('/'));
129+
};
130+
131+
132+
// path.relative(from, to)
133+
// posix version
134+
exports.relative = function(from, to) {
135+
from = exports.resolve(from).substr(1);
136+
to = exports.resolve(to).substr(1);
137+
138+
function trim(arr) {
139+
var start = 0;
140+
for (; start < arr.length; start++) {
141+
if (arr[start] !== '') break;
142+
}
143+
144+
var end = arr.length - 1;
145+
for (; end >= 0; end--) {
146+
if (arr[end] !== '') break;
147+
}
148+
149+
if (start > end) return [];
150+
return arr.slice(start, end - start + 1);
151+
}
152+
153+
var fromParts = trim(from.split('/'));
154+
var toParts = trim(to.split('/'));
155+
156+
var length = Math.min(fromParts.length, toParts.length);
157+
var samePartsLength = length;
158+
for (var i = 0; i < length; i++) {
159+
if (fromParts[i] !== toParts[i]) {
160+
samePartsLength = i;
161+
break;
162+
}
163+
}
164+
165+
var outputParts = [];
166+
for (var i = samePartsLength; i < fromParts.length; i++) {
167+
outputParts.push('..');
168+
}
169+
170+
outputParts = outputParts.concat(toParts.slice(samePartsLength));
171+
172+
return outputParts.join('/');
173+
};
174+
175+
exports.sep = '/';
176+
exports.delimiter = ':';
177+
178+
exports.dirname = function(path) {
179+
var result = splitPath(path),
180+
root = result[0],
181+
dir = result[1];
182+
183+
if (!root && !dir) {
184+
// No dirname whatsoever
185+
return '.';
186+
}
187+
188+
if (dir) {
189+
// It has a dirname, strip trailing slash
190+
dir = dir.substr(0, dir.length - 1);
191+
}
192+
193+
return root + dir;
194+
};
195+
196+
197+
exports.basename = function(path, ext) {
198+
var f = splitPath(path)[2];
199+
// TODO: make this comparison case-insensitive on windows?
200+
if (ext && f.substr(-1 * ext.length) === ext) {
201+
f = f.substr(0, f.length - ext.length);
202+
}
203+
return f;
204+
};
205+
206+
207+
exports.extname = function(path) {
208+
return splitPath(path)[3];
209+
};

0 commit comments

Comments
 (0)