aboutsummaryrefslogtreecommitdiff
path: root/node_modules/vue/src/platforms/web/runtime/modules/transition.js
diff options
context:
space:
mode:
authorruki <waruqi@gmail.com>2018-11-08 00:38:48 +0800
committerruki <waruqi@gmail.com>2018-11-07 21:53:09 +0800
commit26105034da4fcce7ac883c899d781f016559310d (patch)
treec459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/vue/src/platforms/web/runtime/modules/transition.js
parent2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff)
downloadxmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz
xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip
switch to vuepress
Diffstat (limited to 'node_modules/vue/src/platforms/web/runtime/modules/transition.js')
-rw-r--r--node_modules/vue/src/platforms/web/runtime/modules/transition.js343
1 files changed, 343 insertions, 0 deletions
diff --git a/node_modules/vue/src/platforms/web/runtime/modules/transition.js b/node_modules/vue/src/platforms/web/runtime/modules/transition.js
new file mode 100644
index 00000000..0796b5da
--- /dev/null
+++ b/node_modules/vue/src/platforms/web/runtime/modules/transition.js
@@ -0,0 +1,343 @@
+/* @flow */
+
+import { inBrowser, isIE9, warn } from 'core/util/index'
+import { mergeVNodeHook } from 'core/vdom/helpers/index'
+import { activeInstance } from 'core/instance/lifecycle'
+
+import {
+ once,
+ isDef,
+ isUndef,
+ isObject,
+ toNumber
+} from 'shared/util'
+
+import {
+ nextFrame,
+ resolveTransition,
+ whenTransitionEnds,
+ addTransitionClass,
+ removeTransitionClass
+} from '../transition-util'
+
+export function enter (vnode: VNodeWithData, toggleDisplay: ?() => void) {
+ const el: any = vnode.elm
+
+ // call leave callback now
+ if (isDef(el._leaveCb)) {
+ el._leaveCb.cancelled = true
+ el._leaveCb()
+ }
+
+ const data = resolveTransition(vnode.data.transition)
+ if (isUndef(data)) {
+ return
+ }
+
+ /* istanbul ignore if */
+ if (isDef(el._enterCb) || el.nodeType !== 1) {
+ return
+ }
+
+ const {
+ css,
+ type,
+ enterClass,
+ enterToClass,
+ enterActiveClass,
+ appearClass,
+ appearToClass,
+ appearActiveClass,
+ beforeEnter,
+ enter,
+ afterEnter,
+ enterCancelled,
+ beforeAppear,
+ appear,
+ afterAppear,
+ appearCancelled,
+ duration
+ } = data
+
+ // activeInstance will always be the <transition> component managing this
+ // transition. One edge case to check is when the <transition> is placed
+ // as the root node of a child component. In that case we need to check
+ // <transition>'s parent for appear check.
+ let context = activeInstance
+ let transitionNode = activeInstance.$vnode
+ while (transitionNode && transitionNode.parent) {
+ transitionNode = transitionNode.parent
+ context = transitionNode.context
+ }
+
+ const isAppear = !context._isMounted || !vnode.isRootInsert
+
+ if (isAppear && !appear && appear !== '') {
+ return
+ }
+
+ const startClass = isAppear && appearClass
+ ? appearClass
+ : enterClass
+ const activeClass = isAppear && appearActiveClass
+ ? appearActiveClass
+ : enterActiveClass
+ const toClass = isAppear && appearToClass
+ ? appearToClass
+ : enterToClass
+
+ const beforeEnterHook = isAppear
+ ? (beforeAppear || beforeEnter)
+ : beforeEnter
+ const enterHook = isAppear
+ ? (typeof appear === 'function' ? appear : enter)
+ : enter
+ const afterEnterHook = isAppear
+ ? (afterAppear || afterEnter)
+ : afterEnter
+ const enterCancelledHook = isAppear
+ ? (appearCancelled || enterCancelled)
+ : enterCancelled
+
+ const explicitEnterDuration: any = toNumber(
+ isObject(duration)
+ ? duration.enter
+ : duration
+ )
+
+ if (process.env.NODE_ENV !== 'production' && explicitEnterDuration != null) {
+ checkDuration(explicitEnterDuration, 'enter', vnode)
+ }
+
+ const expectsCSS = css !== false && !isIE9
+ const userWantsControl = getHookArgumentsLength(enterHook)
+
+ const cb = el._enterCb = once(() => {
+ if (expectsCSS) {
+ removeTransitionClass(el, toClass)
+ removeTransitionClass(el, activeClass)
+ }
+ if (cb.cancelled) {
+ if (expectsCSS) {
+ removeTransitionClass(el, startClass)
+ }
+ enterCancelledHook && enterCancelledHook(el)
+ } else {
+ afterEnterHook && afterEnterHook(el)
+ }
+ el._enterCb = null
+ })
+
+ if (!vnode.data.show) {
+ // remove pending leave element on enter by injecting an insert hook
+ mergeVNodeHook(vnode, 'insert', () => {
+ const parent = el.parentNode
+ const pendingNode = parent && parent._pending && parent._pending[vnode.key]
+ if (pendingNode &&
+ pendingNode.tag === vnode.tag &&
+ pendingNode.elm._leaveCb
+ ) {
+ pendingNode.elm._leaveCb()
+ }
+ enterHook && enterHook(el, cb)
+ })
+ }
+
+ // start enter transition
+ beforeEnterHook && beforeEnterHook(el)
+ if (expectsCSS) {
+ addTransitionClass(el, startClass)
+ addTransitionClass(el, activeClass)
+ nextFrame(() => {
+ removeTransitionClass(el, startClass)
+ if (!cb.cancelled) {
+ addTransitionClass(el, toClass)
+ if (!userWantsControl) {
+ if (isValidDuration(explicitEnterDuration)) {
+ setTimeout(cb, explicitEnterDuration)
+ } else {
+ whenTransitionEnds(el, type, cb)
+ }
+ }
+ }
+ })
+ }
+
+ if (vnode.data.show) {
+ toggleDisplay && toggleDisplay()
+ enterHook && enterHook(el, cb)
+ }
+
+ if (!expectsCSS && !userWantsControl) {
+ cb()
+ }
+}
+
+export function leave (vnode: VNodeWithData, rm: Function) {
+ const el: any = vnode.elm
+
+ // call enter callback now
+ if (isDef(el._enterCb)) {
+ el._enterCb.cancelled = true
+ el._enterCb()
+ }
+
+ const data = resolveTransition(vnode.data.transition)
+ if (isUndef(data) || el.nodeType !== 1) {
+ return rm()
+ }
+
+ /* istanbul ignore if */
+ if (isDef(el._leaveCb)) {
+ return
+ }
+
+ const {
+ css,
+ type,
+ leaveClass,
+ leaveToClass,
+ leaveActiveClass,
+ beforeLeave,
+ leave,
+ afterLeave,
+ leaveCancelled,
+ delayLeave,
+ duration
+ } = data
+
+ const expectsCSS = css !== false && !isIE9
+ const userWantsControl = getHookArgumentsLength(leave)
+
+ const explicitLeaveDuration: any = toNumber(
+ isObject(duration)
+ ? duration.leave
+ : duration
+ )
+
+ if (process.env.NODE_ENV !== 'production' && isDef(explicitLeaveDuration)) {
+ checkDuration(explicitLeaveDuration, 'leave', vnode)
+ }
+
+ const cb = el._leaveCb = once(() => {
+ if (el.parentNode && el.parentNode._pending) {
+ el.parentNode._pending[vnode.key] = null
+ }
+ if (expectsCSS) {
+ removeTransitionClass(el, leaveToClass)
+ removeTransitionClass(el, leaveActiveClass)
+ }
+ if (cb.cancelled) {
+ if (expectsCSS) {
+ removeTransitionClass(el, leaveClass)
+ }
+ leaveCancelled && leaveCancelled(el)
+ } else {
+ rm()
+ afterLeave && afterLeave(el)
+ }
+ el._leaveCb = null
+ })
+
+ if (delayLeave) {
+ delayLeave(performLeave)
+ } else {
+ performLeave()
+ }
+
+ function performLeave () {
+ // the delayed leave may have already been cancelled
+ if (cb.cancelled) {
+ return
+ }
+ // record leaving element
+ if (!vnode.data.show) {
+ (el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key: any)] = vnode
+ }
+ beforeLeave && beforeLeave(el)
+ if (expectsCSS) {
+ addTransitionClass(el, leaveClass)
+ addTransitionClass(el, leaveActiveClass)
+ nextFrame(() => {
+ removeTransitionClass(el, leaveClass)
+ if (!cb.cancelled) {
+ addTransitionClass(el, leaveToClass)
+ if (!userWantsControl) {
+ if (isValidDuration(explicitLeaveDuration)) {
+ setTimeout(cb, explicitLeaveDuration)
+ } else {
+ whenTransitionEnds(el, type, cb)
+ }
+ }
+ }
+ })
+ }
+ leave && leave(el, cb)
+ if (!expectsCSS && !userWantsControl) {
+ cb()
+ }
+ }
+}
+
+// only used in dev mode
+function checkDuration (val, name, vnode) {
+ if (typeof val !== 'number') {
+ warn(
+ `<transition> explicit ${name} duration is not a valid number - ` +
+ `got ${JSON.stringify(val)}.`,
+ vnode.context
+ )
+ } else if (isNaN(val)) {
+ warn(
+ `<transition> explicit ${name} duration is NaN - ` +
+ 'the duration expression might be incorrect.',
+ vnode.context
+ )
+ }
+}
+
+function isValidDuration (val) {
+ return typeof val === 'number' && !isNaN(val)
+}
+
+/**
+ * Normalize a transition hook's argument length. The hook may be:
+ * - a merged hook (invoker) with the original in .fns
+ * - a wrapped component method (check ._length)
+ * - a plain function (.length)
+ */
+function getHookArgumentsLength (fn: Function): boolean {
+ if (isUndef(fn)) {
+ return false
+ }
+ const invokerFns = fn.fns
+ if (isDef(invokerFns)) {
+ // invoker
+ return getHookArgumentsLength(
+ Array.isArray(invokerFns)
+ ? invokerFns[0]
+ : invokerFns
+ )
+ } else {
+ return (fn._length || fn.length) > 1
+ }
+}
+
+function _enter (_: any, vnode: VNodeWithData) {
+ if (vnode.data.show !== true) {
+ enter(vnode)
+ }
+}
+
+export default inBrowser ? {
+ create: _enter,
+ activate: _enter,
+ remove (vnode: VNode, rm: Function) {
+ /* istanbul ignore else */
+ if (vnode.data.show !== true) {
+ leave(vnode, rm)
+ } else {
+ rm()
+ }
+ }
+} : {}