diff options
Diffstat (limited to 'node_modules/vue/src/platforms/weex/runtime/modules')
6 files changed, 543 insertions, 0 deletions
diff --git a/node_modules/vue/src/platforms/weex/runtime/modules/attrs.js b/node_modules/vue/src/platforms/weex/runtime/modules/attrs.js new file mode 100755 index 00000000..1b6185ca --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/modules/attrs.js @@ -0,0 +1,44 @@ +/* @flow */ + +import { extend } from 'shared/util' + +function updateAttrs (oldVnode: VNodeWithData, vnode: VNodeWithData) { + if (!oldVnode.data.attrs && !vnode.data.attrs) { + return + } + let key, cur, old + const elm = vnode.elm + const oldAttrs = oldVnode.data.attrs || {} + let attrs = vnode.data.attrs || {} + // clone observed objects, as the user probably wants to mutate it + if (attrs.__ob__) { + attrs = vnode.data.attrs = extend({}, attrs) + } + + const supportBatchUpdate = typeof elm.setAttrs === 'function' + const batchedAttrs = {} + for (key in attrs) { + cur = attrs[key] + old = oldAttrs[key] + if (old !== cur) { + supportBatchUpdate + ? (batchedAttrs[key] = cur) + : elm.setAttr(key, cur) + } + } + for (key in oldAttrs) { + if (attrs[key] == null) { + supportBatchUpdate + ? (batchedAttrs[key] = undefined) + : elm.setAttr(key) + } + } + if (supportBatchUpdate) { + elm.setAttrs(batchedAttrs) + } +} + +export default { + create: updateAttrs, + update: updateAttrs +} diff --git a/node_modules/vue/src/platforms/weex/runtime/modules/class.js b/node_modules/vue/src/platforms/weex/runtime/modules/class.js new file mode 100755 index 00000000..029b9e9e --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/modules/class.js @@ -0,0 +1,75 @@ +/* @flow */ + +import { extend } from 'shared/util' + +function updateClass (oldVnode: VNodeWithData, vnode: VNodeWithData) { + const el = vnode.elm + const ctx = vnode.context + + const data: VNodeData = vnode.data + const oldData: VNodeData = oldVnode.data + if (!data.staticClass && + !data.class && + (!oldData || (!oldData.staticClass && !oldData.class)) + ) { + return + } + + const oldClassList = [] + // unlike web, weex vnode staticClass is an Array + const oldStaticClass: any = oldData.staticClass + if (oldStaticClass) { + oldClassList.push.apply(oldClassList, oldStaticClass) + } + if (oldData.class) { + oldClassList.push.apply(oldClassList, oldData.class) + } + + const classList = [] + // unlike web, weex vnode staticClass is an Array + const staticClass: any = data.staticClass + if (staticClass) { + classList.push.apply(classList, staticClass) + } + if (data.class) { + classList.push.apply(classList, data.class) + } + + if (typeof el.setClassList === 'function') { + el.setClassList(classList) + } else { + const style = getStyle(oldClassList, classList, ctx) + if (typeof el.setStyles === 'function') { + el.setStyles(style) + } else { + for (const key in style) { + el.setStyle(key, style[key]) + } + } + } +} + +function getStyle (oldClassList: Array<string>, classList: Array<string>, ctx: Component): Object { + // style is a weex-only injected object + // compiled from <style> tags in weex files + const stylesheet: any = ctx.$options.style || {} + const result = {} + classList.forEach(name => { + const style = stylesheet[name] + extend(result, style) + }) + oldClassList.forEach(name => { + const style = stylesheet[name] + for (const key in style) { + if (!result.hasOwnProperty(key)) { + result[key] = '' + } + } + }) + return result +} + +export default { + create: updateClass, + update: updateClass +} diff --git a/node_modules/vue/src/platforms/weex/runtime/modules/events.js b/node_modules/vue/src/platforms/weex/runtime/modules/events.js new file mode 100755 index 00000000..a3f9e25a --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/modules/events.js @@ -0,0 +1,57 @@ +/* @flow */ + +import { updateListeners } from 'core/vdom/helpers/update-listeners' + +let target: any + +function add ( + event: string, + handler: Function, + once: boolean, + capture: boolean, + passive?: boolean, + params?: Array<any> +) { + if (capture) { + console.log('Weex do not support event in bubble phase.') + return + } + if (once) { + const oldHandler = handler + const _target = target // save current target element in closure + handler = function (ev) { + const res = arguments.length === 1 + ? oldHandler(ev) + : oldHandler.apply(null, arguments) + if (res !== null) { + remove(event, null, null, _target) + } + } + } + target.addEvent(event, handler, params) +} + +function remove ( + event: string, + handler: any, + capture: any, + _target?: any +) { + (_target || target).removeEvent(event) +} + +function updateDOMListeners (oldVnode: VNodeWithData, vnode: VNodeWithData) { + if (!oldVnode.data.on && !vnode.data.on) { + return + } + const on = vnode.data.on || {} + const oldOn = oldVnode.data.on || {} + target = vnode.elm + updateListeners(on, oldOn, add, remove, vnode.context) + target = undefined +} + +export default { + create: updateDOMListeners, + update: updateDOMListeners +} diff --git a/node_modules/vue/src/platforms/weex/runtime/modules/index.js b/node_modules/vue/src/platforms/weex/runtime/modules/index.js new file mode 100755 index 00000000..dd384484 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/modules/index.js @@ -0,0 +1,13 @@ +import attrs from './attrs' +import klass from './class' +import events from './events' +import style from './style' +import transition from './transition' + +export default [ + attrs, + klass, + events, + style, + transition +] diff --git a/node_modules/vue/src/platforms/weex/runtime/modules/style.js b/node_modules/vue/src/platforms/weex/runtime/modules/style.js new file mode 100755 index 00000000..bdabd17b --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/modules/style.js @@ -0,0 +1,84 @@ +/* @flow */ + +import { extend, cached, camelize } from 'shared/util' + +const normalize = cached(camelize) + +function createStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) { + if (!vnode.data.staticStyle) { + updateStyle(oldVnode, vnode) + return + } + const elm = vnode.elm + const staticStyle = vnode.data.staticStyle + const supportBatchUpdate = typeof elm.setStyles === 'function' + const batchedStyles = {} + for (const name in staticStyle) { + if (staticStyle[name]) { + supportBatchUpdate + ? (batchedStyles[normalize(name)] = staticStyle[name]) + : elm.setStyle(normalize(name), staticStyle[name]) + } + } + if (supportBatchUpdate) { + elm.setStyles(batchedStyles) + } + updateStyle(oldVnode, vnode) +} + +function updateStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) { + if (!oldVnode.data.style && !vnode.data.style) { + return + } + let cur, name + const elm = vnode.elm + const oldStyle: any = oldVnode.data.style || {} + let style: any = vnode.data.style || {} + + const needClone = style.__ob__ + + // handle array syntax + if (Array.isArray(style)) { + style = vnode.data.style = toObject(style) + } + + // clone the style for future updates, + // in case the user mutates the style object in-place. + if (needClone) { + style = vnode.data.style = extend({}, style) + } + + const supportBatchUpdate = typeof elm.setStyles === 'function' + const batchedStyles = {} + for (name in oldStyle) { + if (!style[name]) { + supportBatchUpdate + ? (batchedStyles[normalize(name)] = '') + : elm.setStyle(normalize(name), '') + } + } + for (name in style) { + cur = style[name] + supportBatchUpdate + ? (batchedStyles[normalize(name)] = cur) + : elm.setStyle(normalize(name), cur) + } + if (supportBatchUpdate) { + elm.setStyles(batchedStyles) + } +} + +function toObject (arr) { + const res = {} + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]) + } + } + return res +} + +export default { + create: createStyle, + update: updateStyle +} diff --git a/node_modules/vue/src/platforms/weex/runtime/modules/transition.js b/node_modules/vue/src/platforms/weex/runtime/modules/transition.js new file mode 100644 index 00000000..e474c2b3 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/modules/transition.js @@ -0,0 +1,270 @@ +import { warn } from 'core/util/debug' +import { extend, once, noop } from 'shared/util' +import { activeInstance } from 'core/instance/lifecycle' +import { resolveTransition } from 'web/runtime/transition-util' + +export default { + create: enter, + activate: enter, + remove: leave +} + +function enter (_, vnode) { + const el = vnode.elm + + // call leave callback now + if (el._leaveCb) { + el._leaveCb.cancelled = true + el._leaveCb() + } + + const data = resolveTransition(vnode.data.transition) + if (!data) { + return + } + + /* istanbul ignore if */ + if (el._enterCb) { + return + } + + const { + enterClass, + enterToClass, + enterActiveClass, + appearClass, + appearToClass, + appearActiveClass, + beforeEnter, + enter, + afterEnter, + enterCancelled, + beforeAppear, + appear, + afterAppear, + appearCancelled + } = data + + 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 : enterClass + const toClass = isAppear ? appearToClass : enterToClass + const activeClass = isAppear ? appearActiveClass : enterActiveClass + 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 userWantsControl = + enterHook && + // enterHook may be a bound method which exposes + // the length of original fn as _length + (enterHook._length || enterHook.length) > 1 + + const stylesheet = vnode.context.$options.style || {} + const startState = stylesheet[startClass] + const transitionProperties = (stylesheet['@TRANSITION'] && stylesheet['@TRANSITION'][activeClass]) || {} + const endState = getEnterTargetState(el, stylesheet, startClass, toClass, activeClass, vnode.context) + const needAnimation = Object.keys(endState).length > 0 + + const cb = el._enterCb = once(() => { + if (cb.cancelled) { + enterCancelledHook && enterCancelledHook(el) + } else { + afterEnterHook && afterEnterHook(el) + } + el._enterCb = null + }) + + // We need to wait until the native element has been inserted, but currently + // there's no API to do that. So we have to wait "one frame" - not entirely + // sure if this is guaranteed to be enough (e.g. on slow devices?) + setTimeout(() => { + const parent = el.parentNode + const pendingNode = parent && parent._pending && parent._pending[vnode.key] + if (pendingNode && + pendingNode.context === vnode.context && + pendingNode.tag === vnode.tag && + pendingNode.elm._leaveCb + ) { + pendingNode.elm._leaveCb() + } + enterHook && enterHook(el, cb) + + if (needAnimation) { + const animation = vnode.context.$requireWeexModule('animation') + animation.transition(el.ref, { + styles: endState, + duration: transitionProperties.duration || 0, + delay: transitionProperties.delay || 0, + timingFunction: transitionProperties.timingFunction || 'linear' + }, userWantsControl ? noop : cb) + } else if (!userWantsControl) { + cb() + } + }, 16) + + // start enter transition + beforeEnterHook && beforeEnterHook(el) + + if (startState) { + if (typeof el.setStyles === 'function') { + el.setStyles(startState) + } else { + for (const key in startState) { + el.setStyle(key, startState[key]) + } + } + } + + if (!needAnimation && !userWantsControl) { + cb() + } +} + +function leave (vnode, rm) { + const el = vnode.elm + + // call enter callback now + if (el._enterCb) { + el._enterCb.cancelled = true + el._enterCb() + } + + const data = resolveTransition(vnode.data.transition) + if (!data) { + return rm() + } + + if (el._leaveCb) { + return + } + + const { + leaveClass, + leaveToClass, + leaveActiveClass, + beforeLeave, + leave, + afterLeave, + leaveCancelled, + delayLeave + } = data + + const userWantsControl = + leave && + // leave hook may be a bound method which exposes + // the length of original fn as _length + (leave._length || leave.length) > 1 + + const stylesheet = vnode.context.$options.style || {} + const startState = stylesheet[leaveClass] + const endState = stylesheet[leaveToClass] || stylesheet[leaveActiveClass] + const transitionProperties = (stylesheet['@TRANSITION'] && stylesheet['@TRANSITION'][leaveActiveClass]) || {} + + const cb = el._leaveCb = once(() => { + if (el.parentNode && el.parentNode._pending) { + el.parentNode._pending[vnode.key] = null + } + if (cb.cancelled) { + leaveCancelled && leaveCancelled(el) + } else { + rm() + afterLeave && afterLeave(el) + } + el._leaveCb = null + }) + + if (delayLeave) { + delayLeave(performLeave) + } else { + performLeave() + } + + function performLeave () { + const animation = vnode.context.$requireWeexModule('animation') + // 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] = vnode + } + beforeLeave && beforeLeave(el) + + if (startState) { + animation.transition(el.ref, { + styles: startState + }, next) + } else { + next() + } + + function next () { + animation.transition(el.ref, { + styles: endState, + duration: transitionProperties.duration || 0, + delay: transitionProperties.delay || 0, + timingFunction: transitionProperties.timingFunction || 'linear' + }, userWantsControl ? noop : cb) + } + + leave && leave(el, cb) + if (!endState && !userWantsControl) { + cb() + } + } +} + +// determine the target animation style for an entering transition. +function getEnterTargetState (el, stylesheet, startClass, endClass, activeClass, vm) { + const targetState = {} + const startState = stylesheet[startClass] + const endState = stylesheet[endClass] + const activeState = stylesheet[activeClass] + // 1. fallback to element's default styling + if (startState) { + for (const key in startState) { + targetState[key] = el.style[key] + if ( + process.env.NODE_ENV !== 'production' && + targetState[key] == null && + (!activeState || activeState[key] == null) && + (!endState || endState[key] == null) + ) { + warn( + `transition property "${key}" is declared in enter starting class (.${startClass}), ` + + `but not declared anywhere in enter ending class (.${endClass}), ` + + `enter active cass (.${activeClass}) or the element's default styling. ` + + `Note in Weex, CSS properties need explicit values to be transitionable.` + ) + } + } + } + // 2. if state is mixed in active state, extract them while excluding + // transition properties + if (activeState) { + for (const key in activeState) { + if (key.indexOf('transition') !== 0) { + targetState[key] = activeState[key] + } + } + } + // 3. explicit endState has highest priority + if (endState) { + extend(targetState, endState) + } + return targetState +} |
