@@ -86,26 +86,14 @@ for (var method in extensions) {
8686 def ( ArrayProxy , method , extensions [ method ] , ! hasProto )
8787}
8888
89- /**
90- * Watch an object based on type
91- */
92- function watch ( obj , path , observer ) {
93- var type = typeOf ( obj )
94- if ( type === 'Object' ) {
95- watchObject ( obj , path , observer )
96- } else if ( type === 'Array' ) {
97- watchArray ( obj , path , observer )
98- }
99- }
100-
10189/**
10290 * Watch an Object, recursive.
10391 */
10492function watchObject ( obj , path , observer ) {
10593 for ( var key in obj ) {
10694 var keyPrefix = key . charAt ( 0 )
10795 if ( keyPrefix !== '$' && keyPrefix !== '_' ) {
108- bind ( obj , key , path , observer )
96+ convert ( obj , key , observer )
10997 }
11098 }
11199}
@@ -131,33 +119,34 @@ function watchArray (arr, path, observer) {
131119 * so it emits get/set events.
132120 * Then watch the value itself.
133121 */
134- function bind ( obj , key , path , observer ) {
122+ function convert ( obj , key , observer ) {
135123 var val = obj [ key ] ,
136- watchable = isWatchable ( val ) ,
137- values = observer . values ,
138- fullKey = ( path ? path + '.' : '' ) + key
139- values [ fullKey ] = val
124+ values = observer . values
125+ values [ key ] = val
140126 // emit set on bind
141127 // this means when an object is observed it will emit
142128 // a first batch of set events.
143- observer . emit ( 'set' , fullKey , val )
129+ observer . emit ( 'set' , key , val )
144130 Object . defineProperty ( obj , key , {
145131 enumerable : true ,
146132 get : function ( ) {
133+ var value = values [ key ]
147134 // only emit get on tip values
148- if ( depsOb . active && ! watchable ) {
149- observer . emit ( 'get' , fullKey )
135+ if ( depsOb . active && ! isWatchable ( value ) ) {
136+ observer . emit ( 'get' , key )
150137 }
151- return values [ fullKey ]
138+ return value
152139 } ,
153140 set : function ( newVal ) {
154- values [ fullKey ] = newVal
155- ensurePaths ( key , newVal , values )
156- observer . emit ( 'set' , fullKey , newVal )
157- watch ( newVal , fullKey , observer )
141+ var oldVal = values [ key ]
142+ unobserve ( oldVal , key , observer )
143+ values [ key ] = newVal
144+ ensurePaths ( '' , newVal , oldVal )
145+ observer . emit ( 'set' , key , newVal )
146+ observe ( newVal , key , observer )
158147 }
159148 } )
160- watch ( val , fullKey , observer )
149+ observe ( val , key , observer )
161150}
162151
163152/**
@@ -175,14 +164,17 @@ function isWatchable (obj) {
175164 * the watch conversion and simply emit set event for
176165 * all of its properties.
177166 */
178- function emitSet ( obj , observer , set ) {
179- if ( typeOf ( obj ) === 'Array' ) {
180- set ( 'length' , obj . length )
181- } else {
182- var key , val , values = observer . values
183- for ( key in observer . values ) {
184- val = values [ key ]
185- set ( key , val )
167+ function emitSet ( obj ) {
168+ var type = typeOf ( obj ) ,
169+ emitter = obj . __observer__
170+ if ( type === 'Array' ) {
171+ emitter . emit ( 'set' , 'length' , obj . length )
172+ } else if ( type === 'Object' ) {
173+ var key , val
174+ for ( key in obj ) {
175+ val = obj [ key ]
176+ emitter . emit ( 'set' , key , val )
177+ emitSet ( val )
186178 }
187179 }
188180}
@@ -194,10 +186,10 @@ function emitSet (obj, observer, set) {
194186 * any given path.
195187 */
196188function ensurePaths ( key , val , paths ) {
197- key += '. '
189+ key = key ? key + '.' : ' '
198190 for ( var path in paths ) {
199- if ( ! path . indexOf ( key ) ) {
200- ensurePath ( val , path . replace ( key , '' ) )
191+ if ( ! key || ! path . indexOf ( key ) ) {
192+ ensurePath ( val , key ? path . replace ( key , '' ) : path )
201193 }
202194 }
203195}
@@ -222,68 +214,74 @@ function ensurePath (obj, key) {
222214 return obj [ sec ]
223215}
224216
225- module . exports = {
226-
227- // used in v-repeat
228- watchArray : watchArray ,
229- ensurePath : ensurePath ,
230- ensurePaths : ensurePaths ,
231-
232- /**
233- * Observe an object with a given path,
234- * and proxy get/set/mutate events to the provided observer.
235- */
236- observe : function ( obj , rawPath , observer ) {
237- if ( isWatchable ( obj ) ) {
238- var path = rawPath + '.' ,
239- ob , alreadyConverted = ! ! obj . __observer__
240- if ( ! alreadyConverted ) {
241- def ( obj , '__observer__' , new Emitter ( ) )
242- }
243- ob = obj . __observer__
244- ob . values = ob . values || utils . hash ( )
245- var proxies = observer . proxies [ path ] = {
246- get : function ( key ) {
247- observer . emit ( 'get' , path + key )
248- } ,
249- set : function ( key , val ) {
250- observer . emit ( 'set' , path + key , val )
251- } ,
252- mutate : function ( key , val , mutation ) {
253- // if the Array is a root value
254- // the key will be null
255- var fixedPath = key ? path + key : rawPath
256- observer . emit ( 'mutate' , fixedPath , val , mutation )
257- // also emit set for Array's length when it mutates
258- var m = mutation . method
259- if ( m !== 'sort' && m !== 'reverse' ) {
260- observer . emit ( 'set' , fixedPath + '.length' , val . length )
261- }
262- }
263- }
264- ob
265- . on ( 'get' , proxies . get )
266- . on ( 'set' , proxies . set )
267- . on ( 'mutate' , proxies . mutate )
268- if ( alreadyConverted ) {
269- emitSet ( obj , ob , proxies . set )
270- } else {
271- watch ( obj , null , ob )
217+ /**
218+ * Observe an object with a given path,
219+ * and proxy get/set/mutate events to the provided observer.
220+ */
221+ function observe ( obj , rawPath , observer ) {
222+ if ( ! isWatchable ( obj ) ) return
223+ var path = rawPath ? rawPath + '.' : '' ,
224+ ob , alreadyConverted = ! ! obj . __observer__
225+ if ( ! alreadyConverted ) {
226+ def ( obj , '__observer__' , new Emitter ( ) )
227+ }
228+ ob = obj . __observer__
229+ ob . values = ob . values || utils . hash ( )
230+ observer . proxies = observer . proxies || { }
231+ var proxies = observer . proxies [ path ] = {
232+ get : function ( key ) {
233+ observer . emit ( 'get' , path + key )
234+ } ,
235+ set : function ( key , val ) {
236+ observer . emit ( 'set' , path + key , val )
237+ } ,
238+ mutate : function ( key , val , mutation ) {
239+ // if the Array is a root value
240+ // the key will be null
241+ var fixedPath = key ? path + key : rawPath
242+ observer . emit ( 'mutate' , fixedPath , val , mutation )
243+ // also emit set for Array's length when it mutates
244+ var m = mutation . method
245+ if ( m !== 'sort' && m !== 'reverse' ) {
246+ observer . emit ( 'set' , fixedPath + '.length' , val . length )
272247 }
273248 }
274- } ,
275-
276- /**
277- * Cancel observation, turn off the listeners.
278- */
279- unobserve : function ( obj , path , observer ) {
280- if ( ! obj || ! obj . __observer__ ) return
281- path = path + '.'
282- var proxies = observer . proxies [ path ]
283- obj . __observer__
284- . off ( 'get' , proxies . get )
285- . off ( 'set' , proxies . set )
286- . off ( 'mutate' , proxies . mutate )
287- observer . proxies [ path ] = null
288249 }
250+ ob
251+ . on ( 'get' , proxies . get )
252+ . on ( 'set' , proxies . set )
253+ . on ( 'mutate' , proxies . mutate )
254+ if ( alreadyConverted ) {
255+ emitSet ( obj )
256+ } else {
257+ var type = typeOf ( obj )
258+ if ( type === 'Object' ) {
259+ watchObject ( obj , null , ob )
260+ } else if ( type === 'Array' ) {
261+ watchArray ( obj , null , ob )
262+ }
263+ }
264+ }
265+
266+ /**
267+ * Cancel observation, turn off the listeners.
268+ */
269+ function unobserve ( obj , path , observer ) {
270+ if ( ! obj || ! obj . __observer__ ) return
271+ path = path + '.'
272+ var proxies = observer . proxies [ path ]
273+ obj . __observer__
274+ . off ( 'get' , proxies . get )
275+ . off ( 'set' , proxies . set )
276+ . off ( 'mutate' , proxies . mutate )
277+ observer . proxies [ path ] = null
278+ }
279+
280+ module . exports = {
281+ observe : observe ,
282+ unobserve : unobserve ,
283+ ensurePath : ensurePath ,
284+ ensurePaths : ensurePaths ,
285+ // used in v-repeat
286+ watchArray : watchArray ,
289287}
0 commit comments