@@ -37,6 +37,29 @@ function normalizeArray(parts, allowAboveRoot) {
3737 return res ;
3838}
3939
40+ // Returns an array with empty elements removed from either end of the input
41+ // array or the original array if no elements need to be removed
42+ function trimArray ( arr ) {
43+ var lastIndex = arr . length - 1 ;
44+ var start = 0 ;
45+ for ( ; start <= lastIndex ; start ++ ) {
46+ if ( arr [ start ] )
47+ break ;
48+ }
49+
50+ var end = lastIndex ;
51+ for ( ; end >= 0 ; end -- ) {
52+ if ( arr [ end ] )
53+ break ;
54+ }
55+
56+ if ( start === 0 && end === lastIndex )
57+ return arr ;
58+ if ( start > end )
59+ return [ ] ;
60+ return arr . slice ( start , end + 1 ) ;
61+ }
62+
4063// Regex to split a windows path into three parts: [*, device, slash,
4164// tail] windows-only
4265const splitDeviceRe =
@@ -62,9 +85,21 @@ function win32SplitPath(filename) {
6285 return [ device , dir , basename , ext ] ;
6386}
6487
65- var normalizeUNCRoot = function ( device ) {
88+ function win32StatPath ( path ) {
89+ var result = splitDeviceRe . exec ( path ) ,
90+ device = result [ 1 ] || '' ,
91+ isUnc = ! ! device && device [ 1 ] !== ':' ;
92+ return {
93+ device,
94+ isUnc,
95+ isAbsolute : isUnc || ! ! result [ 2 ] , // UNC paths are always absolute
96+ tail : result [ 3 ]
97+ } ;
98+ }
99+
100+ function normalizeUNCRoot ( device ) {
66101 return '\\\\' + device . replace ( / ^ [ \\ \/ ] + / , '' ) . replace ( / [ \\ \/ ] + / g, '\\' ) ;
67- } ;
102+ }
68103
69104// path.resolve([from ...], to)
70105win32 . resolve = function ( ) {
@@ -99,11 +134,11 @@ win32.resolve = function() {
99134 continue ;
100135 }
101136
102- var result = splitDeviceRe . exec ( path ) ,
103- device = result [ 1 ] || '' ,
104- isUnc = device && device . charAt ( 1 ) !== ':' ,
105- isAbsolute = win32 . isAbsolute ( path ) ,
106- tail = result [ 3 ] ;
137+ var result = win32StatPath ( path ) ,
138+ device = result . device ,
139+ isUnc = result . isUnc ,
140+ isAbsolute = result . isAbsolute ,
141+ tail = result . tail ;
107142
108143 if ( device &&
109144 resolvedDevice &&
@@ -147,11 +182,11 @@ win32.resolve = function() {
147182win32 . normalize = function ( path ) {
148183 assertPath ( path ) ;
149184
150- var result = splitDeviceRe . exec ( path ) ,
151- device = result [ 1 ] || '' ,
152- isUnc = device && device . charAt ( 1 ) !== ':' ,
153- isAbsolute = win32 . isAbsolute ( path ) ,
154- tail = result [ 3 ] ,
185+ var result = win32StatPath ( path ) ,
186+ device = result . device ,
187+ isUnc = result . isUnc ,
188+ isAbsolute = result . isAbsolute ,
189+ tail = result . tail ,
155190 trailingSlash = / [ \\ \/ ] $ / . test ( tail ) ;
156191
157192 // Normalize the tail path
@@ -176,23 +211,19 @@ win32.normalize = function(path) {
176211
177212win32 . isAbsolute = function ( path ) {
178213 assertPath ( path ) ;
179-
180- var result = splitDeviceRe . exec ( path ) ,
181- device = result [ 1 ] || '' ,
182- isUnc = ! ! device && device . charAt ( 1 ) !== ':' ;
183- // UNC paths are always absolute
184- return ! ! result [ 2 ] || isUnc ;
214+ return win32StatPath ( path ) . isAbsolute ;
185215} ;
186216
187217win32 . join = function ( ) {
188- function f ( p ) {
189- if ( typeof p !== 'string' ) {
190- throw new TypeError ( 'Arguments to path.join must be strings' ) ;
218+ var paths = [ ] ;
219+ for ( var i = 0 ; i < arguments . length ; i ++ ) {
220+ var arg = arguments [ i ] ;
221+ assertPath ( arg ) ;
222+ if ( arg ) {
223+ paths . push ( arg ) ;
191224 }
192- return p ;
193225 }
194226
195- var paths = Array . prototype . filter . call ( arguments , f ) ;
196227 var joined = paths . join ( '\\' ) ;
197228
198229 // Make sure that the joined path doesn't start with two slashes, because
@@ -232,25 +263,10 @@ win32.relative = function(from, to) {
232263 var lowerFrom = from . toLowerCase ( ) ;
233264 var lowerTo = to . toLowerCase ( ) ;
234265
235- function trim ( arr ) {
236- var start = 0 ;
237- for ( ; start < arr . length ; start ++ ) {
238- if ( arr [ start ] !== '' ) break ;
239- }
240-
241- var end = arr . length - 1 ;
242- for ( ; end >= 0 ; end -- ) {
243- if ( arr [ end ] !== '' ) break ;
244- }
245-
246- if ( start > end ) return [ ] ;
247- return arr . slice ( start , end + 1 ) ;
248- }
266+ var toParts = trimArray ( to . split ( '\\' ) ) ;
249267
250- var toParts = trim ( to . split ( '\\' ) ) ;
251-
252- var lowerFromParts = trim ( lowerFrom . split ( '\\' ) ) ;
253- var lowerToParts = trim ( lowerTo . split ( '\\' ) ) ;
268+ var lowerFromParts = trimArray ( lowerFrom . split ( '\\' ) ) ;
269+ var lowerToParts = trimArray ( lowerTo . split ( '\\' ) ) ;
254270
255271 var length = Math . min ( lowerFromParts . length , lowerToParts . length ) ;
256272 var samePartsLength = length ;
@@ -356,15 +372,13 @@ win32.format = function(pathObject) {
356372
357373 var dir = pathObject . dir ;
358374 var base = pathObject . base || '' ;
359- if ( dir . slice ( dir . length - 1 , dir . length ) === win32 . sep ) {
360- return dir + base ;
375+ if ( ! dir ) {
376+ return base ;
361377 }
362-
363- if ( dir ) {
364- return dir + win32 . sep + base ;
378+ if ( dir [ dir . length - 1 ] === win32 . sep ) {
379+ return dir + base ;
365380 }
366-
367- return base ;
381+ return dir + win32 . sep + base ;
368382} ;
369383
370384
@@ -377,7 +391,7 @@ win32.parse = function(pathString) {
377391 }
378392 return {
379393 root : allParts [ 0 ] ,
380- dir : allParts [ 0 ] + allParts [ 1 ] . slice ( 0 , allParts [ 1 ] . length - 1 ) ,
394+ dir : allParts [ 0 ] + allParts [ 1 ] . slice ( 0 , - 1 ) ,
381395 base : allParts [ 2 ] ,
382396 ext : allParts [ 3 ] ,
383397 name : allParts [ 2 ] . slice ( 0 , allParts [ 2 ] . length - allParts [ 3 ] . length )
@@ -418,7 +432,7 @@ posix.resolve = function() {
418432 }
419433
420434 resolvedPath = path + '/' + resolvedPath ;
421- resolvedAbsolute = path . charAt ( 0 ) === '/' ;
435+ resolvedAbsolute = path [ 0 ] === '/' ;
422436 }
423437
424438 // At this point the path should be resolved to a full absolute path, but
@@ -437,7 +451,7 @@ posix.normalize = function(path) {
437451 assertPath ( path ) ;
438452
439453 var isAbsolute = posix . isAbsolute ( path ) ,
440- trailingSlash = path . substr ( - 1 ) === '/' ;
454+ trailingSlash = path && path [ path . length - 1 ] === '/' ;
441455
442456 // Normalize the path
443457 path = normalizeArray ( path . split ( '/' ) , ! isAbsolute ) . join ( '/' ) ;
@@ -455,7 +469,7 @@ posix.normalize = function(path) {
455469// posix version
456470posix . isAbsolute = function ( path ) {
457471 assertPath ( path ) ;
458- return path . charAt ( 0 ) === '/' ;
472+ return ! ! path && path [ 0 ] === '/' ;
459473} ;
460474
461475// posix version
@@ -487,23 +501,8 @@ posix.relative = function(from, to) {
487501 from = posix . resolve ( from ) . substr ( 1 ) ;
488502 to = posix . resolve ( to ) . substr ( 1 ) ;
489503
490- function trim ( arr ) {
491- var start = 0 ;
492- for ( ; start < arr . length ; start ++ ) {
493- if ( arr [ start ] !== '' ) break ;
494- }
495-
496- var end = arr . length - 1 ;
497- for ( ; end >= 0 ; end -- ) {
498- if ( arr [ end ] !== '' ) break ;
499- }
500-
501- if ( start > end ) return [ ] ;
502- return arr . slice ( start , end + 1 ) ;
503- }
504-
505- var fromParts = trim ( from . split ( '/' ) ) ;
506- var toParts = trim ( to . split ( '/' ) ) ;
504+ var fromParts = trimArray ( from . split ( '/' ) ) ;
505+ var toParts = trimArray ( to . split ( '/' ) ) ;
507506
508507 var length = Math . min ( fromParts . length , toParts . length ) ;
509508 var samePartsLength = length ;
@@ -602,7 +601,7 @@ posix.parse = function(pathString) {
602601
603602 return {
604603 root : allParts [ 0 ] ,
605- dir : allParts [ 0 ] + allParts [ 1 ] . slice ( 0 , allParts [ 1 ] . length - 1 ) ,
604+ dir : allParts [ 0 ] + allParts [ 1 ] . slice ( 0 , - 1 ) ,
606605 base : allParts [ 2 ] ,
607606 ext : allParts [ 3 ] ,
608607 name : allParts [ 2 ] . slice ( 0 , allParts [ 2 ] . length - allParts [ 3 ] . length )
0 commit comments