1
- /* jshint -W084 */
2
- "use strict" ;
1
+ 'use strict' ;
3
2
4
- var invariant = require ( " react/lib/invariant" ) ;
5
- var assign = require ( " object-assign" ) ;
6
- var qs = require ( "qs" ) ;
3
+ var invariant = require ( ' react/lib/invariant' ) ;
4
+ var assign = require ( ' object-assign' ) ;
5
+ var qs = require ( 'qs' ) ;
7
6
7
+ var paramCompileMatcher = / : ( [ a - z A - Z _ $ ] [ a - z A - Z 0 - 9 _ $ ] * ) | [ * . ( ) \[ \] \\ + | { } ^ $ ] / g;
8
+ var paramInjectMatcher = / : ( [ a - z A - Z _ $ ] [ a - z A - Z 0 - 9 _ $ ? ] * [ ? ] ? ) | [ * ] / g;
9
+ var paramInjectTrailingSlashMatcher = / \/ \/ \? | \/ \? \/ | \/ \? / g;
8
10
var queryMatcher = / \? ( .* ) $ / ;
9
11
10
- function escapeRegExp ( string ) {
11
- return string . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, "\\$&" ) ;
12
- }
13
-
14
- function _compilePattern ( pattern ) {
15
- var escapedSource = "" ;
16
- var paramNames = [ ] ;
17
- var tokens = [ ] ;
18
-
19
- var match ,
20
- lastIndex = 0 ,
21
- matcher = / : ( [ a - z A - Z _ $ ] [ a - z A - Z 0 - 9 _ $ ] * ) | \* | \( | \) / g;
22
- while ( match = matcher . exec ( pattern ) ) {
23
- if ( match . index !== lastIndex ) {
24
- tokens . push ( pattern . slice ( lastIndex , match . index ) ) ;
25
- escapedSource += escapeRegExp ( pattern . slice ( lastIndex , match . index ) ) ;
26
- }
27
-
28
- if ( match [ 1 ] ) {
29
- escapedSource += "([^/?#]+)" ;
30
- paramNames . push ( match [ 1 ] ) ;
31
- } else if ( match [ 0 ] === "*" ) {
32
- escapedSource += "(.*?)" ;
33
- paramNames . push ( "splat" ) ;
34
- } else if ( match [ 0 ] === "(" ) {
35
- escapedSource += "(?:" ;
36
- } else if ( match [ 0 ] === ")" ) {
37
- escapedSource += ")?" ;
38
- }
39
-
40
- tokens . push ( match [ 0 ] ) ;
41
-
42
- lastIndex = matcher . lastIndex ;
43
- }
44
-
45
- if ( lastIndex !== pattern . length ) {
46
- tokens . push ( pattern . slice ( lastIndex , pattern . length ) ) ;
47
- escapedSource += escapeRegExp ( pattern . slice ( lastIndex , pattern . length ) ) ;
48
- }
49
-
50
- return {
51
- pattern : pattern ,
52
- escapedSource : escapedSource ,
53
- paramNames : paramNames ,
54
- tokens : tokens
55
- } ;
56
- }
57
-
58
12
var _compiledPatterns = { } ;
59
13
60
14
function compilePattern ( pattern ) {
61
- if ( ! ( pattern in _compiledPatterns ) ) _compiledPatterns [ pattern ] = _compilePattern ( pattern ) ;
15
+ if ( ! ( pattern in _compiledPatterns ) ) {
16
+ var paramNames = [ ] ;
17
+ var source = pattern . replace ( paramCompileMatcher , function ( match , paramName ) {
18
+ if ( paramName ) {
19
+ paramNames . push ( paramName ) ;
20
+ return '([^/?#]+)' ;
21
+ } else if ( match === '*' ) {
22
+ paramNames . push ( 'splat' ) ;
23
+ return '(.*?)' ;
24
+ } else {
25
+ return '\\' + match ;
26
+ }
27
+ } ) ;
28
+
29
+ _compiledPatterns [ pattern ] = {
30
+ matcher : new RegExp ( '^' + source + '$' , 'i' ) ,
31
+ paramNames : paramNames
32
+ } ;
33
+ }
62
34
63
35
return _compiledPatterns [ pattern ] ;
64
36
}
@@ -69,14 +41,14 @@ var PathUtils = {
69
41
* Returns true if the given path is absolute.
70
42
*/
71
43
isAbsolute : function isAbsolute ( path ) {
72
- return path . charAt ( 0 ) === "/" ;
44
+ return path . charAt ( 0 ) === '/' ;
73
45
} ,
74
46
75
47
/**
76
48
* Joins two URL paths together.
77
49
*/
78
50
join : function join ( a , b ) {
79
- return a . replace ( / \/ * $ / , "/" ) + b ;
51
+ return a . replace ( / \/ * $ / , '/' ) + b ;
80
52
} ,
81
53
82
54
/**
@@ -92,12 +64,11 @@ var PathUtils = {
92
64
* pattern does not match the given path.
93
65
*/
94
66
extractParams : function extractParams ( pattern , path ) {
95
- var _compilePattern2 = compilePattern ( pattern ) ;
67
+ var _compilePattern = compilePattern ( pattern ) ;
96
68
97
- var escapedSource = _compilePattern2 . escapedSource ;
98
- var paramNames = _compilePattern2 . paramNames ;
69
+ var matcher = _compilePattern . matcher ;
70
+ var paramNames = _compilePattern . paramNames ;
99
71
100
- var matcher = new RegExp ( "^" + escapedSource + "$" , "i" ) ;
101
72
var match = path . match ( matcher ) ;
102
73
103
74
if ( ! match ) {
@@ -118,41 +89,31 @@ var PathUtils = {
118
89
injectParams : function injectParams ( pattern , params ) {
119
90
params = params || { } ;
120
91
121
- var _compilePattern2 = compilePattern ( pattern ) ;
122
-
123
- var tokens = _compilePattern2 . tokens ;
92
+ var splatIndex = 0 ;
124
93
125
- var parenCount = 0 ,
126
- pathname = "" ,
127
- splatIndex = 0 ;
94
+ return pattern . replace ( paramInjectMatcher , function ( match , paramName ) {
95
+ paramName = paramName || 'splat' ;
128
96
129
- var token , paramName , paramValue ;
130
- for ( var i = 0 , len = tokens . length ; i < len ; ++ i ) {
131
- token = tokens [ i ] ;
97
+ // If param is optional don't check for existence
98
+ if ( paramName . slice ( - 1 ) === '?' ) {
99
+ paramName = paramName . slice ( 0 , - 1 ) ;
132
100
133
- if ( token === "*" ) {
134
- paramValue = Array . isArray ( params . splat ) ? params . splat [ splatIndex ++ ] : params . splat ;
135
-
136
- invariant ( paramValue != null || parenCount > 0 , "Missing splat #%s for path \"%s\"" , splatIndex , pattern ) ;
137
-
138
- if ( paramValue != null ) pathname += paramValue ;
139
- } else if ( token === "(" ) {
140
- parenCount += 1 ;
141
- } else if ( token === ")" ) {
142
- parenCount -= 1 ;
143
- } else if ( token . charAt ( 0 ) === ":" ) {
144
- paramName = token . substring ( 1 ) ;
145
- paramValue = params [ paramName ] ;
101
+ if ( params [ paramName ] == null ) return '' ;
102
+ } else {
103
+ invariant ( params [ paramName ] != null , 'Missing "%s" parameter for path "%s"' , paramName , pattern ) ;
104
+ }
146
105
147
- invariant ( paramValue != null || parenCount > 0 , "Missing \"%s\" parameter for path \"%s\"" , paramName , pattern ) ;
106
+ var segment ;
107
+ if ( paramName === 'splat' && Array . isArray ( params [ paramName ] ) ) {
108
+ segment = params [ paramName ] [ splatIndex ++ ] ;
148
109
149
- if ( paramValue != null ) pathname += paramValue ;
110
+ invariant ( segment != null , 'Missing splat # %s for path "%s"' , splatIndex , pattern ) ;
150
111
} else {
151
- pathname += token ;
112
+ segment = params [ paramName ] ;
152
113
}
153
- }
154
114
155
- return pathname . replace ( / \/ + / g, "/" ) ;
115
+ return segment ;
116
+ } ) . replace ( paramInjectTrailingSlashMatcher , '/' ) ;
156
117
} ,
157
118
158
119
/**
@@ -168,7 +129,7 @@ var PathUtils = {
168
129
* Returns a version of the given path without the query string.
169
130
*/
170
131
withoutQuery : function withoutQuery ( path ) {
171
- return path . replace ( queryMatcher , "" ) ;
132
+ return path . replace ( queryMatcher , '' ) ;
172
133
} ,
173
134
174
135
/**
@@ -180,10 +141,10 @@ var PathUtils = {
180
141
181
142
if ( existingQuery ) query = query ? assign ( existingQuery , query ) : existingQuery ;
182
143
183
- var queryString = qs . stringify ( query , { arrayFormat : " brackets" } ) ;
144
+ var queryString = qs . stringify ( query , { arrayFormat : ' brackets' } ) ;
184
145
185
146
if ( queryString ) {
186
- return PathUtils . withoutQuery ( path ) + "?" + queryString ;
147
+ return PathUtils . withoutQuery ( path ) + '?' + queryString ;
187
148
} return PathUtils . withoutQuery ( path ) ;
188
149
}
189
150
0 commit comments