1
- var utils = require ( './utils' )
1
+ var utils = require ( './utils' ) ,
2
+ hasOwn = Object . prototype . hasOwnProperty
2
3
3
4
// Variable extraction scooped from https://github.com/RubyLouvre/avalon
4
5
@@ -37,25 +38,45 @@ function getVariables (code) {
37
38
}
38
39
39
40
/**
40
- * Based on top level variables, extract full keypaths accessed.
41
- * We need full paths because we need to define them in the compiler's
42
- * bindings, so that they emit 'get' events during dependency tracking.
41
+ * Filter
43
42
*/
44
- // function getPaths (code, vars) {
45
- // var pathRE = new RegExp("\\b(" + vars.join('|') + ")[$\\w\\.]*\\b", 'g')
46
- // return code.match(pathRE)
47
- // }
48
-
49
43
function filterUnique ( vars ) {
50
44
var hash = utils . hash ( ) ,
51
45
i = vars . length ,
52
- key
46
+ key , res = [ ]
53
47
while ( i -- ) {
54
48
key = vars [ i ]
55
49
if ( hash [ key ] ) continue
56
50
hash [ key ] = 1
51
+ res . push ( key )
57
52
}
58
- return Object . keys ( hash )
53
+ return res
54
+ }
55
+
56
+ function getRel ( path , compiler ) {
57
+ var rel = '' ,
58
+ vm = compiler . vm ,
59
+ dot = path . indexOf ( '.' ) ,
60
+ key = dot > - 1
61
+ ? path . slice ( 0 , dot )
62
+ : path
63
+ while ( true ) {
64
+ if ( hasOwn . call ( vm , key ) ) {
65
+ break
66
+ } else {
67
+ if ( vm . $parent ) {
68
+ vm = vm . $parent
69
+ rel += '$parent.'
70
+ } else {
71
+ break
72
+ }
73
+ }
74
+ }
75
+ compiler = vm . $compiler
76
+ if ( ! hasOwn . call ( compiler . bindings , path ) ) {
77
+ compiler . createBinding ( path )
78
+ }
79
+ return rel
59
80
}
60
81
61
82
/**
@@ -81,41 +102,17 @@ module.exports = {
81
102
* from an arbitrary expression, together with a list of paths to be
82
103
* created as bindings.
83
104
*/
84
- parse : function ( exp ) {
105
+ parse : function ( exp , compiler ) {
85
106
// extract variable names
86
107
var vars = getVariables ( exp )
87
108
if ( ! vars . length ) {
88
- return {
89
- getter : makeGetter ( 'return ' + exp , exp )
90
- }
109
+ return makeGetter ( 'return ' + exp , exp )
91
110
}
92
- console . log ( vars )
93
111
vars = filterUnique ( vars )
94
- // var args = [],
95
- // v, i, keyPrefix,
96
- // l = vars.length,
97
- // hash = Object.create(null)
98
- // for (i = 0; i < l; i++) {
99
- // v = vars[i]
100
- // // avoid duplicate keys
101
- // if (hash[v]) continue
102
- // hash[v] = v
103
- // // push assignment
104
- // keyPrefix = v.charAt(0)
105
- // args.push(v + (
106
- // (keyPrefix === '$' || keyPrefix === '_')
107
- // ? '=this.' + v
108
- // : '=this.$get("' + v + '")'
109
- // ))
110
- // }
111
- // args = 'var ' + args.join(',') + ';return ' + exp
112
112
var pathRE = new RegExp ( "\\b(" + vars . join ( '|' ) + ")[$\\w\\.]*\\b" , 'g' ) ,
113
- paths = exp . match ( pathRE ) ,
114
- body = 'return ' + exp . replace ( pathRE , 'this.$&' )
115
- console . log ( paths , body )
116
- return {
117
- getter : makeGetter ( body , exp ) ,
118
- paths : paths
119
- }
113
+ body = 'return ' + exp . replace ( pathRE , function ( path ) {
114
+ return 'this.' + getRel ( path , compiler ) + path
115
+ } )
116
+ return makeGetter ( body , exp )
120
117
}
121
118
}
0 commit comments