1
- var doubleSlashWinRegExp = / \\ + / g;
2
- var doubleSlashNixRegExp = / \/ + / g;
3
- var currentDirectoryWinMiddleRegExp = / \\ ( \. \\ ) + / ;
4
- var currentDirectoryWinEndRegExp = / \\ \. $ / ;
5
- var parentDirectoryWinMiddleRegExp = / \\ + [ ^ \\ ] + \\ + \. \. \\ / ;
6
- var parentDirectoryWinEndRegExp1 = / ( [ A - Z ] : \\ ) \\ * [ ^ \\ ] + \\ + \. \. $ / i;
7
- var parentDirectoryWinEndRegExp2 = / \\ + [ ^ \\ ] + \\ + \. \. $ / ;
8
- var currentDirectoryNixMiddleRegExp = / \/ + ( \. \/ ) + / ;
9
- var currentDirectoryNixEndRegExp1 = / ^ \/ + \. $ / ;
10
- var currentDirectoryNixEndRegExp2 = / \/ + \. $ / ;
11
- var parentDirectoryNixMiddleRegExp = / ( ^ | \/ [ ^ \/ ] + ) \/ + \. \. \/ + / ;
12
- var parentDirectoryNixEndRegExp1 = / ^ \/ [ ^ \/ ] + \/ + \. \. $ / ;
13
- var parentDirectoryNixEndRegExp2 = / \/ + [ ^ \/ ] + \/ + \. \. $ / ;
14
- var parentDirectoryNixEndRegExp3 = / ^ \/ + \. \. $ / ;
15
-
16
- // RegExp magic :)
17
-
18
1
module . exports = function normalize ( path ) {
19
- while ( currentDirectoryWinMiddleRegExp . test ( path ) )
20
- path = path . replace ( currentDirectoryWinMiddleRegExp , "\\" ) ;
21
- path = path . replace ( currentDirectoryWinEndRegExp , "" ) ;
22
- while ( parentDirectoryWinMiddleRegExp . test ( path ) )
23
- path = path . replace ( parentDirectoryWinMiddleRegExp , "\\" ) ;
24
- path = path . replace ( parentDirectoryWinEndRegExp1 , "$1" ) ;
25
- path = path . replace ( parentDirectoryWinEndRegExp2 , "" ) ;
26
-
27
- while ( currentDirectoryNixMiddleRegExp . test ( path ) )
28
- path = path . replace ( currentDirectoryNixMiddleRegExp , "/" ) ;
29
- path = path . replace ( currentDirectoryNixEndRegExp1 , "/" ) ;
30
- path = path . replace ( currentDirectoryNixEndRegExp2 , "" ) ;
31
- while ( parentDirectoryNixMiddleRegExp . test ( path ) )
32
- path = path . replace ( parentDirectoryNixMiddleRegExp , "/" ) ;
33
- path = path . replace ( parentDirectoryNixEndRegExp1 , "/" ) ;
34
- path = path . replace ( parentDirectoryNixEndRegExp2 , "" ) ;
35
- path = path . replace ( parentDirectoryNixEndRegExp3 , "/" ) ;
36
-
37
- return path . replace ( doubleSlashWinRegExp , "\\" ) . replace ( doubleSlashNixRegExp , "/" ) ;
38
- } ;
2
+ var parts = path . split ( / ( \\ + | \/ + ) / ) ;
3
+ if ( parts . length === 1 )
4
+ return path ;
5
+ var result = [ ] ;
6
+ var absolutePathStart = 0 ;
7
+ for ( var i = 0 , sep = false ; i < parts . length ; i ++ , sep = ! sep ) {
8
+ var part = parts [ i ] ;
9
+ if ( i === 0 && / ^ ( [ A - Z ] : ) ? $ / i. test ( part ) ) {
10
+ result . push ( part ) ;
11
+ absolutePathStart = 2 ;
12
+ } else if ( sep ) {
13
+ result . push ( part [ 0 ] ) ;
14
+ } else if ( part === ".." ) {
15
+ switch ( result . length ) {
16
+ case 0 :
17
+ // i. e. ".." => ".."
18
+ // i. e. "../a/b/c" => "../a/b/c"
19
+ result . push ( part ) ;
20
+ break ;
21
+ case 2 :
22
+ // i. e. "a/.." => ""
23
+ // i. e. "/.." => "/"
24
+ // i. e. "C:\.." => "C:\"
25
+ // i. e. "a/../b/c" => "b/c"
26
+ // i. e. "/../b/c" => "/b/c"
27
+ // i. e. "C:\..\a\b\c" => "C:\a\b\c"
28
+ i ++ ;
29
+ sep = ! sep ;
30
+ result . length = absolutePathStart ;
31
+ break ;
32
+ case 4 :
33
+ // i. e. "a/b/.." => "a"
34
+ // i. e. "/a/.." => "/"
35
+ // i. e. "C:\a\.." => "C:\"
36
+ // i. e. "/a/../b/c" => "/b/c"
37
+ if ( absolutePathStart === 0 ) {
38
+ result . length -= 3 ;
39
+ } else {
40
+ i ++ ;
41
+ sep = ! sep ;
42
+ result . length = 2 ;
43
+ }
44
+ break ;
45
+ default :
46
+ // i. e. "/a/b/.." => "/a"
47
+ // i. e. "/a/b/../c" => "/a/c"
48
+ result . length -= 3 ;
49
+ break ;
50
+ }
51
+ } else if ( part === "." ) {
52
+ switch ( result . length ) {
53
+ case 0 :
54
+ // i. e. "." => "."
55
+ // i. e. "./a/b/c" => "./a/b/c"
56
+ result . push ( part ) ;
57
+ break ;
58
+ case 2 :
59
+ // i. e. "a/." => "a"
60
+ // i. e. "/." => "/"
61
+ // i. e. "C:\." => "C:\"
62
+ // i. e. "C:\.\a\b\c" => "C:\a\b\c"
63
+ if ( absolutePathStart === 0 ) {
64
+ result . length -- ;
65
+ } else {
66
+ i ++ ;
67
+ sep = ! sep ;
68
+ }
69
+ break ;
70
+ default :
71
+ // i. e. "a/b/." => "a/b"
72
+ // i. e. "/a/." => "/"
73
+ // i. e. "C:\a\." => "C:\"
74
+ // i. e. "a/./b/c" => "a/b/c"
75
+ // i. e. "/a/./b/c" => "/a/b/c"
76
+ result . length -- ;
77
+ break ;
78
+ }
79
+ } else if ( part ) {
80
+ result . push ( part ) ;
81
+ }
82
+ }
83
+ if ( result . length === 1 && / ^ [ A - Z a - z ] : $ / . test ( result ) )
84
+ return result [ 0 ] + "\\" ;
85
+ return result . join ( "" ) ;
86
+ } ;
0 commit comments