Skip to content

Commit

Permalink
feat(weex richtext): support to parse styles and classList
Browse files Browse the repository at this point in the history
  • Loading branch information
Hanks10100 authored and yyx990803 committed Aug 29, 2017
1 parent 0ea2bb4 commit b609642
Show file tree
Hide file tree
Showing 2 changed files with 317 additions and 13 deletions.
32 changes: 23 additions & 9 deletions src/platforms/weex/runtime/components/richtext.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,28 @@ function isSimpleSpan (vnode) {
}

function trimCSSUnit (prop) {
return Number(prop.replace(/px$/i, '')) || prop
return Number(String(prop).replace(/px$/i, '')) || prop
}

function parseStyle (vnode) {
const { staticStyle, staticClass } = vnode.data
if (vnode.data.style || vnode.data.class || staticStyle || staticClass) {
const styles = Object.assign({}, staticStyle, vnode.data.style)

// TODO: more reliable
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])
}
})

for (const key in styles) {
styles[key] = trimCSSUnit(styles[key])
}
return styles
}
}

function convertVNodeChildren (children) {
Expand All @@ -31,15 +52,8 @@ function convertVNodeChildren (children) {
}

if (vnode.data) {
props.style = vnode.data.staticStyle
props.style = parseStyle(vnode)
props.attr = vnode.data.attrs

// TODO: convert inline styles
if (props.style) {
for (const key in props.style) {
props.style[key] = trimCSSUnit(props.style[key])
}
}
}

if (type === 'span' && isSimpleSpan(vnode)) {
Expand Down
298 changes: 294 additions & 4 deletions test/weex/runtime/component/richtext.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import {
createInstance
} from '../../helpers/index'

function compileSnippet (runtime, snippet) {
function compileSnippet (runtime, snippet, additional) {
const { render, staticRenderFns } = compileAndStringify(`<div>${snippet}</div>`)
const instance = createInstance(runtime, `
new Vue({
el: 'body',
render: ${render},
staticRenderFns: ${staticRenderFns},
el: 'body'
${additional}
})
`)
const result = instance.getRealRoot().children[0]
return result
return instance.getRealRoot().children[0]
}

describe('richtext component', () => {
Expand Down Expand Up @@ -57,6 +57,7 @@ describe('richtext component', () => {
})

describe('span', () => {
// pending('work in progress')
it('single node', () => {
expect(compileSnippet(runtime, `
<richtext>
Expand Down Expand Up @@ -124,6 +125,7 @@ describe('richtext component', () => {
})

describe('a', () => {
// pending('work in progress')
it('single node', () => {
expect(compileSnippet(runtime, `
<richtext>
Expand Down Expand Up @@ -162,6 +164,7 @@ describe('richtext component', () => {
})

describe('image', () => {
// pending('work in progress')
it('single node', () => {
expect(compileSnippet(runtime, `
<richtext>
Expand Down Expand Up @@ -220,6 +223,7 @@ describe('richtext component', () => {
})

describe('nested', () => {
// pending('work in progress')
it('span', () => {
expect(compileSnippet(runtime, `
<richtext>
Expand Down Expand Up @@ -296,6 +300,7 @@ describe('richtext component', () => {
describe('with styles', () => {
// pending('work in progress')
it('inline', () => {
// pending('work in progress')
expect(compileSnippet(runtime, `
<richtext>
<span style="font-size:16px;color:#FF6600;">ABCD</span>
Expand All @@ -316,5 +321,290 @@ describe('richtext component', () => {
}
})
})

it('class list', () => {
// pending('work in progress')
expect(compileSnippet(runtime, `
<richtext>
<image class="icon" src="path/to/A.png"></image>
<span class="title large">ABCD</span>
</richtext>
`, `
style: {
title: { color: '#FF6600' },
large: { fontSize: 24 },
icon: { width: 40, height: 60 }
}
`)).toEqual({
type: 'richtext',
attr: {
value: [{
type: 'image',
style: { width: 40, height: 60 },
attr: { src: 'path/to/A.png' }
}, {
type: 'span',
style: { fontSize: 24, color: '#FF6600' },
attr: { value: 'ABCD' }
}]
}
})
})
})

describe('data binding', () => {
// pending('work in progress')
it('simple', () => {
expect(compileSnippet(runtime, `
<richtext>
<span>{{name}}</span>
</richtext>
`, `data: { name: 'ABCDEFG' }`)).toEqual({
type: 'richtext',
attr: {
value: [{
type: 'span',
attr: { value: 'ABCDEFG' }
}]
}
})
})

it('nested', () => {
expect(compileSnippet(runtime, `
<richtext>
<span>{{a}}</span>
<span>{{b}}<span>{{c.d}}</span></span>
<span>{{e}}</span>
</richtext>
`, `data: { a: 'A', b: 'B', c: { d: 'CD' }, e: 'E' }`))
.toEqual({
type: 'richtext',
attr: {
value: [{
type: 'span',
attr: { value: 'A' }
}, {
type: 'span',
children: [{
type: 'span',
attr: { value: 'B' }
}, {
type: 'span',
attr: { value: 'CD' }
}]
}, {
type: 'span',
attr: { value: 'E' }
}]
}
})
})

it('update', () => {
expect(compileSnippet(runtime, `
<richtext>
<span>{{name}}</span>
</richtext>
`, `
data: { name: 'default' },
created: function () {
this.name = 'updated'
}
`)).toEqual({
type: 'richtext',
attr: {
value: [{
type: 'span',
attr: { value: 'updated' }
}]
}
})
})

it('attribute', () => {
expect(compileSnippet(runtime, `
<richtext>
<span :label="label">{{name}}</span>
</richtext>
`, `
data: {
label: 'uid',
name: '10100'
}
`)).toEqual({
type: 'richtext',
attr: {
value: [{
type: 'span',
attr: {
label: 'uid',
value: '10100'
}
}]
}
})
})

it('update attribute', () => {
expect(compileSnippet(runtime, `
<richtext>
<span :label="label">{{name}}</span>
</richtext>
`, `
data: {
label: 'name',
name: 'Hanks'
},
created: function () {
this.label = 'uid';
this.name = '10100';
}
`)).toEqual({
type: 'richtext',
attr: {
value: [{
type: 'span',
attr: {
label: 'uid',
value: '10100'
}
}]
}
})
})

it('inline style', () => {
expect(compileSnippet(runtime, `
<richtext>
<span :style="styleObject">ABCD</span>
<span :style="{ textAlign: align, color: 'red' }">EFGH</span>
</richtext>
`, `
data: {
styleObject: { fontSize: '32px', color: '#F6F660' },
align: 'center'
}
`)).toEqual({
type: 'richtext',
attr: {
value: [{
type: 'span',
style: { fontSize: 32, color: '#F6F660' },
attr: { value: 'ABCD' }
}, {
type: 'span',
style: { textAlign: 'center', color: 'red' },
attr: { value: 'EFGH' }
}]
}
})
})

it('class list', () => {
// pending('work in progress')
expect(compileSnippet(runtime, `
<richtext>
<image :class="classList" src="path/to/A.png"></image>
<span :class="['title', size]">ABCD</span>
<span class="large" style="color:#F6F0F4">EFGH</span>
</richtext>
`, `
style: {
title: { color: '#FF6600' },
large: { fontSize: 24 },
icon: { width: 40, height: 60 }
},
data: {
classList: ['unknown'],
size: 'small'
},
created: function () {
this.classList = ['icon'];
this.size = 'large';
}
`)).toEqual({
type: 'richtext',
attr: {
value: [{
type: 'image',
style: { width: 40, height: 60 },
attr: { src: 'path/to/A.png' }
}, {
type: 'span',
style: { fontSize: 24, color: '#FF6600' },
attr: { value: 'ABCD' }
}, {
type: 'span',
style: { fontSize: 24, color: '#F6F0F4' },
attr: { value: 'EFGH' }
}]
}
})
})

it('update inline style', () => {
expect(compileSnippet(runtime, `
<richtext>
<span :style="styleObject">ABCD</span>
<span :style="{ textAlign: align, color: 'red' }">EFGH</span>
</richtext>
`, `
data: {
styleObject: { fontSize: '32px', color: '#F6F660' }
},
created: function () {
this.styleObject = { fontSize: '24px', color: 'blue' }
this.styleObject.color = '#ABCDEF'
this.align = 'left'
}
`)).toEqual({
type: 'richtext',
attr: {
value: [{
type: 'span',
style: { fontSize: 24, color: '#ABCDEF' },
attr: { value: 'ABCD' }
}, {
type: 'span',
style: { textAlign: 'left', color: 'red' },
attr: { value: 'EFGH' }
}]
}
})
})
})

describe('bind events', () => {
pending('work in progress')
it('inline', () => {
const { render, staticRenderFns } = compileAndStringify(`
<div>
<richtext>
<span @click="handler">Button</span>
</richtext>
</div>
`)
const instance = createInstance(runtime, `
new Vue({
el: 'body',
render: ${render},
staticRenderFns: ${staticRenderFns},
methods: {
handler: function () {}
}
})
`)
expect(instance.getRealRoot().children[0]).toEqual({
type: 'richtext',
attr: {
value: [{
type: 'span',
events: { click: 'handler' },
attr: { value: 'Button' }
}]
}
})
})
})
})

0 comments on commit b609642

Please sign in to comment.