11/*!
2- * Vue.js v2.6.0-beta.1
2+ * Vue.js v2.6.0-beta.2
33 * (c) 2014-2019 Evan You
44 * Released under the MIT License.
55 */
@@ -358,7 +358,7 @@ var LIFECYCLE_HOOKS = [
358358 'activated' ,
359359 'deactivated' ,
360360 'errorCaptured' ,
361- 'ssrPrefetch '
361+ 'serverPrefetch '
362362] ;
363363
364364/* */
@@ -1878,6 +1878,8 @@ function logError (err, vm, info) {
18781878
18791879/* */
18801880
1881+ var isUsingMicroTask = false ;
1882+
18811883var callbacks = [ ] ;
18821884var pending = false ;
18831885
@@ -1921,6 +1923,7 @@ if (typeof Promise !== 'undefined' && isNative(Promise)) {
19211923 // "force" the microtask queue to be flushed by adding an empty timer.
19221924 if ( isIOS ) { setTimeout ( noop ) ; }
19231925 } ;
1926+ isUsingMicroTask = true ;
19241927} else if ( ! isIE && typeof MutationObserver !== 'undefined' && (
19251928 isNative ( MutationObserver ) ||
19261929 // PhantomJS and iOS 7.x
@@ -1939,6 +1942,7 @@ if (typeof Promise !== 'undefined' && isNative(Promise)) {
19391942 counter = ( counter + 1 ) % 2 ;
19401943 textNode . data = String ( counter ) ;
19411944 } ;
1945+ isUsingMicroTask = true ;
19421946} else if ( typeof setImmediate !== 'undefined' && isNative ( setImmediate ) ) {
19431947 // Fallback to setImmediate.
19441948 // Techinically it leverages the (macro) task queue,
@@ -2737,13 +2741,14 @@ function isWhitespace (node) {
27372741
27382742function resolveScopedSlots (
27392743 fns , // see flow/vnode
2744+ hasDynamicKeys ,
27402745 res
27412746) {
2742- res = res || { } ;
2747+ res = res || { $stable : ! hasDynamicKeys } ;
27432748 for ( var i = 0 ; i < fns . length ; i ++ ) {
27442749 var slot = fns [ i ] ;
27452750 if ( Array . isArray ( slot ) ) {
2746- resolveScopedSlots ( slot , res ) ;
2751+ resolveScopedSlots ( slot , hasDynamicKeys , res ) ;
27472752 } else {
27482753 res [ slot . key ] = slot . fn ;
27492754 }
@@ -2959,12 +2964,22 @@ function updateChildComponent (
29592964 }
29602965
29612966 // determine whether component has slot children
2962- // we need to do this before overwriting $options._renderChildren
2963- var hasChildren = ! ! (
2967+ // we need to do this before overwriting $options._renderChildren.
2968+
2969+ // check if there are dynamic scopedSlots (hand-written or compiled but with
2970+ // dynamic slot names). Static scoped slots compiled from template has the
2971+ // "$stable" marker.
2972+ var hasDynamicScopedSlot = ! ! (
2973+ ( parentVnode . data . scopedSlots && ! parentVnode . data . scopedSlots . $stable ) ||
2974+ ( vm . $scopedSlots !== emptyObject && ! vm . $scopedSlots . $stable )
2975+ ) ;
2976+ // Any static slot children from the parent may have changed during parent's
2977+ // update. Dynamic scoped slots may also have changed. In such cases, a forced
2978+ // update is necessary to ensure correctness.
2979+ var needsForceUpdate = ! ! (
29642980 renderChildren || // has new static slots
29652981 vm . $options . _renderChildren || // has old static slots
2966- parentVnode . data . scopedSlots || // has new scoped slots
2967- vm . $scopedSlots !== emptyObject // has old scoped slots
2982+ hasDynamicScopedSlot
29682983 ) ;
29692984
29702985 vm . $options . _parentVnode = parentVnode ;
@@ -3003,7 +3018,7 @@ function updateChildComponent (
30033018 updateComponentListeners ( vm , listeners , oldListeners ) ;
30043019
30053020 // resolve slots + force update if has children
3006- if ( hasChildren ) {
3021+ if ( needsForceUpdate ) {
30073022 vm . $slots = resolveSlots ( renderChildren , parentVnode . context ) ;
30083023 vm . $forceUpdate ( ) ;
30093024 }
@@ -3094,10 +3109,32 @@ function resetSchedulerState () {
30943109 waiting = flushing = false ;
30953110}
30963111
3112+ // Async edge case #6566 requires saving the timestamp when event listeners are
3113+ // attached. However, calling performance.now() has a perf overhead especially
3114+ // if the page has thousands of event listeners. Instead, we take a timestamp
3115+ // every time the scheduler flushes and use that for all event listeners
3116+ // attached during that flush.
3117+ var currentFlushTimestamp = 0 ;
3118+
3119+ // Async edge case fix requires storing an event listener's attach timestamp.
3120+ var getNow = Date . now ;
3121+
3122+ // Determine what event timestamp the browser is using. Annoyingly, the
3123+ // timestamp can either be hi-res ( relative to poge load) or low-res
3124+ // (relative to UNIX epoch), so in order to compare time we have to use the
3125+ // same timestamp type when saving the flush timestamp.
3126+ if ( inBrowser && getNow ( ) > document . createEvent ( 'Event' ) . timeStamp ) {
3127+ // if the low-res timestamp which is bigger than the event timestamp
3128+ // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
3129+ // and we need to use the hi-res version for event listeners as well.
3130+ getNow = function ( ) { return performance . now ( ) ; } ;
3131+ }
3132+
30973133/**
30983134 * Flush both queues and run the watchers.
30993135 */
31003136function flushSchedulerQueue ( ) {
3137+ currentFlushTimestamp = getNow ( ) ;
31013138 flushing = true ;
31023139 var watcher , id ;
31033140
@@ -3854,7 +3891,7 @@ function normalizeScopedSlots (
38543891 } else {
38553892 res = { } ;
38563893 for ( var key in slots ) {
3857- if ( slots [ key ] ) {
3894+ if ( slots [ key ] && key [ 0 ] !== '$' ) {
38583895 res [ key ] = normalizeScopedSlot ( slots [ key ] ) ;
38593896 }
38603897 }
@@ -3866,6 +3903,7 @@ function normalizeScopedSlots (
38663903 }
38673904 }
38683905 res . _normalized = true ;
3906+ res . $stable = slots && slots . $stable ;
38693907 return res
38703908}
38713909
@@ -4144,6 +4182,31 @@ function bindObjectListeners (data, value) {
41444182
41454183/* */
41464184
4185+ function bindDynamicKeys ( baseObj , values ) {
4186+ for ( var i = 0 ; i < values . length ; i += 2 ) {
4187+ var key = values [ i ] ;
4188+ if ( typeof key === 'string' && key ) {
4189+ baseObj [ values [ i ] ] = values [ i + 1 ] ;
4190+ } else if ( process . env . NODE_ENV !== 'production' && key !== '' && key !== null ) {
4191+ // null is a speical value for explicitly removing a binding
4192+ warn (
4193+ ( "Invalid value for dynamic directive argument (expected string or null): " + key ) ,
4194+ this
4195+ ) ;
4196+ }
4197+ }
4198+ return baseObj
4199+ }
4200+
4201+ // helper to dynamically append modifier runtime markers to event names.
4202+ // ensure only append when value is already string, otherwise it will be cast
4203+ // to string and cause the type check to miss.
4204+ function prependModifier ( value , symbol ) {
4205+ return typeof value === 'string' ? symbol + value : value
4206+ }
4207+
4208+ /* */
4209+
41474210function installRenderHelpers ( target ) {
41484211 target . _o = markOnce ;
41494212 target . _n = toNumber ;
@@ -4160,6 +4223,8 @@ function installRenderHelpers (target) {
41604223 target . _e = createEmptyVNode ;
41614224 target . _u = resolveScopedSlots ;
41624225 target . _g = bindObjectListeners ;
4226+ target . _d = bindDynamicKeys ;
4227+ target . _p = prependModifier ;
41634228}
41644229
41654230/* */
@@ -5265,7 +5330,7 @@ Object.defineProperty(Vue, 'FunctionalRenderContext', {
52655330 value : FunctionalRenderContext
52665331} ) ;
52675332
5268- Vue . version = '2.6.0-beta.1 ' ;
5333+ Vue . version = '2.6.0-beta.2 ' ;
52695334
52705335/* */
52715336
@@ -6409,6 +6474,7 @@ function _update (oldVnode, vnode) {
64096474 } else {
64106475 // existing directive, update
64116476 dir . oldValue = oldDir . value ;
6477+ dir . oldArg = oldDir . arg ;
64126478 callHook$1 ( dir , 'update' , vnode , oldVnode ) ;
64136479 if ( dir . def && dir . def . componentUpdated ) {
64146480 dirsWithPostpatch . push ( dir ) ;
@@ -6686,17 +6752,17 @@ function add$1 (
66866752 capture ,
66876753 passive
66886754) {
6689- if ( isChrome ) {
6690- // async edge case #6566: inner click event triggers patch, event handler
6691- // attached to outer element during patch, and triggered again. This only
6692- // happens in Chrome as it fires microtask ticks between event propagation.
6693- // the solution is simple: we save the timestamp when a handler is attached,
6694- // and the handler would only fire if the event passed to it was fired
6695- // AFTER it was attached.
6696- var now = performance . now ( ) ;
6755+ // async edge case #6566: inner click event triggers patch, event handler
6756+ // attached to outer element during patch, and triggered again. This
6757+ // happens because browsers fire microtask ticks between event propagation.
6758+ // the solution is simple: we save the timestamp when a handler is attached,
6759+ // and the handler would only fire if the event passed to it was fired
6760+ // AFTER it was attached.
6761+ if ( isUsingMicroTask ) {
6762+ var attachedTimestamp = currentFlushTimestamp ;
66976763 var original = handler ;
66986764 handler = original . _wrapper = function ( e ) {
6699- if ( e . timeStamp >= now ) {
6765+ if ( e . timeStamp >= attachedTimestamp ) {
67006766 return original . apply ( this , arguments )
67016767 }
67026768 } ;
@@ -6777,14 +6843,11 @@ function updateDOMProps (oldVnode, vnode) {
67776843 }
67786844 }
67796845
6780- // #4521: if a click event triggers update before the change event is
6781- // dispatched on a checkbox/radio input, the input's checked state will
6782- // be reset and fail to trigger another update.
6783- // The root cause here is that browsers may fire microtasks in between click/change.
6784- // In Chrome / Firefox, click event fires before change, thus having this problem.
6785- // In Safari / Edge, the order is opposite.
6786- // Note: in Edge, if you click too fast, only the click event would fire twice.
6787- if ( key === 'checked' && ! isNotInFocusAndDirty ( elm , cur ) ) {
6846+ // skip the update if old and new VDOM state is the same.
6847+ // the only exception is `value` where the DOM value may be temporarily
6848+ // out of sync with VDOM state due to focus, composition and modifiers.
6849+ // This also covers #4521 by skipping the unnecesarry `checked` update.
6850+ if ( key !== 'value' && cur === oldProps [ key ] ) {
67886851 continue
67896852 }
67906853
0 commit comments