1- var utils = require ( './utils' ) ,
2- dirId = 1 ,
3-
4- // match up to the first single pipe, ignore those within quotes.
5- KEY_RE = / ^ (?: [ ' " ] (?: \\ .| [ ^ ' " ] ) * [ ' " ] | \\ .| [ ^ \| ] | \| \| ) + / ,
6- ARG_RE = / ^ ( [ \w - $ ] + ) : ( .+ ) $ / ,
7- FILTERS_RE = / \| [ ^ \| ] + / g,
8- FILTER_TOKEN_RE = / [ ^ \s ' ] + | ' [ ^ ' ] + ' | [ ^ \s " ] + | " [ ^ " ] + " / g,
1+ var dirId = 1 ,
2+ ARG_RE = / ^ [ \w - ] + $ / ,
3+ FILTER_TOKEN_RE = / [ ^ \s ' " ] + | ' [ ^ ' ] + ' | " [ ^ " ] + " / g,
94 NESTING_RE = / ^ \$ ( p a r e n t | r o o t ) \. / ,
105 SINGLE_VAR_RE = / ^ [ \w \. $ ] + $ / ,
116 QUOTE_RE = / " / g
@@ -14,16 +9,19 @@ var utils = require('./utils'),
149 * Directive class
1510 * represents a single directive instance in the DOM
1611 */
17- function Directive ( dirname , definition , expression , rawKey , compiler , node ) {
12+ function Directive ( name , ast , definition , compiler , el ) {
1813
1914 this . id = dirId ++
20- this . name = dirname
15+ this . name = name
2116 this . compiler = compiler
2217 this . vm = compiler . vm
23- this . el = node
18+ this . el = el
2419 this . computeFilters = false
20+ this . key = ast . key
21+ this . arg = ast . arg
22+ this . expression = ast . expression
2523
26- var isEmpty = expression === ''
24+ var isEmpty = this . expression === ''
2725
2826 // mix in properties from the directive definition
2927 if ( typeof definition === 'function' ) {
@@ -46,15 +44,11 @@ function Directive (dirname, definition, expression, rawKey, compiler, node) {
4644
4745 this . expression = (
4846 this . isLiteral
49- ? compiler . eval ( expression )
50- : expression
47+ ? compiler . eval ( this . expression )
48+ : this . expression
5149 ) . trim ( )
52-
53- var parsed = Directive . parseArg ( rawKey )
54- this . key = parsed . key
55- this . arg = parsed . arg
56-
57- var filters = Directive . parseFilters ( this . expression . slice ( rawKey . length ) ) ,
50+
51+ var filters = ast . filters ,
5852 filter , fn , i , l , computed
5953 if ( filters ) {
6054 this . filters = [ ]
@@ -133,8 +127,8 @@ DirProto.unbind = function () {
133127// Exposed static methods -----------------------------------------------------
134128
135129/**
136- * split a unquoted-comma separated expression into
137- * multiple clauses
130+ * Parse a directive string into an Array of
131+ * AST-like objects representing directives
138132 */
139133Directive . parse = function ( str ) {
140134
@@ -147,7 +141,8 @@ Directive.parse = function (str) {
147141 argIndex = 0 ,
148142 dirs = [ ] ,
149143 dir = { } ,
150- lastFilterIndex = 0
144+ lastFilterIndex = 0 ,
145+ arg
151146
152147 for ( var c , i = 0 , l = str . length ; i < l ; i ++ ) {
153148 c = str . charAt ( i )
@@ -165,12 +160,15 @@ Directive.parse = function (str) {
165160 begin = argIndex = lastFilterIndex = i + 1
166161 } else if ( c === ':' && ! dir . key && ! dir . arg ) {
167162 // argument
168- argIndex = i + 1
169- dir . arg = str . slice ( begin , i ) . trim ( )
163+ arg = str . slice ( begin , i ) . trim ( )
164+ if ( ARG_RE . test ( arg ) ) {
165+ argIndex = i + 1
166+ dir . arg = str . slice ( begin , i ) . trim ( )
167+ }
170168 } else if ( c === '|' && str . charAt ( i + 1 ) !== '|' ) {
171- if ( ! dir . key ) {
169+ if ( dir . key === undefined ) {
172170 // first filter, end of key
173- lastFilterIndex = i
171+ lastFilterIndex = i + 1
174172 dir . key = str . slice ( argIndex , i ) . trim ( )
175173 } else {
176174 // already has filter
@@ -194,127 +192,40 @@ Directive.parse = function (str) {
194192 curly --
195193 }
196194 }
197- if ( begin !== i ) {
195+ if ( i === 0 || begin !== i ) {
198196 pushDir ( )
199197 }
200198
201199 function pushDir ( ) {
202200 dir . expression = str . slice ( begin , i ) . trim ( )
203- if ( ! dir . key ) {
201+ if ( dir . key === undefined ) {
204202 dir . key = str . slice ( argIndex , i ) . trim ( )
205203 } else if ( lastFilterIndex !== begin ) {
206204 pushFilter ( )
207205 }
208- dirs . push ( dir )
206+ if ( i === 0 || dir . key ) {
207+ dirs . push ( dir )
208+ }
209209 }
210210
211211 function pushFilter ( ) {
212- ( dir . filters = dir . filters || [ ] )
213- . push ( str . slice ( lastFilterIndex + 1 , i ) . trim ( ) )
212+ var exp = str . slice ( lastFilterIndex , i ) . trim ( ) ,
213+ filter
214+ if ( exp ) {
215+ filter = { }
216+ var tokens = exp . match ( FILTER_TOKEN_RE )
217+ filter . name = tokens [ 0 ]
218+ filter . args = tokens . length > 1 ? tokens . slice ( 1 ) : null
219+ }
220+ if ( filter ) {
221+ ( dir . filters = dir . filters || [ ] ) . push ( filter )
222+ }
214223 lastFilterIndex = i + 1
215224 }
216225
217226 return dirs
218227}
219228
220- // function split (str) {
221- // var inSingle = false,
222- // inDouble = false,
223- // curly = 0,
224- // square = 0,
225- // paren = 0,
226- // begin = 0,
227- // end = 0,
228- // res = []
229- // for (var c, i = 0, l = str.length; i < l; i++) {
230- // c = str.charAt(i)
231- // if (inSingle) {
232- // if (c === "'") {
233- // inSingle = !inSingle
234- // }
235- // end++
236- // } else if (inDouble) {
237- // if (c === '"') {
238- // inDouble = !inDouble
239- // }
240- // end++
241- // } else if (c === ',' && !paren && !curly && !square) {
242- // res.push(str.slice(begin, end))
243- // begin = end = i + 1
244- // } else {
245- // if (c === '"') {
246- // inDouble = true
247- // } else if (c === "'") {
248- // inSingle = true
249- // } else if (c === '(') {
250- // paren++
251- // } else if (c === ')') {
252- // paren--
253- // } else if (c === '[') {
254- // square++
255- // } else if (c === ']') {
256- // square--
257- // } else if (c === '{') {
258- // curly++
259- // } else if (c === ' }') {
260- // curly--
261- // }
262- // end++
263- // }
264- // }
265- // if (begin !== end) {
266- // res.push(str.slice(begin, end))
267- // }
268- // return res
269- // }
270-
271- // /**
272- // * parse a key, extract argument
273- // */
274- // Directive.parseArg = function (rawKey) {
275- // var key = rawKey,
276- // arg = null
277- // if (rawKey.indexOf(':') > -1) {
278- // var argMatch = rawKey.match(ARG_RE)
279- // key = argMatch
280- // ? argMatch[2].trim()
281- // : key
282- // arg = argMatch
283- // ? argMatch[1].trim()
284- // : arg
285- // }
286- // return {
287- // key: key,
288- // arg: arg
289- // }
290- // }
291-
292- // /**
293- // * parse a the filters
294- // */
295- // Directive.parseFilters = function (exp) {
296- // if (exp.indexOf('|') < 0) {
297- // return
298- // }
299- // var filters = exp.match(FILTERS_RE),
300- // res, i, l, tokens
301- // if (filters) {
302- // res = []
303- // for (i = 0, l = filters.length; i < l; i++) {
304- // tokens = filters[i].slice(1).match(FILTER_TOKEN_RE)
305- // if (tokens) {
306- // res.push({
307- // name: tokens[0],
308- // args: tokens.length > 1
309- // ? tokens.slice(1)
310- // : null
311- // })
312- // }
313- // }
314- // }
315- // return res
316- // }
317-
318229/**
319230 * Inline computed filters so they become part
320231 * of the expression
@@ -345,36 +256,4 @@ function escapeQuote (v) {
345256 : v
346257}
347258
348- /**
349- * Parse the key from a directive raw expression
350- */
351- Directive . parseKey = function ( expression ) {
352- if ( expression . indexOf ( '|' ) > - 1 ) {
353- var keyMatch = expression . match ( KEY_RE )
354- if ( keyMatch ) {
355- return keyMatch [ 0 ] . trim ( )
356- }
357- } else {
358- return expression . trim ( )
359- }
360- }
361-
362- /**
363- * make sure the directive and expression is valid
364- * before we create an instance
365- */
366- Directive . build = function ( dirname , expression , compiler , node ) {
367-
368- var dir = compiler . getOption ( 'directives' , dirname )
369- if ( ! dir ) return
370-
371- var rawKey = Directive . parseKey ( expression )
372- // have a valid raw key, or be an empty directive
373- if ( rawKey || expression === '' ) {
374- return new Directive ( dirname , dir , expression , rawKey , compiler , node )
375- } else {
376- utils . warn ( 'Invalid directive expression: ' + expression )
377- }
378- }
379-
380259module . exports = Directive
0 commit comments