vue 2.5.9 → 2.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +39 -31
  2. package/dist/vue.common.js +245 -153
  3. package/dist/vue.esm.js +245 -153
  4. package/dist/vue.js +240 -152
  5. package/dist/vue.min.js +2 -2
  6. package/dist/vue.runtime.common.js +155 -92
  7. package/dist/vue.runtime.esm.js +155 -92
  8. package/dist/vue.runtime.js +150 -91
  9. package/dist/vue.runtime.min.js +2 -2
  10. package/package.json +12 -12
  11. package/src/compiler/codegen/events.js +30 -3
  12. package/src/compiler/codegen/index.js +20 -9
  13. package/src/compiler/create-compiler.js +1 -1
  14. package/src/compiler/helpers.js +12 -1
  15. package/src/compiler/index.js +3 -1
  16. package/src/compiler/parser/index.js +39 -30
  17. package/src/compiler/parser/text-parser.js +17 -5
  18. package/src/compiler/to-function.js +1 -3
  19. package/src/core/config.js +2 -0
  20. package/src/core/global-api/assets.js +3 -9
  21. package/src/core/global-api/extend.js +3 -9
  22. package/src/core/instance/init.js +10 -6
  23. package/src/core/instance/inject.js +5 -5
  24. package/src/core/instance/lifecycle.js +1 -1
  25. package/src/core/instance/render-helpers/render-static.js +7 -13
  26. package/src/core/instance/render-helpers/resolve-slots.js +4 -2
  27. package/src/core/instance/state.js +2 -1
  28. package/src/core/observer/array.js +1 -2
  29. package/src/core/util/options.js +23 -12
  30. package/src/core/util/props.js +5 -1
  31. package/src/core/vdom/create-component.js +15 -6
  32. package/src/core/vdom/create-element.js +7 -5
  33. package/src/core/vdom/helpers/update-listeners.js +12 -5
  34. package/src/core/vdom/modules/directives.js +3 -0
  35. package/src/core/vdom/patch.js +26 -8
  36. package/src/platforms/web/compiler/directives/model.js +11 -11
  37. package/src/platforms/web/compiler/modules/class.js +2 -2
  38. package/src/platforms/web/compiler/modules/model.js +1 -5
  39. package/src/platforms/web/compiler/modules/style.js +2 -2
  40. package/src/platforms/web/runtime/modules/dom-props.js +15 -9
  41. package/src/platforms/web/util/class.js +3 -3
  42. package/src/platforms/web/util/style.js +5 -2
  43. package/src/platforms/weex/compiler/index.js +26 -4
  44. package/src/platforms/weex/compiler/modules/append.js +7 -1
  45. package/src/platforms/weex/compiler/modules/class.js +1 -1
  46. package/src/platforms/weex/compiler/modules/index.js +2 -0
  47. package/src/platforms/weex/compiler/modules/recycle-list/component-root.js +15 -0
  48. package/src/platforms/weex/compiler/modules/recycle-list/component.js +16 -0
  49. package/src/platforms/weex/compiler/modules/recycle-list/index.js +56 -0
  50. package/src/platforms/weex/compiler/modules/recycle-list/text.js +23 -0
  51. package/src/platforms/weex/compiler/modules/recycle-list/v-bind.js +22 -0
  52. package/src/platforms/weex/compiler/modules/recycle-list/v-for.js +33 -0
  53. package/src/platforms/weex/compiler/modules/recycle-list/v-if.js +47 -0
  54. package/src/platforms/weex/compiler/modules/recycle-list/v-on.js +25 -0
  55. package/src/platforms/weex/compiler/modules/style.js +1 -1
  56. package/src/platforms/weex/entry-framework.js +10 -51
  57. package/src/platforms/weex/runtime/index.js +1 -1
  58. package/src/platforms/weex/runtime/modules/events.js +4 -2
  59. package/src/platforms/weex/runtime/recycle-list/render-component-template.js +34 -0
  60. package/src/platforms/weex/runtime/recycle-list/virtual-component.js +136 -0
  61. package/src/platforms/weex/util/element.js +52 -0
  62. package/src/platforms/weex/util/index.js +35 -37
  63. package/src/server/create-renderer.js +6 -2
  64. package/src/server/optimizing-compiler/modules.js +1 -1
  65. package/src/server/render-context.js +1 -1
  66. package/src/server/render.js +4 -7
  67. package/src/server/template-renderer/index.js +2 -3
  68. package/src/sfc/parser.js +4 -4
  69. package/src/shared/util.js +2 -0
  70. package/types/vue.d.ts +13 -11
@@ -263,11 +263,14 @@ export function createPatchFunction (backend) {
263
263
 
264
264
  function createChildren (vnode, children, insertedVnodeQueue) {
265
265
  if (Array.isArray(children)) {
266
+ if (process.env.NODE_ENV !== 'production') {
267
+ checkDuplicateKeys(children)
268
+ }
266
269
  for (let i = 0; i < children.length; ++i) {
267
270
  createElm(children[i], insertedVnodeQueue, vnode.elm, null, true)
268
271
  }
269
272
  } else if (isPrimitive(vnode.text)) {
270
- nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(vnode.text))
273
+ nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)))
271
274
  }
272
275
  }
273
276
 
@@ -394,6 +397,10 @@ export function createPatchFunction (backend) {
394
397
  // during leaving transitions
395
398
  const canMove = !removeOnly
396
399
 
400
+ if (process.env.NODE_ENV !== 'production') {
401
+ checkDuplicateKeys(newCh)
402
+ }
403
+
397
404
  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
398
405
  if (isUndef(oldStartVnode)) {
399
406
  oldStartVnode = oldCh[++oldStartIdx] // Vnode has been moved left
@@ -426,13 +433,6 @@ export function createPatchFunction (backend) {
426
433
  createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm)
427
434
  } else {
428
435
  vnodeToMove = oldCh[idxInOld]
429
- /* istanbul ignore if */
430
- if (process.env.NODE_ENV !== 'production' && !vnodeToMove) {
431
- warn(
432
- 'It seems there are duplicate keys that is causing an update error. ' +
433
- 'Make sure each v-for item has a unique key.'
434
- )
435
- }
436
436
  if (sameVnode(vnodeToMove, newStartVnode)) {
437
437
  patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue)
438
438
  oldCh[idxInOld] = undefined
@@ -453,6 +453,24 @@ export function createPatchFunction (backend) {
453
453
  }
454
454
  }
455
455
 
456
+ function checkDuplicateKeys (children) {
457
+ const seenKeys = {}
458
+ for (let i = 0; i < children.length; i++) {
459
+ const vnode = children[i]
460
+ const key = vnode.key
461
+ if (isDef(key)) {
462
+ if (seenKeys[key]) {
463
+ warn(
464
+ `Duplicate keys detected: '${key}'. This may cause an update error.`,
465
+ vnode.context
466
+ )
467
+ } else {
468
+ seenKeys[key] = true
469
+ }
470
+ }
471
+ }
472
+ }
473
+
456
474
  function findIdxInOld (node, oldCh, start, end) {
457
475
  for (let i = start; i < end; i++) {
458
476
  const c = oldCh[i]
@@ -73,11 +73,11 @@ function genCheckboxModel (
73
73
  const falseValueBinding = getBindingAttr(el, 'false-value') || 'false'
74
74
  addProp(el, 'checked',
75
75
  `Array.isArray(${value})` +
76
- `?_i(${value},${valueBinding})>-1` + (
77
- trueValueBinding === 'true'
78
- ? `:(${value})`
79
- : `:_q(${value},${trueValueBinding})`
80
- )
76
+ `?_i(${value},${valueBinding})>-1` + (
77
+ trueValueBinding === 'true'
78
+ ? `:(${value})`
79
+ : `:_q(${value},${trueValueBinding})`
80
+ )
81
81
  )
82
82
  addHandler(el, 'change',
83
83
  `var $$a=${value},` +
@@ -94,9 +94,9 @@ function genCheckboxModel (
94
94
  }
95
95
 
96
96
  function genRadioModel (
97
- el: ASTElement,
98
- value: string,
99
- modifiers: ?ASTModifiers
97
+ el: ASTElement,
98
+ value: string,
99
+ modifiers: ?ASTModifiers
100
100
  ) {
101
101
  const number = modifiers && modifiers.number
102
102
  let valueBinding = getBindingAttr(el, 'value') || 'null'
@@ -106,9 +106,9 @@ function genRadioModel (
106
106
  }
107
107
 
108
108
  function genSelect (
109
- el: ASTElement,
110
- value: string,
111
- modifiers: ?ASTModifiers
109
+ el: ASTElement,
110
+ value: string,
111
+ modifiers: ?ASTModifiers
112
112
  ) {
113
113
  const number = modifiers && modifiers.number
114
114
  const selectedVal = `Array.prototype.filter` +
@@ -11,8 +11,8 @@ function transformNode (el: ASTElement, options: CompilerOptions) {
11
11
  const warn = options.warn || baseWarn
12
12
  const staticClass = getAndRemoveAttr(el, 'class')
13
13
  if (process.env.NODE_ENV !== 'production' && staticClass) {
14
- const expression = parseText(staticClass, options.delimiters)
15
- if (expression) {
14
+ const res = parseText(staticClass, options.delimiters)
15
+ if (res) {
16
16
  warn(
17
17
  `class="${staticClass}": ` +
18
18
  'Interpolation inside attributes has been removed. ' +
@@ -11,6 +11,7 @@
11
11
  */
12
12
 
13
13
  import {
14
+ addRawAttr,
14
15
  getBindingAttr,
15
16
  getAndRemoveAttr
16
17
  } from 'compiler/helpers'
@@ -77,11 +78,6 @@ function cloneASTElement (el) {
77
78
  return createASTElement(el.tag, el.attrsList.slice(), el.parent)
78
79
  }
79
80
 
80
- function addRawAttr (el, name, value) {
81
- el.attrsMap[name] = value
82
- el.attrsList.push({ name, value })
83
- }
84
-
85
81
  export default {
86
82
  preTransformNode
87
83
  }
@@ -14,8 +14,8 @@ function transformNode (el: ASTElement, options: CompilerOptions) {
14
14
  if (staticStyle) {
15
15
  /* istanbul ignore if */
16
16
  if (process.env.NODE_ENV !== 'production') {
17
- const expression = parseText(staticStyle, options.delimiters)
18
- if (expression) {
17
+ const res = parseText(staticStyle, options.delimiters)
18
+ if (res) {
19
19
  warn(
20
20
  `style="${staticStyle}": ` +
21
21
  'Interpolation inside attributes has been removed. ' +
@@ -56,12 +56,12 @@ type acceptValueElm = HTMLInputElement | HTMLSelectElement | HTMLOptionElement;
56
56
  function shouldUpdateValue (elm: acceptValueElm, checkVal: string): boolean {
57
57
  return (!elm.composing && (
58
58
  elm.tagName === 'OPTION' ||
59
- isDirty(elm, checkVal) ||
60
- isInputChanged(elm, checkVal)
59
+ isNotInFocusAndDirty(elm, checkVal) ||
60
+ isDirtyWithModifiers(elm, checkVal)
61
61
  ))
62
62
  }
63
63
 
64
- function isDirty (elm: acceptValueElm, checkVal: string): boolean {
64
+ function isNotInFocusAndDirty (elm: acceptValueElm, checkVal: string): boolean {
65
65
  // return true when textbox (.number and .trim) loses focus and its value is
66
66
  // not equal to the updated value
67
67
  let notInFocus = true
@@ -71,14 +71,20 @@ function isDirty (elm: acceptValueElm, checkVal: string): boolean {
71
71
  return notInFocus && elm.value !== checkVal
72
72
  }
73
73
 
74
- function isInputChanged (elm: any, newVal: string): boolean {
74
+ function isDirtyWithModifiers (elm: any, newVal: string): boolean {
75
75
  const value = elm.value
76
76
  const modifiers = elm._vModifiers // injected by v-model runtime
77
- if (isDef(modifiers) && modifiers.number) {
78
- return toNumber(value) !== toNumber(newVal)
79
- }
80
- if (isDef(modifiers) && modifiers.trim) {
81
- return value.trim() !== newVal.trim()
77
+ if (isDef(modifiers)) {
78
+ if (modifiers.lazy) {
79
+ // inputs with lazy should only be updated when not in focus
80
+ return false
81
+ }
82
+ if (modifiers.number) {
83
+ return toNumber(value) !== toNumber(newVal)
84
+ }
85
+ if (modifiers.trim) {
86
+ return value.trim() !== newVal.trim()
87
+ }
82
88
  }
83
89
  return value !== newVal
84
90
  }
@@ -2,18 +2,18 @@
2
2
 
3
3
  import { isDef, isObject } from 'shared/util'
4
4
 
5
- export function genClassForVnode (vnode: VNode): string {
5
+ export function genClassForVnode (vnode: VNodeWithData): string {
6
6
  let data = vnode.data
7
7
  let parentNode = vnode
8
8
  let childNode = vnode
9
9
  while (isDef(childNode.componentInstance)) {
10
10
  childNode = childNode.componentInstance._vnode
11
- if (childNode.data) {
11
+ if (childNode && childNode.data) {
12
12
  data = mergeClassData(childNode.data, data)
13
13
  }
14
14
  }
15
15
  while (isDef(parentNode = parentNode.parent)) {
16
- if (parentNode.data) {
16
+ if (parentNode && parentNode.data) {
17
17
  data = mergeClassData(data, parentNode.data)
18
18
  }
19
19
  }
@@ -40,7 +40,7 @@ export function normalizeStyleBinding (bindingStyle: any): ?Object {
40
40
  * parent component style should be after child's
41
41
  * so that parent component's style could override it
42
42
  */
43
- export function getStyle (vnode: VNode, checkChild: boolean): Object {
43
+ export function getStyle (vnode: VNodeWithData, checkChild: boolean): Object {
44
44
  const res = {}
45
45
  let styleData
46
46
 
@@ -48,7 +48,10 @@ export function getStyle (vnode: VNode, checkChild: boolean): Object {
48
48
  let childNode = vnode
49
49
  while (childNode.componentInstance) {
50
50
  childNode = childNode.componentInstance._vnode
51
- if (childNode.data && (styleData = normalizeStyleData(childNode.data))) {
51
+ if (
52
+ childNode && childNode.data &&
53
+ (styleData = normalizeStyleData(childNode.data))
54
+ ) {
52
55
  extend(res, styleData)
53
56
  }
54
57
  }
@@ -12,9 +12,9 @@ import {
12
12
  isReservedTag,
13
13
  canBeLeftOpenTag,
14
14
  getTagNamespace
15
- } from '../util/index'
15
+ } from '../util/element'
16
16
 
17
- export const baseOptions: CompilerOptions = {
17
+ export const baseOptions: WeexCompilerOptions = {
18
18
  modules,
19
19
  directives,
20
20
  isUnaryTag,
@@ -23,8 +23,30 @@ export const baseOptions: CompilerOptions = {
23
23
  isReservedTag,
24
24
  getTagNamespace,
25
25
  preserveWhitespace: false,
26
+ recyclable: false,
26
27
  staticKeys: genStaticKeys(modules)
27
28
  }
28
29
 
29
- const { compile, compileToFunctions } = createCompiler(baseOptions)
30
- export { compile, compileToFunctions }
30
+ const compiler = createCompiler(baseOptions)
31
+
32
+ export function compile (
33
+ template: string,
34
+ options?: WeexCompilerOptions
35
+ ): WeexCompiledResult {
36
+ let generateAltRender = false
37
+ if (options && options.recyclable === true) {
38
+ generateAltRender = true
39
+ options.recyclable = false
40
+ }
41
+ const result = compiler.compile(template, options)
42
+
43
+ // generate @render function for <recycle-list>
44
+ if (options && generateAltRender) {
45
+ options.recyclable = true
46
+ // disable static optimizations
47
+ options.optimize = false
48
+ const { render } = compiler.compile(template, options)
49
+ result['@render'] = render
50
+ }
51
+ return result
52
+ }
@@ -1,7 +1,13 @@
1
1
  /* @flow */
2
2
 
3
+ import { makeMap } from 'shared/util'
4
+
5
+ // The "unitary tag" means that the tag node and its children
6
+ // must be sent to the native together.
7
+ const isUnitaryTag = makeMap('cell,header,cell-slot,recycle-list', true)
8
+
3
9
  function preTransformNode (el: ASTElement, options: CompilerOptions) {
4
- if (el.tag === 'cell' && !el.attrsList.some(item => item.name === 'append')) {
10
+ if (isUnitaryTag(el.tag) && !el.attrsList.some(item => item.name === 'append')) {
5
11
  el.attrsMap.append = 'tree'
6
12
  el.attrsList.push({ name: 'append', value: 'tree' })
7
13
  }
@@ -55,7 +55,7 @@ function parseStaticClass (staticClass: ?string, options: CompilerOptions): Stat
55
55
  const result = parseText(name, options.delimiters)
56
56
  if (result) {
57
57
  dynamic = true
58
- return result
58
+ return result.expression
59
59
  }
60
60
  return JSON.stringify(name)
61
61
  })
@@ -2,8 +2,10 @@ import klass from './class'
2
2
  import style from './style'
3
3
  import props from './props'
4
4
  import append from './append'
5
+ import recycleList from './recycle-list/index'
5
6
 
6
7
  export default [
8
+ recycleList,
7
9
  klass,
8
10
  style,
9
11
  props,
@@ -0,0 +1,15 @@
1
+ /* @flow */
2
+
3
+ import { addAttr } from 'compiler/helpers'
4
+
5
+ // mark component root nodes as
6
+ export function postTransformComponentRoot (
7
+ el: ASTElement,
8
+ options: WeexCompilerOptions
9
+ ) {
10
+ if (!el.parent) {
11
+ // component root
12
+ addAttr(el, '@isComponentRoot', 'true')
13
+ addAttr(el, '@componentProps', '$props || {}')
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ /* @flow */
2
+
3
+ import { addAttr } from 'compiler/helpers'
4
+ import { RECYCLE_LIST_MARKER } from 'weex/util/index'
5
+
6
+ // mark components as inside recycle-list so that we know we need to invoke
7
+ // their special @render function instead of render in create-component.js
8
+ export function postTransformComponent (
9
+ el: ASTElement,
10
+ options: WeexCompilerOptions
11
+ ) {
12
+ // $flow-disable-line (we know isReservedTag is there)
13
+ if (!options.isReservedTag(el.tag) && el.tag !== 'cell-slot') {
14
+ addAttr(el, RECYCLE_LIST_MARKER, 'true')
15
+ }
16
+ }
@@ -0,0 +1,56 @@
1
+ /* @flow */
2
+
3
+ import { postTransformComponent } from './component'
4
+ import { postTransformComponentRoot } from './component-root'
5
+ import { postTransformText } from './text'
6
+ import { preTransformVBind } from './v-bind'
7
+ import { preTransformVIf } from './v-if'
8
+ import { preTransformVFor } from './v-for'
9
+ import { postTransformVOn } from './v-on'
10
+
11
+ let currentRecycleList = null
12
+
13
+ function shouldCompile (el: ASTElement, options: WeexCompilerOptions) {
14
+ return options.recyclable ||
15
+ (currentRecycleList && el !== currentRecycleList)
16
+ }
17
+
18
+ function preTransformNode (el: ASTElement, options: WeexCompilerOptions) {
19
+ if (el.tag === 'recycle-list') {
20
+ currentRecycleList = el
21
+ }
22
+ if (shouldCompile(el, options)) {
23
+ preTransformVBind(el, options)
24
+ preTransformVIf(el, options) // also v-else-if and v-else
25
+ preTransformVFor(el, options)
26
+ }
27
+ }
28
+
29
+ function transformNode (el: ASTElement, options: WeexCompilerOptions) {
30
+ if (shouldCompile(el, options)) {
31
+ // do nothing yet
32
+ }
33
+ }
34
+
35
+ function postTransformNode (el: ASTElement, options: WeexCompilerOptions) {
36
+ if (shouldCompile(el, options)) {
37
+ // mark child component in parent template
38
+ postTransformComponent(el, options)
39
+ // mark root in child component template
40
+ postTransformComponentRoot(el, options)
41
+ // <text>: transform children text into value attr
42
+ if (el.tag === 'text') {
43
+ postTransformText(el, options)
44
+ }
45
+ postTransformVOn(el, options)
46
+ }
47
+ if (el === currentRecycleList) {
48
+ currentRecycleList = null
49
+ }
50
+ }
51
+
52
+ export default {
53
+ preTransformNode,
54
+ transformNode,
55
+ postTransformNode
56
+ }
@@ -0,0 +1,23 @@
1
+ /* @flow */
2
+
3
+ import { addAttr } from 'compiler/helpers'
4
+
5
+ function genText (node: ASTNode) {
6
+ const value = node.type === 3
7
+ ? node.text
8
+ : node.type === 2
9
+ ? node.tokens.length === 1
10
+ ? node.tokens[0]
11
+ : node.tokens
12
+ : ''
13
+ return JSON.stringify(value)
14
+ }
15
+
16
+ export function postTransformText (el: ASTElement, options: WeexCompilerOptions) {
17
+ // weex <text> can only contain text, so the parser
18
+ // always generates a single child.
19
+ if (el.children.length) {
20
+ addAttr(el, 'value', genText(el.children[0]))
21
+ el.children = []
22
+ }
23
+ }
@@ -0,0 +1,22 @@
1
+ /* @flow */
2
+
3
+ import { camelize } from 'shared/util'
4
+ import { bindRE } from 'compiler/parser/index'
5
+ import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
6
+
7
+ function parseAttrName (name: string): string {
8
+ return camelize(name.replace(bindRE, ''))
9
+ }
10
+
11
+ export function preTransformVBind (el: ASTElement, options: WeexCompilerOptions) {
12
+ for (const attr in el.attrsMap) {
13
+ if (bindRE.test(attr)) {
14
+ const name: string = parseAttrName(attr)
15
+ const value = {
16
+ '@binding': getAndRemoveAttr(el, attr)
17
+ }
18
+ delete el.attrsMap[attr]
19
+ addRawAttr(el, name, value)
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,33 @@
1
+ /* @flow */
2
+
3
+ import { parseFor } from 'compiler/parser/index'
4
+ import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
5
+
6
+ export function preTransformVFor (el: ASTElement, options: WeexCompilerOptions) {
7
+ const exp = getAndRemoveAttr(el, 'v-for')
8
+ if (!exp) {
9
+ return
10
+ }
11
+
12
+ const res = parseFor(exp)
13
+ if (!res) {
14
+ if (process.env.NODE_ENV !== 'production' && options.warn) {
15
+ options.warn(`Invalid v-for expression: ${exp}`)
16
+ }
17
+ return
18
+ }
19
+
20
+ const desc: Object = {
21
+ '@expression': res.for,
22
+ '@alias': res.alias
23
+ }
24
+ if (res.iterator2) {
25
+ desc['@key'] = res.iterator1
26
+ desc['@index'] = res.iterator2
27
+ } else {
28
+ desc['@index'] = res.iterator1
29
+ }
30
+
31
+ delete el.attrsMap['v-for']
32
+ addRawAttr(el, '[[repeat]]', desc)
33
+ }
@@ -0,0 +1,47 @@
1
+ /* @flow */
2
+
3
+ import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
4
+
5
+ function hasConditionDirective (el: ASTElement): boolean {
6
+ for (const attr in el.attrsMap) {
7
+ if (/^v\-if|v\-else|v\-else\-if$/.test(attr)) {
8
+ return true
9
+ }
10
+ }
11
+ return false
12
+ }
13
+
14
+ function getPrevMatch (el: ASTElement): any {
15
+ if (el.parent && el.parent.children) {
16
+ const prev: Object = el.parent.children[el.parent.children.length - 1]
17
+ return prev.attrsMap['[[match]]']
18
+ }
19
+ }
20
+
21
+ export function preTransformVIf (el: ASTElement, options: WeexCompilerOptions) {
22
+ if (hasConditionDirective(el)) {
23
+ let exp
24
+ const ifExp = getAndRemoveAttr(el, 'v-if', true /* remove from attrsMap */)
25
+ const elseifExp = getAndRemoveAttr(el, 'v-else-if', true)
26
+ // don't need the value, but remove it to avoid being generated as a
27
+ // custom directive
28
+ getAndRemoveAttr(el, 'v-else', true)
29
+ if (ifExp) {
30
+ exp = ifExp
31
+ } else {
32
+ const prevMatch = getPrevMatch(el)
33
+ if (prevMatch) {
34
+ exp = elseifExp
35
+ ? `!(${prevMatch}) && (${elseifExp})` // v-else-if
36
+ : `!(${prevMatch})` // v-else
37
+ } else if (process.env.NODE_ENV !== 'production' && options.warn) {
38
+ options.warn(
39
+ `v-${elseifExp ? ('else-if="' + elseifExp + '"') : 'else'} ` +
40
+ `used on element <${el.tag}> without corresponding v-if.`
41
+ )
42
+ return
43
+ }
44
+ }
45
+ addRawAttr(el, '[[match]]', exp)
46
+ }
47
+ }
@@ -0,0 +1,25 @@
1
+ /* @flow */
2
+
3
+ const inlineStatementRE = /^\s*([A-Za-z_$0-9\['\."\]]+)*\s*\(\s*(([A-Za-z_$0-9\['\."\]]+)?(\s*,\s*([A-Za-z_$0-9\['\."\]]+))*)\s*\)$/
4
+
5
+ function parseHandlerParams (handler: ASTElementHandler) {
6
+ const res = inlineStatementRE.exec(handler.value)
7
+ if (res && res[2]) {
8
+ handler.params = res[2].split(/\s*,\s*/)
9
+ }
10
+ }
11
+
12
+ export function postTransformVOn (el: ASTElement, options: WeexCompilerOptions) {
13
+ const events: ASTElementHandlers | void = el.events
14
+ if (!events) {
15
+ return
16
+ }
17
+ for (const name in events) {
18
+ const handler: ASTElementHandler | Array<ASTElementHandler> = events[name]
19
+ if (Array.isArray(handler)) {
20
+ handler.map(fn => parseHandlerParams(fn))
21
+ } else {
22
+ parseHandlerParams(handler)
23
+ }
24
+ }
25
+ }
@@ -64,7 +64,7 @@ function parseStaticStyle (staticStyle: ?string, options: CompilerOptions): Stat
64
64
  const dynamicValue = parseText(value, options.delimiters)
65
65
  if (dynamicValue) {
66
66
  dynamic = true
67
- return key + ':' + dynamicValue
67
+ return key + ':' + dynamicValue.expression
68
68
  }
69
69
  return key + ':' + JSON.stringify(value)
70
70
  }).filter(result => result)
@@ -61,12 +61,8 @@ export function createInstance (
61
61
  }, timerAPIs, env.services)
62
62
 
63
63
  appCode = `(function(global){ \n${appCode}\n })(Object.create(this))`
64
-
65
64
  callFunction(instanceVars, appCode)
66
65
 
67
- // Send `createFinish` signal to native.
68
- document.taskCenter.send('dom', { action: 'createFinish' }, [])
69
-
70
66
  return instance
71
67
  }
72
68
 
@@ -117,53 +113,6 @@ export function getRoot (instanceId) {
117
113
  return instance.app.$el.toJSON()
118
114
  }
119
115
 
120
- const jsHandlers = {
121
- fireEvent: (id, ...args) => {
122
- return fireEvent(instances[id], ...args)
123
- },
124
- callback: (id, ...args) => {
125
- return callback(instances[id], ...args)
126
- }
127
- }
128
-
129
- function fireEvent (instance, nodeId, type, e, domChanges) {
130
- const el = instance.document.getRef(nodeId)
131
- if (el) {
132
- return instance.document.fireEvent(el, type, e, domChanges)
133
- }
134
- return new Error(`invalid element reference "${nodeId}"`)
135
- }
136
-
137
- function callback (instance, callbackId, data, ifKeepAlive) {
138
- const result = instance.document.taskCenter.callback(callbackId, data, ifKeepAlive)
139
- instance.document.taskCenter.send('dom', { action: 'updateFinish' }, [])
140
- return result
141
- }
142
-
143
- /**
144
- * Accept calls from native (event or callback).
145
- *
146
- * @param {string} id
147
- * @param {array} tasks list with `method` and `args`
148
- */
149
- export function receiveTasks (id, tasks) {
150
- const instance = instances[id]
151
- if (instance && Array.isArray(tasks)) {
152
- const results = []
153
- tasks.forEach((task) => {
154
- const handler = jsHandlers[task.method]
155
- const args = [...task.args]
156
- /* istanbul ignore else */
157
- if (typeof handler === 'function') {
158
- args.unshift(id)
159
- results.push(handler(...args))
160
- }
161
- })
162
- return results
163
- }
164
- return new Error(`invalid instance id "${id}" or tasks`)
165
- }
166
-
167
116
  /**
168
117
  * Create a fresh instance of Vue for each Weex instance.
169
118
  */
@@ -208,6 +157,16 @@ function createVueModuleInstance (instanceId, weex) {
208
157
  // record instance by id
209
158
  instance.app = this
210
159
  }
160
+ },
161
+ mounted () {
162
+ const options = this.$options
163
+ // root component (vm)
164
+ if (options.el && weex.document) {
165
+ try {
166
+ // Send "createFinish" signal to native.
167
+ weex.document.taskCenter.send('dom', { action: 'createFinish' }, [])
168
+ } catch (e) {}
169
+ }
211
170
  }
212
171
  })
213
172
 
@@ -12,7 +12,7 @@ import {
12
12
  isReservedTag,
13
13
  isRuntimeComponent,
14
14
  isUnknownElement
15
- } from 'weex/util/index'
15
+ } from 'weex/util/element'
16
16
 
17
17
  // install platform specific utils
18
18
  Vue.config.mustUseProp = mustUseProp