Skip to content

Commit 701942f

Browse files
committed
wip: weex basic transition support
1 parent a36dc07 commit 701942f

File tree

4 files changed

+277
-2
lines changed

4 files changed

+277
-2
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Transition from 'web/runtime/components/transition'
2+
3+
export default {
4+
Transition
5+
}

src/platforms/weex/runtime/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
import Vue from 'core/index'
44
import { patch } from 'weex/runtime/patch'
55
import platformDirectives from 'weex/runtime/directives/index'
6+
import platformComponents from 'weex/runtime/components/index'
67
import { query, isUnknownElement, isReservedTag, mustUseProp } from 'weex/util/index'
78

89
// install platform specific utils
910
Vue.config.isUnknownElement = isUnknownElement
1011
Vue.config.isReservedTag = isReservedTag
1112
Vue.config.mustUseProp = mustUseProp
1213

13-
// install platform runtime directives
14+
// install platform runtime directives and components
1415
Vue.options.directives = platformDirectives
16+
Vue.options.components = platformComponents
1517

1618
// install platform patch function
1719
Vue.prototype.__patch__ = patch

src/platforms/weex/runtime/modules/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import attrs from './attrs'
22
import klass from './class'
33
import events from './events'
44
import style from './style'
5+
import transition from './transition'
56

67
export default [
78
attrs,
89
klass,
910
events,
10-
style
11+
style,
12+
transition
1113
]
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
import { extend, cached, noop } from 'shared/util'
2+
import { activeInstance } from 'core/instance/lifecycle'
3+
4+
export default {
5+
create: enter,
6+
activate: enter,
7+
remove: leave
8+
}
9+
10+
function enter (_, vnode) {
11+
const el = vnode.elm
12+
13+
// call leave callback now
14+
if (el._leaveCb) {
15+
el._leaveCb.cancelled = true
16+
el._leaveCb()
17+
}
18+
19+
const data = resolveTransition(vnode.data.transition)
20+
if (!data) {
21+
return
22+
}
23+
24+
/* istanbul ignore if */
25+
if (el._enterCb) {
26+
return
27+
}
28+
29+
const {
30+
enterClass,
31+
enterActiveClass,
32+
appearClass,
33+
appearActiveClass,
34+
beforeEnter,
35+
enter,
36+
afterEnter,
37+
enterCancelled,
38+
beforeAppear,
39+
appear,
40+
afterAppear,
41+
appearCancelled
42+
} = data
43+
44+
let context = activeInstance
45+
let transitionNode = activeInstance.$vnode
46+
while (transitionNode && transitionNode.parent) {
47+
transitionNode = transitionNode.parent
48+
context = transitionNode.context
49+
}
50+
51+
const isAppear = !context._isMounted || !vnode.isRootInsert
52+
53+
if (isAppear && !appear && appear !== '') {
54+
return
55+
}
56+
57+
const startClass = isAppear ? appearClass : enterClass
58+
const activeClass = isAppear ? appearActiveClass : enterActiveClass
59+
const beforeEnterHook = isAppear ? (beforeAppear || beforeEnter) : beforeEnter
60+
const enterHook = isAppear ? (typeof appear === 'function' ? appear : enter) : enter
61+
const afterEnterHook = isAppear ? (afterAppear || afterEnter) : afterEnter
62+
const enterCancelledHook = isAppear ? (appearCancelled || enterCancelled) : enterCancelled
63+
64+
const userWantsControl =
65+
enterHook &&
66+
// enterHook may be a bound method which exposes
67+
// the length of original fn as _length
68+
(enterHook._length || enterHook.length) > 1
69+
70+
const stylesheet = vnode.context.$options.style || {}
71+
const startState = stylesheet[startClass]
72+
const endState = stylesheet[activeClass]
73+
const expectsCSS = startState && endState
74+
75+
const cb = el._enterCb = once(() => {
76+
if (cb.cancelled) {
77+
enterCancelledHook && enterCancelledHook(el)
78+
} else {
79+
afterEnterHook && afterEnterHook(el)
80+
}
81+
el._enterCb = null
82+
})
83+
84+
// remove pending leave element on enter by injecting an insert hook
85+
// mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', () => {
86+
87+
// }, 'transition-insert')
88+
89+
setTimeout(() => {
90+
const parent = el.parentNode
91+
const pendingNode = parent && parent._pending && parent._pending[vnode.key]
92+
if (pendingNode &&
93+
pendingNode.context === vnode.context &&
94+
pendingNode.tag === vnode.tag &&
95+
pendingNode.elm._leaveCb) {
96+
pendingNode.elm._leaveCb()
97+
}
98+
enterHook && enterHook(el, cb)
99+
100+
if (endState) {
101+
const animation = vnode.context.$options.animation
102+
animation.transition(el.ref, {
103+
styles: endState,
104+
duration: 300,
105+
timingFunction: 'ease-in-out'
106+
}, userWantsControl ? noop : cb)
107+
} else if (!userWantsControl) {
108+
cb()
109+
}
110+
// if (expectsCSS) {
111+
// animation.transition(el.ref, {
112+
// styles: startState
113+
// }, () => {
114+
// animation.transition(el.ref, {
115+
// styles: endState,
116+
// duration: 300,
117+
// timingFunction: 'ease-in-out'
118+
// }, userWantsControl ? noop : cb)
119+
// })
120+
// }
121+
}, 16)
122+
123+
// start enter transition
124+
beforeEnterHook && beforeEnterHook(el)
125+
126+
if (startState) {
127+
for (const key in startState) {
128+
el.setStyle(key, startState[key])
129+
}
130+
}
131+
132+
if (!expectsCSS && !userWantsControl) {
133+
cb()
134+
}
135+
}
136+
137+
function leave (vnode, rm) {
138+
const el = vnode.elm
139+
140+
// call enter callback now
141+
if (el._enterCb) {
142+
el._enterCb.cancelled = true
143+
el._enterCb()
144+
}
145+
146+
const data = resolveTransition(vnode.data.transition)
147+
if (!data) {
148+
return rm()
149+
}
150+
151+
if (el._leaveCb) {
152+
return
153+
}
154+
155+
const {
156+
leaveClass,
157+
leaveActiveClass,
158+
beforeLeave,
159+
leave,
160+
afterLeave,
161+
leaveCancelled,
162+
delayLeave
163+
} = data
164+
165+
const userWantsControl =
166+
leave &&
167+
// leave hook may be a bound method which exposes
168+
// the length of original fn as _length
169+
(leave._length || leave.length) > 1
170+
171+
const stylesheet = vnode.context.$options.style || {}
172+
const startState = stylesheet[leaveClass]
173+
const endState = stylesheet[leaveActiveClass]
174+
const expectsCSS = startState && endState
175+
176+
const cb = el._leaveCb = once(() => {
177+
if (el.parentNode && el.parentNode._pending) {
178+
el.parentNode._pending[vnode.key] = null
179+
}
180+
if (cb.cancelled) {
181+
leaveCancelled && leaveCancelled(el)
182+
} else {
183+
rm()
184+
afterLeave && afterLeave(el)
185+
}
186+
el._leaveCb = null
187+
})
188+
189+
if (delayLeave) {
190+
delayLeave(performLeave)
191+
} else {
192+
performLeave()
193+
}
194+
195+
function performLeave () {
196+
const animation = vnode.context.$options.animation
197+
// the delayed leave may have already been cancelled
198+
if (cb.cancelled) {
199+
return
200+
}
201+
// record leaving element
202+
if (!vnode.data.show) {
203+
(el.parentNode._pending || (el.parentNode._pending = {}))[vnode.key] = vnode
204+
}
205+
beforeLeave && beforeLeave(el)
206+
207+
if (startState) {
208+
animation.transition(el.ref, {
209+
styles: startState
210+
}, next)
211+
} else {
212+
next()
213+
}
214+
215+
function next () {
216+
animation.transition(el.ref, {
217+
styles: endState,
218+
duration: 300,
219+
timingFunction: 'ease-in-out'
220+
}, userWantsControl ? noop : cb)
221+
}
222+
223+
leave && leave(el, cb)
224+
if (!expectsCSS && !userWantsControl) {
225+
cb()
226+
}
227+
}
228+
}
229+
230+
function resolveTransition (def) {
231+
if (!def) {
232+
return
233+
}
234+
/* istanbul ignore else */
235+
if (typeof def === 'object') {
236+
const res = {}
237+
if (def.css !== false) {
238+
extend(res, autoCssTransition(def.name || 'v'))
239+
}
240+
extend(res, def)
241+
return res
242+
} else if (typeof def === 'string') {
243+
return autoCssTransition(def)
244+
}
245+
}
246+
247+
function once (fn) {
248+
let called = false
249+
return () => {
250+
if (!called) {
251+
called = true
252+
fn()
253+
}
254+
}
255+
}
256+
257+
const autoCssTransition = cached(name => {
258+
return {
259+
enterClass: `${name}-enter`,
260+
leaveClass: `${name}-leave`,
261+
appearClass: `${name}-enter`,
262+
enterActiveClass: `${name}-enter-active`,
263+
leaveActiveClass: `${name}-leave-active`,
264+
appearActiveClass: `${name}-enter-active`
265+
}
266+
})

0 commit comments

Comments
 (0)