Przeglądaj źródła

feat(weex richtext): support events and add more test cases

Hanks 9 lat temu
rodzic
commit
d627161a91

+ 22 - 13
src/platforms/weex/runtime/components/richtext.js

@@ -1,9 +1,8 @@
 function getVNodeType (vnode) {
-  const tagName = vnode.tag
-  if (!tagName) {
+  if (!vnode.tag) {
     return ''
   }
-  return tagName.replace(/vue\-component\-(\d+\-)?/, '')
+  return vnode.tag.replace(/vue\-component\-(\d+\-)?/, '')
 }
 
 function isSimpleSpan (vnode) {
@@ -11,10 +10,15 @@ function isSimpleSpan (vnode) {
 }
 
 function trimCSSUnit (prop) {
+  // TODO: more reliable
   return Number(String(prop).replace(/px$/i, '')) || prop
 }
 
 function parseStyle (vnode) {
+  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)
@@ -39,6 +43,7 @@ function convertVNodeChildren (children) {
   if (!children.length) {
     return
   }
+
   return children.map(vnode => {
     const type = getVNodeType(vnode)
     const props = { type }
@@ -49,17 +54,20 @@ function convertVNodeChildren (children) {
       props.attr = {
         value: (vnode.text || '').trim()
       }
-    }
-
-    if (vnode.data) {
+    } else {
       props.style = parseStyle(vnode)
-      props.attr = vnode.data.attrs
-    }
+      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 (type === 'span' && isSimpleSpan(vnode)) {
+        props.attr = props.attr || {}
+        props.attr.value = vnode.children[0].text.trim()
+        return props
+      }
     }
 
     if (vnode.children && vnode.children.length) {
@@ -72,9 +80,10 @@ function convertVNodeChildren (children) {
 
 export default {
   name: 'richtext',
-  abstract: true,
+  // abstract: true,
   render (h) {
     return h('weex:richtext', {
+      on: this._events,
       attrs: {
         value: convertVNodeChildren(this.$options._renderChildren || [])
       }

+ 100 - 8
test/weex/runtime/component/richtext.spec.js

@@ -577,12 +577,12 @@ describe('richtext component', () => {
 
   describe('bind events', () => {
     pending('work in progress')
-    it('inline', () => {
+    it('inline', (done) => {
       const { render, staticRenderFns } = compileAndStringify(`
         <div>
-        <richtext>
-          <span @click="handler">Button</span>
-        </richtext>
+          <richtext>
+            <span @click="handler">{{label}}</span>
+          </richtext>
         </div>
       `)
       const instance = createInstance(runtime, `
@@ -590,21 +590,113 @@ describe('richtext component', () => {
           el: 'body',
           render: ${render},
           staticRenderFns: ${staticRenderFns},
+          data: { label: 'AAA' },
           methods: {
-            handler: function () {}
+            handler: function () {
+              this.label = 'BBB'
+            }
           }
         })
       `)
-      expect(instance.getRealRoot().children[0]).toEqual({
+      // instance.$fireEvent(instance.doc.body.children[0].ref, 'click', {})
+      const richtext = instance.doc.body.children[0]
+      const span = richtext.children[0].ref
+      instance.$fireEvent(span.ref, 'click', {})
+      setTimeout(() => {
+        expect(instance.getRealRoot().children[0]).toEqual({
+          type: 'richtext',
+          event: ['click'],
+          attr: {
+            value: [{
+              type: 'span',
+              attr: { value: 'BBB' }
+            }]
+          }
+        })
+        done()
+      }, 0)
+    })
+  })
+
+  describe('itself', () => {
+    // pending('work in progress')
+    it('inline styles', () => {
+      expect(compileSnippet(runtime, `
+        <richtext style="background-color:red">
+          <span>empty</span>
+        </richtext>
+      `)).toEqual({
         type: 'richtext',
+        style: { backgroundColor: 'red' },
         attr: {
           value: [{
             type: 'span',
-            events: { click: 'handler' },
-            attr: { value: 'Button' }
+            attr: { value: 'empty' }
           }]
         }
       })
     })
+
+    it('class list', () => {
+      // pending('work in progress')
+      expect(compileSnippet(runtime, `
+        <richtext class="title">
+          <span class="large">ABCD</span>
+        </richtext>
+      `, `
+        style: {
+          title: { backgroundColor: '#FF6600', height: 200 },
+          large: { fontSize: 24 }
+        }
+      `)).toEqual({
+        type: 'richtext',
+        style: { backgroundColor: '#FF6600', height: 200 },
+        attr: {
+          value: [{
+            type: 'span',
+            style: { fontSize: 24 },
+            attr: { value: 'ABCD' }
+          }]
+        }
+      })
+    })
+
+    it('bind events', (done) => {
+      const { render, staticRenderFns } = compileAndStringify(`
+        <div>
+          <richtext @click="handler">
+            <span>Label: {{label}}</span>
+          </richtext>
+        </div>
+      `)
+      const instance = createInstance(runtime, `
+        new Vue({
+          el: 'body',
+          render: ${render},
+          staticRenderFns: ${staticRenderFns},
+          data: { label: 'AAA' },
+          methods: {
+            handler: function () {
+              this.label = 'BBB'
+            }
+          }
+        })
+      `)
+      const richtext = instance.doc.body.children[0]
+      instance.$fireEvent(richtext.ref, 'click', {})
+      setTimeout(() => {
+        expect(instance.getRealRoot().children[0]).toEqual({
+          type: 'richtext',
+          event: ['click'],
+          attr: {
+            value: [{
+              type: 'span',
+              attr: { value: 'Label: BBB' }
+            }]
+          }
+        })
+        done()
+      }, 0)
+    })
   })
 })