@@ -3,78 +3,100 @@ var Cache = require('../cache')
33var pathCache = new Cache ( 1000 )
44var identRE = exports . identRE = / ^ [ $ _ a - z A - Z ] + [ \w $ ] * $ /
55
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+ }
933
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 ]
78100}
79101
80102function noop ( ) { }
@@ -144,38 +166,37 @@ function getPathCharType (ch) {
144166function parsePath ( path ) {
145167 var keys = [ ]
146168 var index = - 1
147- var mode = 'beforePath'
169+ var mode = BEFORE_PATH
148170 var c , newChar , key , type , transition , action , typeMap
149171
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
164185 }
165186 }
166187
167188 function maybeUnescapeQuote ( ) {
168189 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 === '"' ) ) {
171192 index ++
172193 newChar = nextChar
173- actions . append ( )
194+ actions [ APPEND ] ( )
174195 return true
175196 }
176197 }
177198
178- while ( mode ) {
199+ while ( mode != null ) {
179200 index ++
180201 c = path [ index ]
181202
@@ -185,9 +206,9 @@ function parsePath (path) {
185206
186207 type = getPathCharType ( c )
187208 typeMap = pathStateMachine [ mode ]
188- transition = typeMap [ type ] || typeMap [ 'else' ] || 'error'
209+ transition = typeMap [ type ] || typeMap [ 'else' ] || ERROR
189210
190- if ( transition === 'error' ) {
211+ if ( transition === ERROR ) {
191212 return // parse error
192213 }
193214
@@ -201,7 +222,7 @@ function parsePath (path) {
201222 : newChar
202223 action ( )
203224
204- if ( mode === 'afterPath' ) {
225+ if ( mode === AFTER_PATH ) {
205226 keys . raw = path
206227 return keys
207228 }
0 commit comments