@@ -15,7 +15,8 @@ var utils = require('./utils'),
15
15
FILTERS_RE = / \| [ ^ \| ] + / g,
16
16
FILTER_TOKEN_RE = / [ ^ \s ' ] + | ' [ ^ ' ] + ' | [ ^ \s " ] + | " [ ^ " ] + " / g,
17
17
NESTING_RE = / ^ \$ ( p a r e n t | r o o t ) \. / ,
18
- SINGLE_VAR_RE = / ^ [ \w \. $ ] + $ /
18
+ SINGLE_VAR_RE = / ^ [ \w \. $ ] + $ / ,
19
+ QUOTE_RE = / " / g
19
20
20
21
/**
21
22
* Directive class
@@ -57,28 +58,35 @@ function Directive (dirname, definition, expression, rawKey, compiler, node) {
57
58
: expression
58
59
) . trim ( )
59
60
60
- parseKey ( this , rawKey )
61
+ var parsed = Directive . parseArg ( rawKey )
62
+ this . key = parsed . key
63
+ this . arg = parsed . arg
61
64
62
- var filterExps = this . expression . slice ( rawKey . length ) . match ( FILTERS_RE )
63
- if ( filterExps ) {
65
+ var filters = Directive . parseFilters ( this . expression . slice ( rawKey . length ) ) ,
66
+ filter , fn , i , l
67
+ if ( filters ) {
64
68
this . filters = [ ]
65
- for ( var i = 0 , l = filterExps . length , filter ; i < l ; i ++ ) {
66
- filter = parseFilter ( filterExps [ i ] , this . compiler )
67
- if ( filter ) {
69
+ for ( i = 0 , l = filters . length ; i < l ; i ++ ) {
70
+ filter = filters [ i ]
71
+ fn = this . compiler . getOption ( 'filters' , filter . name )
72
+ if ( fn ) {
73
+ filter . apply = fn
68
74
this . filters . push ( filter )
69
- if ( filter . apply . computed ) {
70
- // some special filters, e.g. filterBy & orderBy,
71
- // can involve VM properties and they often need to
72
- // be computed.
75
+ if ( fn . computed ) {
73
76
this . computeFilters = true
74
77
}
75
78
}
76
79
}
77
- if ( ! this . filters . length ) this . filters = null
78
- } else {
80
+ }
81
+
82
+ if ( ! this . filters || ! this . filters . length ) {
79
83
this . filters = null
80
84
}
81
85
86
+ if ( this . computeFilters ) {
87
+ this . key = Directive . inlineFilters ( this . key , this . filters )
88
+ }
89
+
82
90
this . isExp =
83
91
this . computeFilters ||
84
92
! SINGLE_VAR_RE . test ( this . key ) ||
@@ -88,47 +96,6 @@ function Directive (dirname, definition, expression, rawKey, compiler, node) {
88
96
89
97
var DirProto = Directive . prototype
90
98
91
- /**
92
- * parse a key, extract argument and nesting/root info
93
- */
94
- function parseKey ( dir , rawKey ) {
95
- var key = rawKey
96
- if ( rawKey . indexOf ( ':' ) > - 1 ) {
97
- var argMatch = rawKey . match ( ARG_RE )
98
- key = argMatch
99
- ? argMatch [ 2 ] . trim ( )
100
- : key
101
- dir . arg = argMatch
102
- ? argMatch [ 1 ] . trim ( )
103
- : null
104
- }
105
- dir . key = key
106
- }
107
-
108
- /**
109
- * parse a filter expression
110
- */
111
- function parseFilter ( filter , compiler ) {
112
-
113
- var tokens = filter . slice ( 1 ) . match ( FILTER_TOKEN_RE )
114
- if ( ! tokens ) return
115
-
116
- var name = tokens [ 0 ] ,
117
- apply = compiler . getOption ( 'filters' , name )
118
- if ( ! apply ) {
119
- utils . warn ( 'Unknown filter: ' + name )
120
- return
121
- }
122
-
123
- return {
124
- name : name ,
125
- apply : apply ,
126
- args : tokens . length > 1
127
- ? tokens . slice ( 1 )
128
- : null
129
- }
130
- }
131
-
132
99
/**
133
100
* called when a new value is set
134
101
* for computed properties, this will only be called once
@@ -170,7 +137,7 @@ DirProto.unbind = function () {
170
137
this . vm = this . el = this . binding = this . compiler = null
171
138
}
172
139
173
- // exposed methods ------- -----------------------------------------------------
140
+ // Exposed static methods -----------------------------------------------------
174
141
175
142
/**
176
143
* split a unquoted-comma separated expression into
@@ -183,27 +150,104 @@ Directive.split = function (exp) {
183
150
}
184
151
185
152
/**
186
- * make sure the directive and expression is valid
187
- * before we create an instance
153
+ * parse a key, extract argument
188
154
*/
189
- Directive . parse = function ( dirname , expression , compiler , node ) {
155
+ Directive . parseArg = function ( rawKey ) {
156
+ var key = rawKey ,
157
+ arg = null
158
+ if ( rawKey . indexOf ( ':' ) > - 1 ) {
159
+ var argMatch = rawKey . match ( ARG_RE )
160
+ key = argMatch
161
+ ? argMatch [ 2 ] . trim ( )
162
+ : key
163
+ arg = argMatch
164
+ ? argMatch [ 1 ] . trim ( )
165
+ : arg
166
+ }
167
+ return {
168
+ key : key ,
169
+ arg : arg
170
+ }
171
+ }
190
172
191
- var dir = compiler . getOption ( 'directives' , dirname ) || directives [ dirname ]
192
- if ( ! dir ) {
193
- utils . warn ( 'Unknown directive: ' + dirname )
194
- return
173
+ /**
174
+ * parse a the filters
175
+ */
176
+ Directive . parseFilters = function ( exp ) {
177
+ if ( ! exp . indexOf ( '|' ) < 0 ) return
178
+ var filters = exp . match ( FILTERS_RE ) ,
179
+ res , i , l , tokens
180
+ if ( filters ) {
181
+ res = [ ]
182
+ for ( i = 0 , l = filters . length ; i < l ; i ++ ) {
183
+ tokens = filters [ i ] . slice ( 1 ) . match ( FILTER_TOKEN_RE )
184
+ if ( tokens ) {
185
+ res . push ( {
186
+ name : tokens [ 0 ] ,
187
+ args : tokens . length > 1
188
+ ? tokens . slice ( 1 )
189
+ : null
190
+ } )
191
+ }
192
+ }
193
+ }
194
+ return res
195
+ }
196
+
197
+ /**
198
+ * Inline computed filters so they become part
199
+ * of the expression
200
+ */
201
+ Directive . inlineFilters = function ( key , filters ) {
202
+ var args , filter
203
+ for ( var i = 0 , l = filters . length ; i < l ; i ++ ) {
204
+ filter = filters [ i ]
205
+ args = filter . args
206
+ ? ',"' + filter . args . map ( escapeQuote ) . join ( '","' ) + '"'
207
+ : ''
208
+ key = 'this.$compiler.getOption("filters", "' +
209
+ filter . name +
210
+ '").call(this,' +
211
+ key + args +
212
+ ')'
195
213
}
214
+ return key
215
+ }
216
+
217
+ /**
218
+ * Convert double quotes to single quotes
219
+ * so they don't mess up the generated function body
220
+ */
221
+ function escapeQuote ( v ) {
222
+ return v . indexOf ( '"' ) > - 1
223
+ ? v . replace ( QUOTE_RE , '\'' )
224
+ : v
225
+ }
196
226
197
- var rawKey
227
+ /**
228
+ * Parse the key from a directive raw expression
229
+ */
230
+ Directive . parseKey = function ( expression ) {
198
231
if ( expression . indexOf ( '|' ) > - 1 ) {
199
232
var keyMatch = expression . match ( KEY_RE )
200
233
if ( keyMatch ) {
201
- rawKey = keyMatch [ 0 ] . trim ( )
234
+ return keyMatch [ 0 ] . trim ( )
202
235
}
203
236
} else {
204
- rawKey = expression . trim ( )
237
+ return expression . trim ( )
205
238
}
206
-
239
+ }
240
+
241
+ /**
242
+ * make sure the directive and expression is valid
243
+ * before we create an instance
244
+ */
245
+ Directive . build = function ( dirname , expression , compiler , node ) {
246
+
247
+ var dir = compiler . getOption ( 'directives' , dirname )
248
+ if ( ! dir ) return
249
+
250
+ var rawKey = Directive . parseKey ( expression )
207
251
// have a valid raw key, or be an empty directive
208
252
if ( rawKey || expression === '' ) {
209
253
return new Directive ( dirname , dir , expression , rawKey , compiler , node )
0 commit comments