From 26105034da4fcce7ac883c899d781f016559310d Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 8 Nov 2018 00:38:48 +0800 Subject: switch to vuepress --- .../platforms/weex/compiler/directives/index.js | 5 + .../platforms/weex/compiler/directives/model.js | 34 +++ .../vue/src/platforms/weex/compiler/index.js | 52 ++++ .../src/platforms/weex/compiler/modules/append.js | 27 +++ .../src/platforms/weex/compiler/modules/class.js | 73 ++++++ .../src/platforms/weex/compiler/modules/index.js | 13 + .../src/platforms/weex/compiler/modules/props.js | 32 +++ .../modules/recycle-list/component-root.js | 16 ++ .../compiler/modules/recycle-list/component.js | 16 ++ .../weex/compiler/modules/recycle-list/index.js | 60 +++++ .../compiler/modules/recycle-list/recycle-list.js | 50 ++++ .../weex/compiler/modules/recycle-list/text.js | 23 ++ .../weex/compiler/modules/recycle-list/v-bind.js | 21 ++ .../weex/compiler/modules/recycle-list/v-for.js | 33 +++ .../weex/compiler/modules/recycle-list/v-if.js | 63 +++++ .../weex/compiler/modules/recycle-list/v-on.js | 25 ++ .../weex/compiler/modules/recycle-list/v-once.js | 19 ++ .../src/platforms/weex/compiler/modules/style.js | 86 +++++++ .../vue/src/platforms/weex/entry-compiler.js | 1 + .../vue/src/platforms/weex/entry-framework.js | 187 ++++++++++++++ .../src/platforms/weex/entry-runtime-factory.js | 6 + .../src/platforms/weex/runtime/components/index.js | 9 + .../platforms/weex/runtime/components/richtext.js | 82 +++++++ .../weex/runtime/components/transition-group.js | 148 +++++++++++ .../weex/runtime/components/transition.js | 9 + .../src/platforms/weex/runtime/directives/index.js | 2 + .../vue/src/platforms/weex/runtime/index.js | 42 ++++ .../src/platforms/weex/runtime/modules/attrs.js | 44 ++++ .../src/platforms/weex/runtime/modules/class.js | 75 ++++++ .../src/platforms/weex/runtime/modules/events.js | 57 +++++ .../src/platforms/weex/runtime/modules/index.js | 13 + .../src/platforms/weex/runtime/modules/style.js | 84 +++++++ .../platforms/weex/runtime/modules/transition.js | 270 +++++++++++++++++++++ .../vue/src/platforms/weex/runtime/node-ops.js | 91 +++++++ .../vue/src/platforms/weex/runtime/patch.js | 16 ++ .../recycle-list/render-component-template.js | 34 +++ .../weex/runtime/recycle-list/virtual-component.js | 136 +++++++++++ .../vue/src/platforms/weex/runtime/text-node.js | 9 + .../vue/src/platforms/weex/util/element.js | 52 ++++ node_modules/vue/src/platforms/weex/util/index.js | 40 +++ node_modules/vue/src/platforms/weex/util/parser.js | 60 +++++ 41 files changed, 2115 insertions(+) create mode 100755 node_modules/vue/src/platforms/weex/compiler/directives/index.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/directives/model.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/index.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/append.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/class.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/index.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/props.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/index.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/recycle-list.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-for.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-if.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/style.js create mode 100644 node_modules/vue/src/platforms/weex/entry-compiler.js create mode 100644 node_modules/vue/src/platforms/weex/entry-framework.js create mode 100644 node_modules/vue/src/platforms/weex/entry-runtime-factory.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/index.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/richtext.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/transition-group.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/transition.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/directives/index.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/index.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/attrs.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/class.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/events.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/index.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/style.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/modules/transition.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/node-ops.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/patch.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/recycle-list/render-component-template.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/recycle-list/virtual-component.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/text-node.js create mode 100644 node_modules/vue/src/platforms/weex/util/element.js create mode 100755 node_modules/vue/src/platforms/weex/util/index.js create mode 100644 node_modules/vue/src/platforms/weex/util/parser.js (limited to 'node_modules/vue/src/platforms/weex') diff --git a/node_modules/vue/src/platforms/weex/compiler/directives/index.js b/node_modules/vue/src/platforms/weex/compiler/directives/index.js new file mode 100755 index 00000000..12ced224 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/directives/index.js @@ -0,0 +1,5 @@ +import model from './model' + +export default { + model +} diff --git a/node_modules/vue/src/platforms/weex/compiler/directives/model.js b/node_modules/vue/src/platforms/weex/compiler/directives/model.js new file mode 100644 index 00000000..6c9b7685 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/directives/model.js @@ -0,0 +1,34 @@ +/* @flow */ + +import { addHandler, addAttr } from 'compiler/helpers' +import { genComponentModel, genAssignmentCode } from 'compiler/directives/model' + +export default function model ( + el: ASTElement, + dir: ASTDirective, + _warn: Function +): ?boolean { + if (el.tag === 'input' || el.tag === 'textarea') { + genDefaultModel(el, dir.value, dir.modifiers) + } else { + genComponentModel(el, dir.value, dir.modifiers) + } +} + +function genDefaultModel ( + el: ASTElement, + value: string, + modifiers: ?ASTModifiers +): ?boolean { + const { lazy, trim, number } = modifiers || {} + const event = lazy ? 'change' : 'input' + + let valueExpression = `$event.target.attr.value${trim ? '.trim()' : ''}` + if (number) { + valueExpression = `_n(${valueExpression})` + } + + const code = genAssignmentCode(value, valueExpression) + addAttr(el, 'value', `(${value})`) + addHandler(el, event, code, null, true) +} diff --git a/node_modules/vue/src/platforms/weex/compiler/index.js b/node_modules/vue/src/platforms/weex/compiler/index.js new file mode 100644 index 00000000..94f350b8 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/index.js @@ -0,0 +1,52 @@ +/* @flow */ + +import { genStaticKeys } from 'shared/util' +import { createCompiler } from 'compiler/index' + +import modules from './modules/index' +import directives from './directives/index' + +import { + isUnaryTag, + mustUseProp, + isReservedTag, + canBeLeftOpenTag, + getTagNamespace +} from '../util/element' + +export const baseOptions: WeexCompilerOptions = { + modules, + directives, + isUnaryTag, + mustUseProp, + canBeLeftOpenTag, + isReservedTag, + getTagNamespace, + preserveWhitespace: false, + recyclable: false, + staticKeys: genStaticKeys(modules) +} + +const compiler = createCompiler(baseOptions) + +export function compile ( + template: string, + options?: WeexCompilerOptions +): WeexCompiledResult { + let generateAltRender = false + if (options && options.recyclable === true) { + generateAltRender = true + options.recyclable = false + } + const result = compiler.compile(template, options) + + // generate @render function for + if (options && generateAltRender) { + options.recyclable = true + // disable static optimizations + options.optimize = false + const { render } = compiler.compile(template, options) + result['@render'] = render + } + return result +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/append.js b/node_modules/vue/src/platforms/weex/compiler/modules/append.js new file mode 100644 index 00000000..6e7be267 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/append.js @@ -0,0 +1,27 @@ +/* @flow */ + +import { makeMap } from 'shared/util' + +// The "unitary tag" means that the tag node and its children +// must be sent to the native together. +const isUnitaryTag = makeMap('cell,header,cell-slot,recycle-list', true) + +function preTransformNode (el: ASTElement, options: CompilerOptions) { + if (isUnitaryTag(el.tag) && !el.attrsList.some(item => item.name === 'append')) { + el.attrsMap.append = 'tree' + el.attrsList.push({ name: 'append', value: 'tree' }) + } + if (el.attrsMap.append === 'tree') { + el.appendAsTree = true + } +} + +function genData (el: ASTElement): string { + return el.appendAsTree ? `appendAsTree:true,` : '' +} + +export default { + staticKeys: ['appendAsTree'], + preTransformNode, + genData +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/class.js b/node_modules/vue/src/platforms/weex/compiler/modules/class.js new file mode 100644 index 00000000..371a08ea --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/class.js @@ -0,0 +1,73 @@ +/* @flow */ + +import { parseText } from 'compiler/parser/text-parser' +import { + getAndRemoveAttr, + getBindingAttr, + baseWarn +} from 'compiler/helpers' + +type StaticClassResult = { + dynamic: boolean, + classResult: string +}; + +function transformNode (el: ASTElement, options: CompilerOptions) { + const warn = options.warn || baseWarn + const staticClass = getAndRemoveAttr(el, 'class') + const { dynamic, classResult } = parseStaticClass(staticClass, options) + if (process.env.NODE_ENV !== 'production' && dynamic && staticClass) { + warn( + `class="${staticClass}": ` + + 'Interpolation inside attributes has been deprecated. ' + + 'Use v-bind or the colon shorthand instead.' + ) + } + if (!dynamic && classResult) { + el.staticClass = classResult + } + const classBinding = getBindingAttr(el, 'class', false /* getStatic */) + if (classBinding) { + el.classBinding = classBinding + } else if (dynamic) { + el.classBinding = classResult + } +} + +function genData (el: ASTElement): string { + let data = '' + if (el.staticClass) { + data += `staticClass:${el.staticClass},` + } + if (el.classBinding) { + data += `class:${el.classBinding},` + } + return data +} + +function parseStaticClass (staticClass: ?string, options: CompilerOptions): StaticClassResult { + // "a b c" -> ["a", "b", "c"] => staticClass: ["a", "b", "c"] + // "a {{x}} c" -> ["a", x, "c"] => classBinding: '["a", x, "c"]' + let dynamic = false + let classResult = '' + if (staticClass) { + const classList = staticClass.trim().split(' ').map(name => { + const result = parseText(name, options.delimiters) + if (result) { + dynamic = true + return result.expression + } + return JSON.stringify(name) + }) + if (classList.length) { + classResult = '[' + classList.join(',') + ']' + } + } + return { dynamic, classResult } +} + +export default { + staticKeys: ['staticClass'], + transformNode, + genData +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/index.js b/node_modules/vue/src/platforms/weex/compiler/modules/index.js new file mode 100644 index 00000000..ac17809e --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/index.js @@ -0,0 +1,13 @@ +import klass from './class' +import style from './style' +import props from './props' +import append from './append' +import recycleList from './recycle-list/index' + +export default [ + recycleList, + klass, + style, + props, + append +] diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/props.js b/node_modules/vue/src/platforms/weex/compiler/modules/props.js new file mode 100644 index 00000000..8b0bb5f2 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/props.js @@ -0,0 +1,32 @@ +/* @flow */ + +import { cached, camelize } from 'shared/util' + +const normalize = cached(camelize) + +function normalizeKeyName (str: string): string { + if (str.match(/^v\-/)) { + return str.replace(/(v-[a-z\-]+\:)([a-z\-]+)$/i, ($, directive, prop) => { + return directive + normalize(prop) + }) + } + return normalize(str) +} + +function transformNode (el: ASTElement, options: CompilerOptions) { + if (Array.isArray(el.attrsList)) { + el.attrsList.forEach(attr => { + if (attr.name && attr.name.match(/\-/)) { + const realName = normalizeKeyName(attr.name) + if (el.attrsMap) { + el.attrsMap[realName] = el.attrsMap[attr.name] + delete el.attrsMap[attr.name] + } + attr.name = realName + } + }) + } +} +export default { + transformNode +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js new file mode 100644 index 00000000..7d9fedea --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js @@ -0,0 +1,16 @@ +/* @flow */ + +import { addAttr } from 'compiler/helpers' + +// mark component root nodes as +export function postTransformComponentRoot ( + el: ASTElement, + options: WeexCompilerOptions +) { + if (!el.parent) { + // component root + addAttr(el, '@isComponentRoot', 'true') + addAttr(el, '@templateId', '_uid') + addAttr(el, '@componentProps', '$props || {}') + } +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js new file mode 100644 index 00000000..36d7dfd5 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js @@ -0,0 +1,16 @@ +/* @flow */ + +import { addAttr } from 'compiler/helpers' +import { RECYCLE_LIST_MARKER } from 'weex/util/index' + +// mark components as inside recycle-list so that we know we need to invoke +// their special @render function instead of render in create-component.js +export function postTransformComponent ( + el: ASTElement, + options: WeexCompilerOptions +) { + // $flow-disable-line (we know isReservedTag is there) + if (!options.isReservedTag(el.tag) && el.tag !== 'cell-slot') { + addAttr(el, RECYCLE_LIST_MARKER, 'true') + } +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/index.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/index.js new file mode 100644 index 00000000..502cc782 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/index.js @@ -0,0 +1,60 @@ +/* @flow */ + +import { preTransformRecycleList } from './recycle-list' +import { postTransformComponent } from './component' +import { postTransformComponentRoot } from './component-root' +import { postTransformText } from './text' +import { preTransformVBind } from './v-bind' +import { preTransformVIf } from './v-if' +import { preTransformVFor } from './v-for' +import { postTransformVOn } from './v-on' +import { preTransformVOnce } from './v-once' + +let currentRecycleList = null + +function shouldCompile (el: ASTElement, options: WeexCompilerOptions) { + return options.recyclable || + (currentRecycleList && el !== currentRecycleList) +} + +function preTransformNode (el: ASTElement, options: WeexCompilerOptions) { + if (el.tag === 'recycle-list') { + preTransformRecycleList(el, options) + currentRecycleList = el + } + if (shouldCompile(el, options)) { + preTransformVBind(el, options) + preTransformVIf(el, options) // also v-else-if and v-else + preTransformVFor(el, options) + preTransformVOnce(el, options) + } +} + +function transformNode (el: ASTElement, options: WeexCompilerOptions) { + if (shouldCompile(el, options)) { + // do nothing yet + } +} + +function postTransformNode (el: ASTElement, options: WeexCompilerOptions) { + if (shouldCompile(el, options)) { + // mark child component in parent template + postTransformComponent(el, options) + // mark root in child component template + postTransformComponentRoot(el, options) + // : transform children text into value attr + if (el.tag === 'text') { + postTransformText(el, options) + } + postTransformVOn(el, options) + } + if (el === currentRecycleList) { + currentRecycleList = null + } +} + +export default { + preTransformNode, + transformNode, + postTransformNode +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/recycle-list.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/recycle-list.js new file mode 100644 index 00000000..7fb65167 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/recycle-list.js @@ -0,0 +1,50 @@ +/* @flow */ + +import { parseFor } from 'compiler/parser/index' +import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers' + +/** + * Map the following syntax to corresponding attrs: + * + * + * ... + * ... + * + */ + +export function preTransformRecycleList ( + el: ASTElement, + options: WeexCompilerOptions +) { + const exp = getAndRemoveAttr(el, 'for') + if (!exp) { + if (options.warn) { + options.warn(`Invalid syntax: missing "for" expression.`) + } + return + } + + const res = parseFor(exp) + if (!res) { + if (options.warn) { + options.warn(`Invalid syntax: ${exp}.`) + } + return + } + + addRawAttr(el, ':list-data', res.for) + addRawAttr(el, 'binding-expression', res.for) + addRawAttr(el, 'alias', res.alias) + if (res.iterator2) { + // (item, key, index) for object iteration + // is this even supported? + addRawAttr(el, 'index', res.iterator2) + } else if (res.iterator1) { + addRawAttr(el, 'index', res.iterator1) + } + + const switchKey = getAndRemoveAttr(el, 'switch') + if (switchKey) { + addRawAttr(el, 'switch', switchKey) + } +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js new file mode 100644 index 00000000..575ec7f6 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js @@ -0,0 +1,23 @@ +/* @flow */ + +import { addAttr } from 'compiler/helpers' + +function genText (node: ASTNode) { + const value = node.type === 3 + ? node.text + : node.type === 2 + ? node.tokens.length === 1 + ? node.tokens[0] + : node.tokens + : '' + return JSON.stringify(value) +} + +export function postTransformText (el: ASTElement, options: WeexCompilerOptions) { + // weex can only contain text, so the parser + // always generates a single child. + if (el.children.length) { + addAttr(el, 'value', genText(el.children[0])) + el.children = [] + } +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js new file mode 100644 index 00000000..effdf351 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js @@ -0,0 +1,21 @@ +/* @flow */ + +import { camelize } from 'shared/util' +import { generateBinding } from 'weex/util/parser' +import { bindRE } from 'compiler/parser/index' +import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers' + +function parseAttrName (name: string): string { + return camelize(name.replace(bindRE, '')) +} + +export function preTransformVBind (el: ASTElement, options: WeexCompilerOptions) { + for (const attr in el.attrsMap) { + if (bindRE.test(attr)) { + const name: string = parseAttrName(attr) + const value = generateBinding(getAndRemoveAttr(el, attr)) + delete el.attrsMap[attr] + addRawAttr(el, name, value) + } + } +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-for.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-for.js new file mode 100644 index 00000000..9f09e4b4 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-for.js @@ -0,0 +1,33 @@ +/* @flow */ + +import { parseFor } from 'compiler/parser/index' +import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers' + +export function preTransformVFor (el: ASTElement, options: WeexCompilerOptions) { + const exp = getAndRemoveAttr(el, 'v-for') + if (!exp) { + return + } + + const res = parseFor(exp) + if (!res) { + if (process.env.NODE_ENV !== 'production' && options.warn) { + options.warn(`Invalid v-for expression: ${exp}`) + } + return + } + + const desc: Object = { + '@expression': res.for, + '@alias': res.alias + } + if (res.iterator2) { + desc['@key'] = res.iterator1 + desc['@index'] = res.iterator2 + } else { + desc['@index'] = res.iterator1 + } + + delete el.attrsMap['v-for'] + addRawAttr(el, '[[repeat]]', desc) +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-if.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-if.js new file mode 100644 index 00000000..d82ba632 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-if.js @@ -0,0 +1,63 @@ +/* @flow */ + +import { addIfCondition } from 'compiler/parser/index' +import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers' + +function hasConditionDirective (el: ASTElement): boolean { + for (const attr in el.attrsMap) { + if (/^v\-if|v\-else|v\-else\-if$/.test(attr)) { + return true + } + } + return false +} + +function getPreviousConditions (el: ASTElement): Array { + const conditions = [] + if (el.parent && el.parent.children) { + for (let c = 0, n = el.parent.children.length; c < n; ++c) { + // $flow-disable-line + const ifConditions = el.parent.children[c].ifConditions + if (ifConditions) { + for (let i = 0, l = ifConditions.length; i < l; ++i) { + const condition = ifConditions[i] + if (condition && condition.exp) { + conditions.push(condition.exp) + } + } + } + } + } + return conditions +} + +export function preTransformVIf (el: ASTElement, options: WeexCompilerOptions) { + if (hasConditionDirective(el)) { + let exp + const ifExp = getAndRemoveAttr(el, 'v-if', true /* remove from attrsMap */) + const elseifExp = getAndRemoveAttr(el, 'v-else-if', true) + // don't need the value, but remove it to avoid being generated as a + // custom directive + getAndRemoveAttr(el, 'v-else', true) + if (ifExp) { + exp = ifExp + addIfCondition(el, { exp: ifExp, block: el }) + } else { + elseifExp && addIfCondition(el, { exp: elseifExp, block: el }) + const prevConditions = getPreviousConditions(el) + if (prevConditions.length) { + const prevMatch = prevConditions.join(' || ') + exp = elseifExp + ? `!(${prevMatch}) && (${elseifExp})` // v-else-if + : `!(${prevMatch})` // v-else + } else if (process.env.NODE_ENV !== 'production' && options.warn) { + options.warn( + `v-${elseifExp ? ('else-if="' + elseifExp + '"') : 'else'} ` + + `used on element <${el.tag}> without corresponding v-if.` + ) + return + } + } + addRawAttr(el, '[[match]]', exp) + } +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js new file mode 100644 index 00000000..b1ba262c --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js @@ -0,0 +1,25 @@ +/* @flow */ + +const inlineStatementRE = /^\s*([A-Za-z_$0-9\['\."\]]+)*\s*\(\s*(([A-Za-z_$0-9\['\."\]]+)?(\s*,\s*([A-Za-z_$0-9\['\."\]]+))*)\s*\)$/ + +function parseHandlerParams (handler: ASTElementHandler) { + const res = inlineStatementRE.exec(handler.value) + if (res && res[2]) { + handler.params = res[2].split(/\s*,\s*/) + } +} + +export function postTransformVOn (el: ASTElement, options: WeexCompilerOptions) { + const events: ASTElementHandlers | void = el.events + if (!events) { + return + } + for (const name in events) { + const handler: ASTElementHandler | Array = events[name] + if (Array.isArray(handler)) { + handler.map(fn => parseHandlerParams(fn)) + } else { + parseHandlerParams(handler) + } + } +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js new file mode 100644 index 00000000..baff838a --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js @@ -0,0 +1,19 @@ +/* @flow */ + +import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers' + +function containVOnce (el: ASTElement): boolean { + for (const attr in el.attrsMap) { + if (/^v\-once$/i.test(attr)) { + return true + } + } + return false +} + +export function preTransformVOnce (el: ASTElement, options: WeexCompilerOptions) { + if (containVOnce(el)) { + getAndRemoveAttr(el, 'v-once', true) + addRawAttr(el, '[[once]]', true) + } +} diff --git a/node_modules/vue/src/platforms/weex/compiler/modules/style.js b/node_modules/vue/src/platforms/weex/compiler/modules/style.js new file mode 100644 index 00000000..7bf5027f --- /dev/null +++ b/node_modules/vue/src/platforms/weex/compiler/modules/style.js @@ -0,0 +1,86 @@ +/* @flow */ + +import { cached, camelize, isPlainObject } from 'shared/util' +import { parseText } from 'compiler/parser/text-parser' +import { + getAndRemoveAttr, + getBindingAttr, + baseWarn +} from 'compiler/helpers' + +type StaticStyleResult = { + dynamic: boolean, + styleResult: string | Object | void +}; + +const normalize = cached(camelize) + +function transformNode (el: ASTElement, options: CompilerOptions) { + const warn = options.warn || baseWarn + const staticStyle = getAndRemoveAttr(el, 'style') + const { dynamic, styleResult } = parseStaticStyle(staticStyle, options) + if (process.env.NODE_ENV !== 'production' && dynamic) { + warn( + `style="${String(staticStyle)}": ` + + 'Interpolation inside attributes has been deprecated. ' + + 'Use v-bind or the colon shorthand instead.' + ) + } + if (!dynamic && styleResult) { + // $flow-disable-line + el.staticStyle = styleResult + } + const styleBinding = getBindingAttr(el, 'style', false /* getStatic */) + if (styleBinding) { + el.styleBinding = styleBinding + } else if (dynamic) { + // $flow-disable-line + el.styleBinding = styleResult + } +} + +function genData (el: ASTElement): string { + let data = '' + if (el.staticStyle) { + data += `staticStyle:${el.staticStyle},` + } + if (el.styleBinding) { + data += `style:${el.styleBinding},` + } + return data +} + +function parseStaticStyle (staticStyle: ?string, options: CompilerOptions): StaticStyleResult { + // "width: 200px; height: 200px;" -> {width: 200, height: 200} + // "width: 200px; height: {{y}}" -> {width: 200, height: y} + let dynamic = false + let styleResult = '' + if (typeof staticStyle === 'string') { + const styleList = staticStyle.trim().split(';').map(style => { + const result = style.trim().split(':') + if (result.length !== 2) { + return + } + const key = normalize(result[0].trim()) + const value = result[1].trim() + const dynamicValue = parseText(value, options.delimiters) + if (dynamicValue) { + dynamic = true + return key + ':' + dynamicValue.expression + } + return key + ':' + JSON.stringify(value) + }).filter(result => result) + if (styleList.length) { + styleResult = '{' + styleList.join(',') + '}' + } + } else if (isPlainObject(staticStyle)) { + styleResult = JSON.stringify(staticStyle) || '' + } + return { dynamic, styleResult } +} + +export default { + staticKeys: ['staticStyle'], + transformNode, + genData +} diff --git a/node_modules/vue/src/platforms/weex/entry-compiler.js b/node_modules/vue/src/platforms/weex/entry-compiler.js new file mode 100644 index 00000000..18d79ab7 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/entry-compiler.js @@ -0,0 +1 @@ +export { compile } from 'weex/compiler/index' diff --git a/node_modules/vue/src/platforms/weex/entry-framework.js b/node_modules/vue/src/platforms/weex/entry-framework.js new file mode 100644 index 00000000..a23775d4 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/entry-framework.js @@ -0,0 +1,187 @@ +/* @flow */ + +// this will be preserved during build +// $flow-disable-line +const VueFactory = require('./factory') + +const instanceOptions: { [key: string]: WeexInstanceOption } = {} + +/** + * Create instance context. + */ +export function createInstanceContext ( + instanceId: string, + runtimeContext: WeexRuntimeContext, + data: Object = {} +): WeexInstanceContext { + const weex: Weex = runtimeContext.weex + const instance: WeexInstanceOption = instanceOptions[instanceId] = { + instanceId, + config: weex.config, + document: weex.document, + data + } + + // Each instance has a independent `Vue` module instance + const Vue = instance.Vue = createVueModuleInstance(instanceId, weex) + + // DEPRECATED + const timerAPIs = getInstanceTimer(instanceId, weex.requireModule) + + const instanceContext = Object.assign({ Vue }, timerAPIs) + Object.freeze(instanceContext) + return instanceContext +} + +/** + * Destroy an instance with id. It will make sure all memory of + * this instance released and no more leaks. + */ +export function destroyInstance (instanceId: string): void { + const instance = instanceOptions[instanceId] + if (instance && instance.app instanceof instance.Vue) { + try { + instance.app.$destroy() + instance.document.destroy() + } catch (e) {} + delete instance.document + delete instance.app + } + delete instanceOptions[instanceId] +} + +/** + * Refresh an instance with id and new top-level component data. + * It will use `Vue.set` on all keys of the new data. So it's better + * define all possible meaningful keys when instance created. + */ +export function refreshInstance ( + instanceId: string, + data: Object +): Error | void { + const instance = instanceOptions[instanceId] + if (!instance || !(instance.app instanceof instance.Vue)) { + return new Error(`refreshInstance: instance ${instanceId} not found!`) + } + if (instance.Vue && instance.Vue.set) { + for (const key in data) { + instance.Vue.set(instance.app, key, data[key]) + } + } + // Finally `refreshFinish` signal needed. + instance.document.taskCenter.send('dom', { action: 'refreshFinish' }, []) +} + +/** + * Create a fresh instance of Vue for each Weex instance. + */ +function createVueModuleInstance ( + instanceId: string, + weex: Weex +): GlobalAPI { + const exports = {} + VueFactory(exports, weex.document) + const Vue = exports.Vue + + const instance = instanceOptions[instanceId] + + // patch reserved tag detection to account for dynamically registered + // components + const weexRegex = /^weex:/i + const isReservedTag = Vue.config.isReservedTag || (() => false) + const isRuntimeComponent = Vue.config.isRuntimeComponent || (() => false) + Vue.config.isReservedTag = name => { + return (!isRuntimeComponent(name) && weex.supports(`@component/${name}`)) || + isReservedTag(name) || + weexRegex.test(name) + } + Vue.config.parsePlatformTagName = name => name.replace(weexRegex, '') + + // expose weex-specific info + Vue.prototype.$instanceId = instanceId + Vue.prototype.$document = instance.document + + // expose weex native module getter on subVue prototype so that + // vdom runtime modules can access native modules via vnode.context + Vue.prototype.$requireWeexModule = weex.requireModule + + // Hack `Vue` behavior to handle instance information and data + // before root component created. + Vue.mixin({ + beforeCreate () { + const options = this.$options + // root component (vm) + if (options.el) { + // set external data of instance + const dataOption = options.data + const internalData = (typeof dataOption === 'function' ? dataOption() : dataOption) || {} + options.data = Object.assign(internalData, instance.data) + // record instance by id + instance.app = this + } + }, + mounted () { + const options = this.$options + // root component (vm) + if (options.el && weex.document && instance.app === this) { + try { + // Send "createFinish" signal to native. + weex.document.taskCenter.send('dom', { action: 'createFinish' }, []) + } catch (e) {} + } + } + }) + + /** + * @deprecated Just instance variable `weex.config` + * Get instance config. + * @return {object} + */ + Vue.prototype.$getConfig = function () { + if (instance.app instanceof Vue) { + return instance.config + } + } + + return Vue +} + +/** + * DEPRECATED + * Generate HTML5 Timer APIs. An important point is that the callback + * will be converted into callback id when sent to native. So the + * framework can make sure no side effect of the callback happened after + * an instance destroyed. + */ +function getInstanceTimer ( + instanceId: string, + moduleGetter: Function +): Object { + const instance = instanceOptions[instanceId] + const timer = moduleGetter('timer') + const timerAPIs = { + setTimeout: (...args) => { + const handler = function () { + args[0](...args.slice(2)) + } + + timer.setTimeout(handler, args[1]) + return instance.document.taskCenter.callbackManager.lastCallbackId.toString() + }, + setInterval: (...args) => { + const handler = function () { + args[0](...args.slice(2)) + } + + timer.setInterval(handler, args[1]) + return instance.document.taskCenter.callbackManager.lastCallbackId.toString() + }, + clearTimeout: (n) => { + timer.clearTimeout(n) + }, + clearInterval: (n) => { + timer.clearInterval(n) + } + } + return timerAPIs +} diff --git a/node_modules/vue/src/platforms/weex/entry-runtime-factory.js b/node_modules/vue/src/platforms/weex/entry-runtime-factory.js new file mode 100644 index 00000000..166ddf2d --- /dev/null +++ b/node_modules/vue/src/platforms/weex/entry-runtime-factory.js @@ -0,0 +1,6 @@ +// this entry is built and wrapped with a factory function +// used to generate a fresh copy of Vue for every Weex instance. + +import Vue from './runtime/index' + +exports.Vue = Vue diff --git a/node_modules/vue/src/platforms/weex/runtime/components/index.js b/node_modules/vue/src/platforms/weex/runtime/components/index.js new file mode 100644 index 00000000..449db1ad --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/components/index.js @@ -0,0 +1,9 @@ +import Richtext from './richtext' +import Transition from './transition' +import TransitionGroup from './transition-group' + +export default { + Richtext, + Transition, + TransitionGroup +} diff --git a/node_modules/vue/src/platforms/weex/runtime/components/richtext.js b/node_modules/vue/src/platforms/weex/runtime/components/richtext.js new file mode 100644 index 00000000..a9164c7a --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/components/richtext.js @@ -0,0 +1,82 @@ +/* @flow */ + +function getVNodeType (vnode: VNode): string { + if (!vnode.tag) { + return '' + } + return vnode.tag.replace(/vue\-component\-(\d+\-)?/, '') +} + +function isSimpleSpan (vnode: VNode): boolean { + return vnode.children && + vnode.children.length === 1 && + !vnode.children[0].tag +} + +function parseStyle (vnode: VNode): Object | void { + if (!vnode || !vnode.data) { + return + } + const { staticStyle, staticClass } = vnode.data + if (vnode.data.style || vnode.data.class || staticStyle || staticClass) { + const styles = Object.assign({}, staticStyle, vnode.data.style) + const cssMap = vnode.context.$options.style || {} + const classList = [].concat(staticClass, vnode.data.class) + classList.forEach(name => { + if (name && cssMap[name]) { + Object.assign(styles, cssMap[name]) + } + }) + return styles + } +} + +function convertVNodeChildren (children: Array): Array | void { + if (!children.length) { + return + } + + return children.map(vnode => { + const type: string = getVNodeType(vnode) + const props: Object = { type } + + // convert raw text node + if (!type) { + props.type = 'span' + props.attr = { + value: (vnode.text || '').trim() + } + } else { + props.style = parseStyle(vnode) + if (vnode.data) { + props.attr = vnode.data.attrs + if (vnode.data.on) { + props.events = vnode.data.on + } + } + if (type === 'span' && isSimpleSpan(vnode)) { + props.attr = props.attr || {} + props.attr.value = vnode.children[0].text.trim() + return props + } + } + + if (vnode.children && vnode.children.length) { + props.children = convertVNodeChildren(vnode.children) + } + + return props + }) +} + +export default { + name: 'richtext', + render (h: Function) { + return h('weex:richtext', { + on: this._events, + attrs: { + value: convertVNodeChildren(this.$options._renderChildren || []) + } + }) + } +} diff --git a/node_modules/vue/src/platforms/weex/runtime/components/transition-group.js b/node_modules/vue/src/platforms/weex/runtime/components/transition-group.js new file mode 100644 index 00000000..4a65965f --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/components/transition-group.js @@ -0,0 +1,148 @@ +import { warn, extend } from 'core/util/index' +import { transitionProps, extractTransitionData } from './transition' + +const props = extend({ + tag: String, + moveClass: String +}, transitionProps) + +delete props.mode + +export default { + props, + + created () { + const dom = this.$requireWeexModule('dom') + this.getPosition = el => new Promise((resolve, reject) => { + dom.getComponentRect(el.ref, res => { + if (!res.result) { + reject(new Error(`failed to get rect for element: ${el.tag}`)) + } else { + resolve(res.size) + } + }) + }) + + const animation = this.$requireWeexModule('animation') + this.animate = (el, options) => new Promise(resolve => { + animation.transition(el.ref, options, resolve) + }) + }, + + render (h) { + const tag = this.tag || this.$vnode.data.tag || 'span' + const map = Object.create(null) + const prevChildren = this.prevChildren = this.children + const rawChildren = this.$slots.default || [] + const children = this.children = [] + const transitionData = extractTransitionData(this) + + for (let i = 0; i < rawChildren.length; i++) { + const c = rawChildren[i] + if (c.tag) { + if (c.key != null && String(c.key).indexOf('__vlist') !== 0) { + children.push(c) + map[c.key] = c + ;(c.data || (c.data = {})).transition = transitionData + } else if (process.env.NODE_ENV !== 'production') { + const opts = c.componentOptions + const name = opts + ? (opts.Ctor.options.name || opts.tag) + : c.tag + warn(` children must be keyed: <${name}>`) + } + } + } + + if (prevChildren) { + const kept = [] + const removed = [] + prevChildren.forEach(c => { + c.data.transition = transitionData + + // TODO: record before patch positions + + if (map[c.key]) { + kept.push(c) + } else { + removed.push(c) + } + }) + this.kept = h(tag, null, kept) + this.removed = removed + } + + return h(tag, null, children) + }, + + beforeUpdate () { + // force removing pass + this.__patch__( + this._vnode, + this.kept, + false, // hydrating + true // removeOnly (!important, avoids unnecessary moves) + ) + this._vnode = this.kept + }, + + updated () { + const children = this.prevChildren + const moveClass = this.moveClass || ((this.name || 'v') + '-move') + const moveData = children.length && this.getMoveData(children[0].context, moveClass) + if (!moveData) { + return + } + + // TODO: finish implementing move animations once + // we have access to sync getComponentRect() + + // children.forEach(callPendingCbs) + + // Promise.all(children.map(c => { + // const oldPos = c.data.pos + // const newPos = c.data.newPos + // const dx = oldPos.left - newPos.left + // const dy = oldPos.top - newPos.top + // if (dx || dy) { + // c.data.moved = true + // return this.animate(c.elm, { + // styles: { + // transform: `translate(${dx}px,${dy}px)` + // } + // }) + // } + // })).then(() => { + // children.forEach(c => { + // if (c.data.moved) { + // this.animate(c.elm, { + // styles: { + // transform: '' + // }, + // duration: moveData.duration || 0, + // delay: moveData.delay || 0, + // timingFunction: moveData.timingFunction || 'linear' + // }) + // } + // }) + // }) + }, + + methods: { + getMoveData (context, moveClass) { + const stylesheet = context.$options.style || {} + return stylesheet['@TRANSITION'] && stylesheet['@TRANSITION'][moveClass] + } + } +} + +// function callPendingCbs (c) { +// /* istanbul ignore if */ +// if (c.elm._moveCb) { +// c.elm._moveCb() +// } +// /* istanbul ignore if */ +// if (c.elm._enterCb) { +// c.elm._enterCb() +// } +// } diff --git a/node_modules/vue/src/platforms/weex/runtime/components/transition.js b/node_modules/vue/src/platforms/weex/runtime/components/transition.js new file mode 100644 index 00000000..20ba632d --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/components/transition.js @@ -0,0 +1,9 @@ +// reuse same transition component logic from web +export { + transitionProps, + extractTransitionData +} from 'web/runtime/components/transition' + +import Transition from 'web/runtime/components/transition' + +export default Transition diff --git a/node_modules/vue/src/platforms/weex/runtime/directives/index.js b/node_modules/vue/src/platforms/weex/runtime/directives/index.js new file mode 100755 index 00000000..efba7fa6 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/directives/index.js @@ -0,0 +1,2 @@ +export default { +} diff --git a/node_modules/vue/src/platforms/weex/runtime/index.js b/node_modules/vue/src/platforms/weex/runtime/index.js new file mode 100755 index 00000000..b8e09305 --- /dev/null +++ b/node_modules/vue/src/platforms/weex/runtime/index.js @@ -0,0 +1,42 @@ +/* @flow */ + +import Vue from 'core/index' +import { patch } from 'weex/runtime/patch' +import { mountComponent } from 'core/instance/lifecycle' +import platformDirectives from 'weex/runtime/directives/index' +import platformComponents from 'weex/runtime/components/index' + +import { + query, + mustUseProp, + isReservedTag, + isRuntimeComponent, + isUnknownElement +} from 'weex/util/element' + +// install platform specific utils +Vue.config.mustUseProp = mustUseProp +Vue.config.isReservedTag = isReservedTag +Vue.config.isRuntimeComponent = isRuntimeComponent +Vue.config.isUnknownElement = isUnknownElement + +// install platform runtime directives and components +Vue.options.directives = platformDirectives +Vue.options.components = platformComponents + +// install platform patch function +Vue.prototype.__patch__ = patch + +// wrap mount +Vue.prototype.$mount = function ( + el?: any, + hydrating?: boolean +): Component { + return mountComponent( + this, + el && query(el, this.$document), + hydrating + ) +} + +export default Vue 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, classList: Array, ctx: Component): Object { + // style is a weex-only injected object + // compiled from