@@ -494,13 +494,7 @@ function popTarget() {
494494 Dep . target = targetStack . pop ( ) ;
495495}
496496
497- // We have two separate queues: one for internal component re-render updates
498- // and one for user watcher registered via $watch(). We want to guarantee
499- // re-render updates to be called before user watchers so that when user
500- // watchers are triggered, the DOM would already be in updated state.
501-
502497var queue = [ ] ;
503- var userQueue = [ ] ;
504498var has = { } ;
505499var circular = { } ;
506500var waiting = false ;
@@ -512,7 +506,6 @@ var index = 0;
512506 */
513507function resetSchedulerState ( ) {
514508 queue . length = 0 ;
515- userQueue . length = 0 ;
516509 has = { } ;
517510 if ( process . env . NODE_ENV !== 'production' ) {
518511 circular = { } ;
@@ -525,31 +518,19 @@ function resetSchedulerState() {
525518 */
526519function flushSchedulerQueue ( ) {
527520 flushing = true ;
528- runSchedulerQueue ( userQueue ) ;
529- runSchedulerQueue ( queue . sort ( queueSorter ) ) ;
530- // devtool hook
531- /* istanbul ignore if */
532- if ( devtools && config . devtools ) {
533- devtools . emit ( 'flush' ) ;
534- }
535- resetSchedulerState ( ) ;
536- }
537521
538- /**
539- * Sort queue before flush.
540- * This ensures components are updated from parent to child
541- * so there will be no duplicate updates, e.g. a child was
542- * pushed into the queue first and then its parent's props
543- * changed.
544- */
545- function queueSorter ( a , b ) {
546- return a . id - b . id ;
547- }
522+ // Sort queue before flush.
523+ // This ensures that:
524+ // 1. Components are updated from parent to child. (because parent is always
525+ // created before the child)
526+ // 2. A component's user watchers are run before its render watcher (because
527+ // user watchers are created before the render watcher)
528+ // 3. If a component is destroyed during a parent component's watcher run,
529+ // its watchers can be skipped.
530+ queue . sort ( function ( a , b ) {
531+ return a . id - b . id ;
532+ } ) ;
548533
549- /**
550- * Run the watchers in a single queue.
551- */
552- function runSchedulerQueue ( queue ) {
553534 // do not cache length because more watchers might be pushed
554535 // as we run existing watchers
555536 for ( index = 0 ; index < queue . length ; index ++ ) {
@@ -566,7 +547,14 @@ function runSchedulerQueue(queue) {
566547 }
567548 }
568549 }
569- queue . length = 0 ;
550+
551+ // devtool hook
552+ /* istanbul ignore if */
553+ if ( devtools && config . devtools ) {
554+ devtools . emit ( 'flush' ) ;
555+ }
556+
557+ resetSchedulerState ( ) ;
570558}
571559
572560/**
@@ -577,22 +565,17 @@ function runSchedulerQueue(queue) {
577565function queueWatcher ( watcher ) {
578566 var id = watcher . id ;
579567 if ( has [ id ] == null ) {
580- // if already flushing, and all user watchers have already been run,
581- // run the new user watcher immediately.
582- if ( flushing && watcher . user && ! userQueue . length ) {
583- return watcher . run ( ) ;
584- }
585- // push watcher into appropriate queue
586568 has [ id ] = true ;
587- var q = watcher . user ? userQueue : queue ;
588569 if ( ! flushing ) {
589- q . push ( watcher ) ;
570+ queue . push ( watcher ) ;
590571 } else {
591- var i = q . length - 1 ;
592- while ( i >= 0 && q [ i ] . id > watcher . id ) {
572+ // if already flushing, splice the watcher based on its id
573+ // if already past its id, it will be run next immediately.
574+ var i = queue . length - 1 ;
575+ while ( i >= 0 && queue [ i ] . id > watcher . id ) {
593576 i -- ;
594577 }
595- q . splice ( Math . max ( i , index ) + 1 , 0 , watcher ) ;
578+ queue . splice ( Math . max ( i , index ) + 1 , 0 , watcher ) ;
596579 }
597580 // queue the flush
598581 if ( ! waiting ) {
@@ -2567,9 +2550,10 @@ function validateProp(key, propOptions, propsData, vm) {
25672550 value = getPropDefaultValue ( vm , prop , key ) ;
25682551 // since the default value is a fresh copy,
25692552 // make sure to observe it.
2553+ var prevShouldConvert = observerState . shouldConvert ;
25702554 observerState . shouldConvert = true ;
25712555 observe ( value ) ;
2572- observerState . shouldConvert = false ;
2556+ observerState . shouldConvert = prevShouldConvert ;
25732557 }
25742558 if ( process . env . NODE_ENV !== 'production' ) {
25752559 assertProp ( prop , key , value , vm , absent ) ;
@@ -2894,7 +2878,7 @@ Object.defineProperty(Vue.prototype, '$isServer', {
28942878 }
28952879} ) ;
28962880
2897- Vue . version = '2.0.0-beta.3 ' ;
2881+ Vue . version = '2.0.0-beta.4 ' ;
28982882
28992883// attributes that should be using props for binding
29002884var mustUseProp = makeMap ( 'value,selected,checked,muted' ) ;
@@ -3047,6 +3031,14 @@ var isIE = UA$1 && /msie|trident/.test(UA$1);
30473031var isIE9 = UA$1 && UA$1 . indexOf ( 'msie 9.0' ) > 0 ;
30483032var isAndroid = UA$1 && UA$1 . indexOf ( 'android' ) > 0 ;
30493033
3034+ // some browsers, e.g. PhantomJS, encodes attribute values for innerHTML
3035+ // this causes problems with the in-browser parser.
3036+ var shouldDecodeAttr = inBrowser ? function ( ) {
3037+ var div = document . createElement ( 'div' ) ;
3038+ div . innerHTML = '<div a=">">' ;
3039+ return div . innerHTML . indexOf ( '>' ) > 0 ;
3040+ } ( ) : false ;
3041+
30503042/**
30513043 * Query an element selector if it's not an element already.
30523044 */
@@ -4035,7 +4027,8 @@ function enter(vnode) {
40354027 var appearCancelled = data . appearCancelled ;
40364028
40374029
4038- var isAppear = ! vnode . context . $root . _isMounted ;
4030+ var context = vnode . context . $parent || vnode . context ;
4031+ var isAppear = ! context . _isMounted ;
40394032 if ( isAppear && ! appear && appear !== '' ) {
40404033 return ;
40414034 }
0 commit comments