@@ -494,13 +494,7 @@ function popTarget() {
494
494
Dep . target = targetStack . pop ( ) ;
495
495
}
496
496
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
-
502
497
var queue = [ ] ;
503
- var userQueue = [ ] ;
504
498
var has = { } ;
505
499
var circular = { } ;
506
500
var waiting = false ;
@@ -512,7 +506,6 @@ var index = 0;
512
506
*/
513
507
function resetSchedulerState ( ) {
514
508
queue . length = 0 ;
515
- userQueue . length = 0 ;
516
509
has = { } ;
517
510
if ( process . env . NODE_ENV !== 'production' ) {
518
511
circular = { } ;
@@ -525,31 +518,19 @@ function resetSchedulerState() {
525
518
*/
526
519
function flushSchedulerQueue ( ) {
527
520
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
- }
537
521
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
+ } ) ;
548
533
549
- /**
550
- * Run the watchers in a single queue.
551
- */
552
- function runSchedulerQueue ( queue ) {
553
534
// do not cache length because more watchers might be pushed
554
535
// as we run existing watchers
555
536
for ( index = 0 ; index < queue . length ; index ++ ) {
@@ -566,7 +547,14 @@ function runSchedulerQueue(queue) {
566
547
}
567
548
}
568
549
}
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 ( ) ;
570
558
}
571
559
572
560
/**
@@ -577,22 +565,17 @@ function runSchedulerQueue(queue) {
577
565
function queueWatcher ( watcher ) {
578
566
var id = watcher . id ;
579
567
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
586
568
has [ id ] = true ;
587
- var q = watcher . user ? userQueue : queue ;
588
569
if ( ! flushing ) {
589
- q . push ( watcher ) ;
570
+ queue . push ( watcher ) ;
590
571
} 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 ) {
593
576
i -- ;
594
577
}
595
- q . splice ( Math . max ( i , index ) + 1 , 0 , watcher ) ;
578
+ queue . splice ( Math . max ( i , index ) + 1 , 0 , watcher ) ;
596
579
}
597
580
// queue the flush
598
581
if ( ! waiting ) {
@@ -2567,9 +2550,10 @@ function validateProp(key, propOptions, propsData, vm) {
2567
2550
value = getPropDefaultValue ( vm , prop , key ) ;
2568
2551
// since the default value is a fresh copy,
2569
2552
// make sure to observe it.
2553
+ var prevShouldConvert = observerState . shouldConvert ;
2570
2554
observerState . shouldConvert = true ;
2571
2555
observe ( value ) ;
2572
- observerState . shouldConvert = false ;
2556
+ observerState . shouldConvert = prevShouldConvert ;
2573
2557
}
2574
2558
if ( process . env . NODE_ENV !== 'production' ) {
2575
2559
assertProp ( prop , key , value , vm , absent ) ;
@@ -2894,7 +2878,7 @@ Object.defineProperty(Vue.prototype, '$isServer', {
2894
2878
}
2895
2879
} ) ;
2896
2880
2897
- Vue . version = '2.0.0-beta.3 ' ;
2881
+ Vue . version = '2.0.0-beta.4 ' ;
2898
2882
2899
2883
// attributes that should be using props for binding
2900
2884
var mustUseProp = makeMap ( 'value,selected,checked,muted' ) ;
@@ -3047,6 +3031,14 @@ var isIE = UA$1 && /msie|trident/.test(UA$1);
3047
3031
var isIE9 = UA$1 && UA$1 . indexOf ( 'msie 9.0' ) > 0 ;
3048
3032
var isAndroid = UA$1 && UA$1 . indexOf ( 'android' ) > 0 ;
3049
3033
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
+
3050
3042
/**
3051
3043
* Query an element selector if it's not an element already.
3052
3044
*/
@@ -4035,7 +4027,8 @@ function enter(vnode) {
4035
4027
var appearCancelled = data . appearCancelled ;
4036
4028
4037
4029
4038
- var isAppear = ! vnode . context . $root . _isMounted ;
4030
+ var context = vnode . context . $parent || vnode . context ;
4031
+ var isAppear = ! context . _isMounted ;
4039
4032
if ( isAppear && ! appear && appear !== '' ) {
4040
4033
return ;
4041
4034
}
0 commit comments