@@ -3,78 +3,100 @@ var Cache = require('../cache')
3
3
var pathCache = new Cache ( 1000 )
4
4
var identRE = exports . identRE = / ^ [ $ _ a - z A - Z ] + [ \w $ ] * $ /
5
5
6
- /**
7
- * Path-parsing algorithm scooped from Polymer/observe-js
8
- */
6
+ // actions
7
+ var APPEND = 0
8
+ var PUSH = 1
9
+
10
+ // states
11
+ var BEFORE_PATH = 0
12
+ var IN_PATH = 1
13
+ var BEFORE_IDENT = 2
14
+ var IN_IDENT = 3
15
+ var BEFORE_ELEMENT = 4
16
+ var AFTER_ZERO = 5
17
+ var IN_INDEX = 6
18
+ var IN_SINGLE_QUOTE = 7
19
+ var IN_DOUBLE_QUOTE = 8
20
+ var IN_SUB_PATH = 9
21
+ var AFTER_ELEMENT = 10
22
+ var AFTER_PATH = 11
23
+ var ERROR = 12
24
+
25
+ var pathStateMachine = [ ]
26
+
27
+ pathStateMachine [ BEFORE_PATH ] = {
28
+ 'ws' : [ BEFORE_PATH ] ,
29
+ 'ident' : [ IN_IDENT , APPEND ] ,
30
+ '[' : [ BEFORE_ELEMENT ] ,
31
+ 'eof' : [ AFTER_PATH ]
32
+ }
9
33
10
- var pathStateMachine = {
11
- 'beforePath' : {
12
- 'ws' : [ 'beforePath' ] ,
13
- 'ident' : [ 'inIdent' , 'append' ] ,
14
- '[' : [ 'beforeElement' ] ,
15
- 'eof' : [ 'afterPath' ]
16
- } ,
17
-
18
- 'inPath' : {
19
- 'ws' : [ 'inPath' ] ,
20
- '.' : [ 'beforeIdent' ] ,
21
- '[' : [ 'beforeElement' ] ,
22
- 'eof' : [ 'afterPath' ]
23
- } ,
24
-
25
- 'beforeIdent' : {
26
- 'ws' : [ 'beforeIdent' ] ,
27
- 'ident' : [ 'inIdent' , 'append' ]
28
- } ,
29
-
30
- 'inIdent' : {
31
- 'ident' : [ 'inIdent' , 'append' ] ,
32
- '0' : [ 'inIdent' , 'append' ] ,
33
- 'number' : [ 'inIdent' , 'append' ] ,
34
- 'ws' : [ 'inPath' , 'push' ] ,
35
- '.' : [ 'beforeIdent' , 'push' ] ,
36
- '[' : [ 'beforeElement' , 'push' ] ,
37
- 'eof' : [ 'afterPath' , 'push' ] ,
38
- ']' : [ 'inPath' , 'push' ]
39
- } ,
40
-
41
- 'beforeElement' : {
42
- 'ws' : [ 'beforeElement' ] ,
43
- '0' : [ 'afterZero' , 'append' ] ,
44
- 'number' : [ 'inIndex' , 'append' ] ,
45
- "'" : [ 'inSingleQuote' , 'append' , '' ] ,
46
- '"' : [ 'inDoubleQuote' , 'append' , '' ] ,
47
- 'ident' : [ 'inIdent' , 'append' , '*' ]
48
- } ,
49
-
50
- 'afterZero' : {
51
- 'ws' : [ 'afterElement' , 'push' ] ,
52
- ']' : [ 'inPath' , 'push' ]
53
- } ,
54
-
55
- 'inIndex' : {
56
- '0' : [ 'inIndex' , 'append' ] ,
57
- 'number' : [ 'inIndex' , 'append' ] ,
58
- 'ws' : [ 'afterElement' ] ,
59
- ']' : [ 'inPath' , 'push' ]
60
- } ,
61
-
62
- 'inSingleQuote' : {
63
- "'" : [ 'afterElement' ] ,
64
- 'eof' : 'error' ,
65
- 'else' : [ 'inSingleQuote' , 'append' ]
66
- } ,
67
-
68
- 'inDoubleQuote' : {
69
- '"' : [ 'afterElement' ] ,
70
- 'eof' : 'error' ,
71
- 'else' : [ 'inDoubleQuote' , 'append' ]
72
- } ,
73
-
74
- 'afterElement' : {
75
- 'ws' : [ 'afterElement' ] ,
76
- ']' : [ 'inPath' , 'push' ]
77
- }
34
+ pathStateMachine [ IN_PATH ] = {
35
+ 'ws' : [ IN_PATH ] ,
36
+ '.' : [ BEFORE_IDENT ] ,
37
+ '[' : [ BEFORE_ELEMENT ] ,
38
+ 'eof' : [ AFTER_PATH ]
39
+ }
40
+
41
+ pathStateMachine [ BEFORE_IDENT ] = {
42
+ 'ws' : [ BEFORE_IDENT ] ,
43
+ 'ident' : [ IN_IDENT , APPEND ]
44
+ }
45
+
46
+ pathStateMachine [ IN_IDENT ] = {
47
+ 'ident' : [ IN_IDENT , APPEND ] ,
48
+ '0' : [ IN_IDENT , APPEND ] ,
49
+ 'number' : [ IN_IDENT , APPEND ] ,
50
+ 'ws' : [ IN_PATH , PUSH ] ,
51
+ '.' : [ BEFORE_IDENT , PUSH ] ,
52
+ '[' : [ BEFORE_ELEMENT , PUSH ] ,
53
+ 'eof' : [ AFTER_PATH , PUSH ]
54
+ }
55
+
56
+ pathStateMachine [ BEFORE_ELEMENT ] = {
57
+ 'ws' : [ BEFORE_ELEMENT ] ,
58
+ '0' : [ AFTER_ZERO , APPEND ] ,
59
+ 'number' : [ IN_INDEX , APPEND ] ,
60
+ "'" : [ IN_SINGLE_QUOTE , APPEND , '' ] ,
61
+ '"' : [ IN_DOUBLE_QUOTE , APPEND , '' ] ,
62
+ 'ident' : [ IN_SUB_PATH , APPEND , '*' ]
63
+ }
64
+
65
+ pathStateMachine [ AFTER_ZERO ] = {
66
+ 'ws' : [ AFTER_ELEMENT , PUSH ] ,
67
+ ']' : [ IN_PATH , PUSH ]
68
+ }
69
+
70
+ pathStateMachine [ IN_INDEX ] = {
71
+ '0' : [ IN_INDEX , APPEND ] ,
72
+ 'number' : [ IN_INDEX , APPEND ] ,
73
+ 'ws' : [ AFTER_ELEMENT ] ,
74
+ ']' : [ IN_PATH , PUSH ]
75
+ }
76
+
77
+ pathStateMachine [ IN_SINGLE_QUOTE ] = {
78
+ "'" : [ AFTER_ELEMENT ] ,
79
+ 'eof' : ERROR ,
80
+ 'else' : [ IN_SINGLE_QUOTE , APPEND ]
81
+ }
82
+
83
+ pathStateMachine [ IN_DOUBLE_QUOTE ] = {
84
+ '"' : [ AFTER_ELEMENT ] ,
85
+ 'eof' : ERROR ,
86
+ 'else' : [ IN_DOUBLE_QUOTE , APPEND ]
87
+ }
88
+
89
+ pathStateMachine [ IN_SUB_PATH ] = {
90
+ 'ident' : [ IN_SUB_PATH , APPEND ] ,
91
+ '0' : [ IN_SUB_PATH , APPEND ] ,
92
+ 'number' : [ IN_SUB_PATH , APPEND ] ,
93
+ 'ws' : [ AFTER_ELEMENT , PUSH ] ,
94
+ ']' : [ IN_PATH , PUSH ]
95
+ }
96
+
97
+ pathStateMachine [ AFTER_ELEMENT ] = {
98
+ 'ws' : [ AFTER_ELEMENT ] ,
99
+ ']' : [ IN_PATH , PUSH ]
78
100
}
79
101
80
102
function noop ( ) { }
@@ -144,38 +166,37 @@ function getPathCharType (ch) {
144
166
function parsePath ( path ) {
145
167
var keys = [ ]
146
168
var index = - 1
147
- var mode = 'beforePath'
169
+ var mode = BEFORE_PATH
148
170
var c , newChar , key , type , transition , action , typeMap
149
171
150
- var actions = {
151
- push : function ( ) {
152
- if ( key === undefined ) {
153
- return
154
- }
155
- keys . push ( key )
156
- key = undefined
157
- } ,
158
- append : function ( ) {
159
- if ( key === undefined ) {
160
- key = newChar
161
- } else {
162
- key += newChar
163
- }
172
+ var actions = [ ]
173
+ actions [ PUSH ] = function ( ) {
174
+ if ( key === undefined ) {
175
+ return
176
+ }
177
+ keys . push ( key )
178
+ key = undefined
179
+ }
180
+ actions [ APPEND ] = function ( ) {
181
+ if ( key === undefined ) {
182
+ key = newChar
183
+ } else {
184
+ key += newChar
164
185
}
165
186
}
166
187
167
188
function maybeUnescapeQuote ( ) {
168
189
var nextChar = path [ index + 1 ]
169
- if ( ( mode === 'inSingleQuote' && nextChar === "'" ) ||
170
- ( mode === 'inDoubleQuote' && nextChar === '"' ) ) {
190
+ if ( ( mode === IN_SINGLE_QUOTE && nextChar === "'" ) ||
191
+ ( mode === IN_DOUBLE_QUOTE && nextChar === '"' ) ) {
171
192
index ++
172
193
newChar = nextChar
173
- actions . append ( )
194
+ actions [ APPEND ] ( )
174
195
return true
175
196
}
176
197
}
177
198
178
- while ( mode ) {
199
+ while ( mode != null ) {
179
200
index ++
180
201
c = path [ index ]
181
202
@@ -185,9 +206,9 @@ function parsePath (path) {
185
206
186
207
type = getPathCharType ( c )
187
208
typeMap = pathStateMachine [ mode ]
188
- transition = typeMap [ type ] || typeMap [ 'else' ] || 'error'
209
+ transition = typeMap [ type ] || typeMap [ 'else' ] || ERROR
189
210
190
- if ( transition === 'error' ) {
211
+ if ( transition === ERROR ) {
191
212
return // parse error
192
213
}
193
214
@@ -201,7 +222,7 @@ function parsePath (path) {
201
222
: newChar
202
223
action ( )
203
224
204
- if ( mode === 'afterPath' ) {
225
+ if ( mode === AFTER_PATH ) {
205
226
keys . raw = path
206
227
return keys
207
228
}
0 commit comments