diff --git a/src/platforms/weex/runtime/components/richtext.js b/src/platforms/weex/runtime/components/richtext.js
index 5ad6259750..ddfa3340ba 100644
--- a/src/platforms/weex/runtime/components/richtext.js
+++ b/src/platforms/weex/runtime/components/richtext.js
@@ -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) {
@@ -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)) {
diff --git a/test/weex/runtime/component/richtext.spec.js b/test/weex/runtime/component/richtext.spec.js
index 41bbcefda4..20bc8be2a4 100644
--- a/test/weex/runtime/component/richtext.spec.js
+++ b/test/weex/runtime/component/richtext.spec.js
@@ -5,17 +5,17 @@ import {
createInstance
} from '../../helpers/index'
-function compileSnippet (runtime, snippet) {
+function compileSnippet (runtime, snippet, additional) {
const { render, staticRenderFns } = compileAndStringify(`
${snippet}
`)
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', () => {
@@ -57,6 +57,7 @@ describe('richtext component', () => {
})
describe('span', () => {
+ // pending('work in progress')
it('single node', () => {
expect(compileSnippet(runtime, `
@@ -124,6 +125,7 @@ describe('richtext component', () => {
})
describe('a', () => {
+ // pending('work in progress')
it('single node', () => {
expect(compileSnippet(runtime, `
@@ -162,6 +164,7 @@ describe('richtext component', () => {
})
describe('image', () => {
+ // pending('work in progress')
it('single node', () => {
expect(compileSnippet(runtime, `
@@ -220,6 +223,7 @@ describe('richtext component', () => {
})
describe('nested', () => {
+ // pending('work in progress')
it('span', () => {
expect(compileSnippet(runtime, `
@@ -296,6 +300,7 @@ describe('richtext component', () => {
describe('with styles', () => {
// pending('work in progress')
it('inline', () => {
+ // pending('work in progress')
expect(compileSnippet(runtime, `
ABCD
@@ -316,5 +321,290 @@ describe('richtext component', () => {
}
})
})
+
+ it('class list', () => {
+ // pending('work in progress')
+ expect(compileSnippet(runtime, `
+
+
+ ABCD
+
+ `, `
+ 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, `
+
+ {{name}}
+
+ `, `data: { name: 'ABCDEFG' }`)).toEqual({
+ type: 'richtext',
+ attr: {
+ value: [{
+ type: 'span',
+ attr: { value: 'ABCDEFG' }
+ }]
+ }
+ })
+ })
+
+ it('nested', () => {
+ expect(compileSnippet(runtime, `
+
+ {{a}}
+ {{b}}{{c.d}}
+ {{e}}
+
+ `, `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, `
+
+ {{name}}
+
+ `, `
+ data: { name: 'default' },
+ created: function () {
+ this.name = 'updated'
+ }
+ `)).toEqual({
+ type: 'richtext',
+ attr: {
+ value: [{
+ type: 'span',
+ attr: { value: 'updated' }
+ }]
+ }
+ })
+ })
+
+ it('attribute', () => {
+ expect(compileSnippet(runtime, `
+
+ {{name}}
+
+ `, `
+ data: {
+ label: 'uid',
+ name: '10100'
+ }
+ `)).toEqual({
+ type: 'richtext',
+ attr: {
+ value: [{
+ type: 'span',
+ attr: {
+ label: 'uid',
+ value: '10100'
+ }
+ }]
+ }
+ })
+ })
+
+ it('update attribute', () => {
+ expect(compileSnippet(runtime, `
+
+ {{name}}
+
+ `, `
+ 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, `
+
+ ABCD
+ EFGH
+
+ `, `
+ 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, `
+
+
+ ABCD
+ EFGH
+
+ `, `
+ 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, `
+
+ ABCD
+ EFGH
+
+ `, `
+ 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(`
+
+
+ Button
+
+
+ `)
+ 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' }
+ }]
+ }
+ })
+ })
})
})