Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(compiler): update weex recycle-list compiler #7610

Merged
merged 2 commits into from
Mar 5, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ export function postTransformComponentRoot (
if (!el.parent) {
// component root
addAttr(el, '@isComponentRoot', 'true')
addAttr(el, '@templateId', '_uid')
addAttr(el, '@componentProps', '$props || {}')
}
}
2 changes: 2 additions & 0 deletions src/platforms/weex/compiler/modules/recycle-list/index.js
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ 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

@@ -25,6 +26,7 @@ function preTransformNode (el: ASTElement, options: WeexCompilerOptions) {
preTransformVBind(el, options)
preTransformVIf(el, options) // also v-else-if and v-else
preTransformVFor(el, options)
preTransformVOnce(el, options)
}
}

Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ export function preTransformRecycleList (
}

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
26 changes: 21 additions & 5 deletions src/platforms/weex/compiler/modules/recycle-list/v-if.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* @flow */

import { addIfCondition } from 'compiler/parser/index'
import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'

function hasConditionDirective (el: ASTElement): boolean {
@@ -11,11 +12,23 @@ function hasConditionDirective (el: ASTElement): boolean {
return false
}

function getPrevMatch (el: ASTElement): any {
function getPreviousConditions (el: ASTElement): Array<string> {
const conditions = []
if (el.parent && el.parent.children) {
const prev: Object = el.parent.children[el.parent.children.length - 1]
return prev.attrsMap['[[match]]']
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) {
@@ -28,9 +41,12 @@ export function preTransformVIf (el: ASTElement, options: WeexCompilerOptions) {
getAndRemoveAttr(el, 'v-else', true)
if (ifExp) {
exp = ifExp
addIfCondition(el, { exp: ifExp, block: el })
} else {
const prevMatch = getPrevMatch(el)
if (prevMatch) {
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
19 changes: 19 additions & 0 deletions src/platforms/weex/compiler/modules/recycle-list/v-once.js
Original file line number Diff line number Diff line change
@@ -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)
}
}
59 changes: 30 additions & 29 deletions test/weex/cases/cases.spec.js
Original file line number Diff line number Diff line change
@@ -72,6 +72,7 @@ describe('Usage', () => {
it('v-for-iterator', createRenderTestCase('recycle-list/v-for-iterator'))
it('v-on', createRenderTestCase('recycle-list/v-on'))
it('v-on-inline', createRenderTestCase('recycle-list/v-on-inline'))
it('v-once', createRenderTestCase('recycle-list/v-once'))

it('stateless component', done => {
compileWithDeps('recycle-list/components/stateless.vue', [{
@@ -143,35 +144,35 @@ describe('Usage', () => {
expect(getRoot(instance)).toEqual(target)
tasks.length = 0

// trigger component hooks
instance.$triggerHook(
2, // cid of the virtual component template
'create', // lifecycle hook name

// arguments for the callback
[
'x-1', // componentId of the virtual component
{ start: 3 } // propsData of the virtual component
]
)
instance.$triggerHook(2, 'create', ['x-2', { start: 11 }])

// the state (_data) of the virtual component should be sent to native
expect(tasks.length).toEqual(2)
expect(tasks[0].method).toEqual('updateComponentData')
expect(tasks[0].args).toEqual(['x-1', { count: 6 }, ''])
expect(tasks[1].method).toEqual('updateComponentData')
expect(tasks[1].args).toEqual(['x-2', { count: 22 }, ''])

instance.$triggerHook('x-1', 'attach')
instance.$triggerHook('x-2', 'attach')
tasks.length = 0

// simulate a click event
// the event will be caught by the virtual component template and
// should be dispatched to virtual component according to the componentId
const event = getEvents(instance)[0]
fireEvent(instance, event.ref, 'click', { componentId: 'x-1' })
// // trigger component hooks
// instance.$triggerHook(
// 2, // cid of the virtual component template
// 'create', // lifecycle hook name

// // arguments for the callback
// [
// 'x-1', // componentId of the virtual component
// { start: 3 } // propsData of the virtual component
// ]
// )
// instance.$triggerHook(2, 'create', ['x-2', { start: 11 }])

// // the state (_data) of the virtual component should be sent to native
// expect(tasks.length).toEqual(2)
// expect(tasks[0].method).toEqual('updateComponentData')
// expect(tasks[0].args).toEqual(['x-1', { count: 6 }, ''])
// expect(tasks[1].method).toEqual('updateComponentData')
// expect(tasks[1].args).toEqual(['x-2', { count: 22 }, ''])

// instance.$triggerHook('x-1', 'attach')
// instance.$triggerHook('x-2', 'attach')
// tasks.length = 0

// // simulate a click event
// // the event will be caught by the virtual component template and
// // should be dispatched to virtual component according to the componentId
// const event = getEvents(instance)[0]
// fireEvent(instance, event.ref, 'click', { componentId: 'x-1' })
setTimeout(() => {
// expect(tasks.length).toEqual(1)
// expect(tasks[0].method).toEqual('updateComponentData')
2 changes: 1 addition & 1 deletion test/weex/cases/recycle-list/v-else-if.vdom.js
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@
}, {
type: 'image',
attr: {
'[[match]]': '!(!(item.sourceA) && (item.sourceB))',
'[[match]]': '!(item.sourceA || item.sourceB)',
src: { '@binding': 'item.placeholder' }
}
}]
22 changes: 22 additions & 0 deletions test/weex/cases/recycle-list/v-once.vdom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
({
type: 'recycle-list',
attr: {
append: 'tree',
listData: [
{ type: 'A' },
{ type: 'A' }
],
alias: 'item'
},
children: [{
type: 'cell-slot',
attr: { append: 'tree' },
children: [{
type: 'text',
attr: {
'[[once]]': true,
value: { '@binding': 'item.type' }
}
}]
}]
})
21 changes: 21 additions & 0 deletions test/weex/cases/recycle-list/v-once.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<recycle-list for="item in list">
<cell-slot>
<text v-once>{{item.type}}</text>
</cell-slot>
</recycle-list>
</template>

<script>
module.exports = {
data () {
return {
list: [
{ type: 'A' },
{ type: 'A' }
]
}
}
}
</script>

2 changes: 1 addition & 1 deletion test/weex/compiler/append.spec.js
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ describe('append props', () => {
it('add append="tree" on <recycle-list>', () => {
const { render, staticRenderFns, errors } = compile(`<recycle-list for="item in list"><div></div></recycle-list>`)
expect(render + staticRenderFns).toMatch(strToRegExp(`appendAsTree:true`))
expect(render + staticRenderFns).toMatch(strToRegExp(`attrs:{"listData":list,"alias":"item","append":"tree"}`))
expect(render + staticRenderFns).toMatch(strToRegExp(`"append":"tree"`))
expect(errors).toEqual([])
})

7 changes: 5 additions & 2 deletions test/weex/helpers/index.js
Original file line number Diff line number Diff line change
@@ -117,10 +117,13 @@ function omitUseless (object) {
delete object.ref
for (const key in object) {
omitUseless(object[key])
if (key === '@styleScope') {
if (key === '@styleScope' ||
key === '@templateId' ||
key === 'bindingExpression') {
delete object[key]
}
if (key.charAt(0) !== '@' && (isEmptyObject(object[key]) || object[key] === undefined)) {
if (key.charAt(0) !== '@' &&
(isEmptyObject(object[key]) || object[key] === undefined)) {
delete object[key]
}
}