1- var utils = require ( './utils' )
1+ var utils = require ( './utils' ) ,
2+ hasOwn = Object . prototype . hasOwnProperty
23
34// Variable extraction scooped from https://github.com/RubyLouvre/avalon
45
@@ -37,25 +38,45 @@ function getVariables (code) {
3738}
3839
3940/**
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
4342 */
44- // function getPaths (code, vars) {
45- // var pathRE = new RegExp("\\b(" + vars.join('|') + ")[$\\w\\.]*\\b", 'g')
46- // return code.match(pathRE)
47- // }
48-
4943function filterUnique ( vars ) {
5044 var hash = utils . hash ( ) ,
5145 i = vars . length ,
52- key
46+ key , res = [ ]
5347 while ( i -- ) {
5448 key = vars [ i ]
5549 if ( hash [ key ] ) continue
5650 hash [ key ] = 1
51+ res . push ( key )
5752 }
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
5980}
6081
6182/**
@@ -81,41 +102,17 @@ module.exports = {
81102 * from an arbitrary expression, together with a list of paths to be
82103 * created as bindings.
83104 */
84- parse : function ( exp ) {
105+ parse : function ( exp , compiler ) {
85106 // extract variable names
86107 var vars = getVariables ( exp )
87108 if ( ! vars . length ) {
88- return {
89- getter : makeGetter ( 'return ' + exp , exp )
90- }
109+ return makeGetter ( 'return ' + exp , exp )
91110 }
92- console . log ( vars )
93111 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
112112 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 )
120117 }
121118}
0 commit comments