You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ta...@apache.org on 2017/07/28 09:11:53 UTC

[14/43] incubator-weex git commit: * [html5] implementate the integrated components as render's plugin, which should have no directly dependency on render core.

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/components/slider/slideMixin.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/slider/slideMixin.js b/html5/render/vue/components/slider/slideMixin.js
index 2b7bfa1..f160d58 100644
--- a/html5/render/vue/components/slider/slideMixin.js
+++ b/html5/render/vue/components/slider/slideMixin.js
@@ -17,17 +17,6 @@
  * under the License.
  */
 import './slider.css'
-import {
-  throttle,
-  createEvent,
-  fireLazyload,
-  addTransform,
-  copyTransform,
-  getTransformObj,
-  bind,
-  extendKeys
-} from '../../utils'
-import { extractComponentStyle, createEventMap } from '../../core'
 
 const TRANSITION_TIME = 400
 const NEIGHBOR_SCALE_TIME = 100
@@ -59,7 +48,7 @@ export default {
         }
       }
     }
-    fireLazyload(this.$el, true)
+    weex.utils.fireLazyload(this.$el, true)
     if (this._preIndex !== this.currentIndex) {
       this._slideTo(this.currentIndex)
     }
@@ -68,7 +57,7 @@ export default {
   mounted () {
     this._getWrapperSize()
     this._slideTo(this.currentIndex)
-    fireLazyload(this.$el, true)
+    weex.utils.fireLazyload(this.$el, true)
   },
 
   methods: {
@@ -109,24 +98,23 @@ export default {
     _renderSlides (createElement) {
       this._cells = this._formatChildren(createElement)
       this.frameCount = this._cells.length
-      this._renderHook()
       return createElement(
         'nav',
         {
           ref: 'wrapper',
           attrs: { 'weex-type': this.isNeighbor ? 'slider-neighbor' : 'slider' },
-          on: createEventMap(
+          on: weex.createEventMap(
             this,
             ['scroll', 'scrollstart', 'scrollend'],
             {
               touchstart: this._handleTouchStart,
-              touchmove: throttle(bind(this._handleTouchMove, this), 25),
+              touchmove: weex.utils.throttle(weex.utils.bind(this._handleTouchMove, this), 25),
               touchend: this._handleTouchEnd,
               touchcancel: this._handleTouchCancel
             }
           ),
           staticClass: 'weex-slider weex-slider-wrapper weex-ct',
-          staticStyle: extractComponentStyle(this)
+          staticStyle: weex.extractComponentStyle(this)
         },
         [
           createElement('ul', {
@@ -154,7 +142,7 @@ export default {
       }
       let interval = parseInt(this.interval - TRANSITION_TIME - NEIGHBOR_SCALE_TIME)
       interval = interval > INTERVAL_MINIMUM ? interval : INTERVAL_MINIMUM
-      this._autoPlayTimer = setTimeout(bind(this._next, this), interval)
+      this._autoPlayTimer = setTimeout(weex.utils.bind(this._next, this), interval)
     },
 
     _stopAutoPlay () {
@@ -195,7 +183,7 @@ export default {
 
       if (inner) {
         this._prepareNodes()
-        const translate = getTransformObj(inner).translate
+        const translate = weex.utils.getTransformObj(inner).translate
         const match = translate && translate.match(/translate[^(]+\(([+-\d.]+)/)
         const innerX = match && match[1] || 0
         const dist = innerX - this.innerOffset
@@ -240,7 +228,7 @@ export default {
       }
 
       if (newIndex !== this._preIndex) {
-        this.$emit('change', createEvent(this.$el, 'change', {
+        this.$emit('change', weex.utils.createEvent(this.$el, 'change', {
           index: newIndex
         }))
       }
@@ -252,7 +240,7 @@ export default {
         let node = this._showNodes[i]
         node = node && node.firstElementChild
         if (!node) { continue }
-        addTransform(this._showNodes[i].firstElementChild, {
+        weex.utils.addTransform(this._showNodes[i].firstElementChild, {
           translate: 'translate3d(0px, 0px, 0px)'
         })
       }
@@ -343,7 +331,7 @@ export default {
 
       node._inShow = true
       const translateX = index * this._wrapperWidth - this.innerOffset
-      addTransform(node, {
+      weex.utils.addTransform(node, {
         translate: `translate3d(${translateX}px, 0px, 0px)`
       })
       node.style.zIndex = 99 - Math.abs(index)
@@ -408,16 +396,16 @@ export default {
      * one element to another.
      */
     _copyStyle (from, to, styles = ['opacity', 'zIndex'], transformExtra = {}) {
-      extendKeys(to.style, from.style, styles)
-      const transObj = getTransformObj(from)
+      weex.utils.extendKeys(to.style, from.style, styles)
+      const transObj = weex.utils.getTransformObj(from)
       for (const k in transformExtra) {
         transObj[k] = transformExtra[k]
       }
-      addTransform(to, transObj)
+      weex.utils.addTransform(to, transObj)
       const fromInner = from.firstElementChild
       const toInner = to.firstElementChild
       toInner.style.opacity = fromInner.style.opacity
-      copyTransform(fromInner, toInner)
+      weex.utils.copyTransform(fromInner, toInner)
     },
 
     /**
@@ -438,7 +426,7 @@ export default {
         this._showNodes[origShowIndex] = cl
       }
       origNode._inShow = true
-      const transObj = getTransformObj(clone)
+      const transObj = weex.utils.getTransformObj(clone)
       transObj.translate = transObj.translate.replace(/[+-\d.]+[pw]x/, ($0) => {
         return pos * this._wrapperWidth - this.innerOffset + 'px'
       })
@@ -519,7 +507,7 @@ export default {
           translateX = 0
         }
         transObj.translate = `translate3d(${translateX}px, 0px, 0px)`
-        addTransform(elm, transObj)
+        weex.utils.addTransform(elm, transObj)
         elm.style.opacity = i === 0 ? MAIN_SLIDE_OPACITY : this.neighborAlpha
       }
     },
@@ -620,7 +608,7 @@ export default {
     },
 
     _emitScrollEvent (type, data = {}) {
-      this.$emit(type, createEvent(this.$el, type, data))
+      this.$emit(type, weex.utils.createEvent(this.$el, type, data))
     },
 
     _throttleEmitScroll (offset, callback) {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/components/slider/slider-neighbor.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/slider/slider-neighbor.js b/html5/render/vue/components/slider/slider-neighbor.js
index 7d691e1..ba8ec03 100644
--- a/html5/render/vue/components/slider/slider-neighbor.js
+++ b/html5/render/vue/components/slider/slider-neighbor.js
@@ -23,7 +23,7 @@ const DEFAULT_NEIGHBOR_ALPHA = 0.6
 const DEFAULT_NEIGHBOR_SCALE = 0.8
 const DEFAULT_CURRENT_ITEM_SCALE = 0.9
 
-export default {
+const sliderNeighbor = {
   mixins: [slideMixin],
   props: {
     index: {
@@ -95,10 +95,12 @@ export default {
   },
 
   render (createElement) {
-    /* istanbul ignore next */
-    // if (process.env.NODE_ENV === 'development') {
-    //   validateStyles('slider', this.$vnode.data && this.$vnode.data.staticStyle)
-    // }
     return this._renderSlides(createElement)
   }
 }
+
+export default {
+  init (weex) {
+    weex.registerComponent('slider-neighbor', sliderNeighbor)
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/components/slider/slider.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/slider/slider.js b/html5/render/vue/components/slider/slider.js
new file mode 100644
index 0000000..f916799
--- /dev/null
+++ b/html5/render/vue/components/slider/slider.js
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+// import { validateStyles } from '../../validator'
+// import indicator from './indicator'
+import slideMixin from './slideMixin'
+
+const slider = {
+  mixins: [slideMixin],
+  props: {
+    index: {
+      type: [String, Number],
+      default: 0
+    },
+    'auto-play': {
+      type: [String, Boolean],
+      default: false
+    },
+    interval: {
+      type: [String, Number],
+      default: 3000
+    },
+    infinite: {
+      type: [String, Boolean],
+      default: true
+    }
+  },
+
+  watch: {
+    index () {
+      this.currentIndex = this._normalizeIndex(this.index)
+    }
+  },
+
+  data () {
+    return {
+      frameCount: 0,
+      currentIndex: this.index
+    }
+  },
+
+  beforeCreate () {
+    this.weexType = 'slider'
+  },
+
+  render (createElement) {
+    /* istanbul ignore next */
+    // if (process.env.NODE_ENV === 'development') {
+    //   validateStyles('slider', this.$vnode.data && this.$vnode.data.staticStyle)
+    // }
+    return this._renderSlides(createElement)
+  }
+}
+
+export default {
+  init (weex) {
+    weex.registerComponent('slider', slider)
+    weex.registerComponent('cycleslider', slider)
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/components/switch.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/switch.js b/html5/render/vue/components/switch.js
index 6780da9..508957b 100644
--- a/html5/render/vue/components/switch.js
+++ b/html5/render/vue/components/switch.js
@@ -16,8 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-// import { validateStyles } from '../validator'
-import { extractComponentStyle } from '../core'
 
 const _css = `
 .weex-switch {
@@ -76,58 +74,68 @@ const _css = `
 }
 `
 
-export default {
-  props: {
-    checked: {
-      type: [Boolean, String],
-      default: false
+function getSwitch (weex) {
+  const { extractComponentStyle } = weex
+
+  return {
+    name: 'weex-switch',
+    props: {
+      checked: {
+        type: [Boolean, String],
+        default: false
+      },
+      disabled: {
+        type: [Boolean, String],
+        default: false
+      }
     },
-    disabled: {
-      type: [Boolean, String],
-      default: false
-    }
-  },
-  data () {
-    return {
-      isChecked: (this.checked !== 'false' && this.checked !== false),
-      isDisabled: (this.disabled !== 'false' && this.disabled !== false)
-    }
-  },
-  computed: {
-    wrapperClass () {
-      const classArray = ['weex-switch']
-      this.isChecked && classArray.push('weex-switch-checked')
-      this.isDisabled && classArray.push('weex-switch-disabled')
-      return classArray.join(' ')
-    }
-  },
-  methods: {
-    toggle () {
-      // TODO: handle the events
-      if (!this.isDisabled) {
-        this.isChecked = !this.isChecked
-        this.$emit('change', { value: this.isChecked })
+    data () {
+      return {
+        isChecked: (this.checked !== 'false' && this.checked !== false),
+        isDisabled: (this.disabled !== 'false' && this.disabled !== false)
       }
-    }
-  },
-
-  render (createElement) {
-    /* istanbul ignore next */
-    // if (process.env.NODE_ENV === 'development') {
-    //   validateStyles('switch', this.$vnode.data && this.$vnode.data.staticStyle)
-    // }
-    this._renderHook()
-    return createElement('span', {
-      attrs: { 'weex-type': 'switch' },
-      on: {
-        click: event => {
-          this.$emit('click', event)
-          this.toggle()
+    },
+    computed: {
+      wrapperClass () {
+        const classArray = ['weex-switch']
+        this.isChecked && classArray.push('weex-switch-checked')
+        this.isDisabled && classArray.push('weex-switch-disabled')
+        return classArray.join(' ')
+      }
+    },
+    methods: {
+      toggle () {
+        // TODO: handle the events
+        if (!this.isDisabled) {
+          this.isChecked = !this.isChecked
+          this.$emit('change', { value: this.isChecked })
         }
-      },
-      staticClass: this.wrapperClass,
-      staticStyle: extractComponentStyle(this)
-    }, [createElement('small', { staticClass: 'weex-switch-inner' })])
-  },
-  _css
+      }
+    },
+
+    render (createElement) {
+      /* istanbul ignore next */
+      // if (process.env.NODE_ENV === 'development') {
+      //   validateStyles('switch', this.$vnode.data && this.$vnode.data.staticStyle)
+      // }
+      return createElement('span', {
+        attrs: { 'weex-type': 'switch' },
+        on: {
+          click: event => {
+            this.$emit('click', event)
+            this.toggle()
+          }
+        },
+        staticClass: this.wrapperClass,
+        staticStyle: extractComponentStyle(this)
+      }, [createElement('small', { staticClass: 'weex-switch-inner' })])
+    },
+    _css
+  }
+}
+
+export default {
+  init (weex) {
+    weex.registerComponent('switch', getSwitch(weex))
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/components/text.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/text.js b/html5/render/vue/components/text.js
index e0f14ee..0ff66f4 100644
--- a/html5/render/vue/components/text.js
+++ b/html5/render/vue/components/text.js
@@ -25,9 +25,6 @@
  * be clipped according to the 'lines'. Otherwise, it'll be the 'height'.
  */
 
-import { extractComponentStyle, createEventMap } from '../core'
-import { extend } from '../utils'
-
 const _css = `
 .weex-text {
   display: -webkit-box;
@@ -55,26 +52,33 @@ function getTextSpecStyle (ms = {}) {
   }
 }
 
-export default {
-  props: {
-    lines: [Number, String],
-    value: [String]
-  },
+function getText (weex) {
+  const { extractComponentStyle, createEventMap } = weex
+  const { extend } = weex.utils
+
+  return {
+    name: 'weex-text',
+    props: {
+      lines: [Number, String],
+      value: [String]
+    },
+
+    render (createElement) {
+      const style = extractComponentStyle(this)
+      const textSpecStyle = getTextSpecStyle(style)
+      return createElement('p', {
+        attrs: { 'weex-type': 'text' },
+        on: createEventMap(this),
+        staticClass: 'weex-text weex-el',
+        staticStyle: extend(style, textSpecStyle)
+      }, this.$slots.default || [this.value])
+    },
+    _css
+  }
+}
 
-  render (createElement) {
-    /* istanbul ignore next */
-    // if (process.env.NODE_ENV === 'development') {
-    //   validateStyles('text', this.$vnode.data && this.$vnode.data.staticStyle)
-    // }
-    const style = extractComponentStyle(this)
-    const textSpecStyle = getTextSpecStyle(style)
-    this._renderHook()
-    return createElement('p', {
-      attrs: { 'weex-type': 'text' },
-      on: createEventMap(this),
-      staticClass: 'weex-text weex-el',
-      staticStyle: extend(style, textSpecStyle)
-    }, this.$slots.default || [this.value])
-  },
-  _css
+export default {
+  init (weex) {
+    weex.registerComponent('text', getText(weex))
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/components/textarea.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/textarea.js b/html5/render/vue/components/textarea.js
index 63a2e3c..0a40ba5 100644
--- a/html5/render/vue/components/textarea.js
+++ b/html5/render/vue/components/textarea.js
@@ -16,12 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { extractComponentStyle, createEventMap } from '../core'
-import { inputCommon } from '../mixins'
-import { extend, mapFormEvents } from '../utils'
-
-// import { validateStyles } from '../validator'
-
 const _css = `
 .weex-textarea {
   font-size: 0.426667rem
@@ -31,50 +25,62 @@ const _css = `
 }
 `
 
-export default {
-  mixins: [inputCommon],
-  props: {
-    value: String,
-    placeholder: String,
-    disabled: {
-      type: [String, Boolean],
-      default: false
-    },
-    autofocus: {
-      type: [String, Boolean],
-      default: false
-    },
-    rows: {
-      type: [String, Number],
-      default: 2
-    },
-    returnKeyType: String
-  },
+function getTextarea (weex) {
+  const { extractComponentStyle, createEventMap } = weex
+  const { inputCommon } = weex.mixins
+  const { extend, mapFormEvents } = weex.utils
 
-  render (createElement) {
-    /* istanbul ignore next */
-    // if (process.env.NODE_ENV === 'development') {
-    //   validateStyles('textarea', this.$vnode.data && this.$vnode.data.staticStyle)
-    // }
-    const events = extend(createEventMap(this), mapFormEvents(this))
-    this._renderHook()
-    return createElement('html:textarea', {
-      attrs: {
-        'weex-type': 'textarea',
-        value: this.value,
-        disabled: (this.disabled !== 'false' && this.disabled !== false),
-        autofocus: (this.autofocus !== 'false' && this.autofocus !== false),
-        placeholder: this.placeholder,
-        rows: this.rows,
-        'return-key-type': this.returnKeyType
+  return {
+    name: 'weex-textarea',
+    mixins: [inputCommon],
+    props: {
+      value: String,
+      placeholder: String,
+      disabled: {
+        type: [String, Boolean],
+        default: false
+      },
+      autofocus: {
+        type: [String, Boolean],
+        default: false
       },
-      domProps: {
-        value: this.value
+      rows: {
+        type: [String, Number],
+        default: 2
       },
-      on: this.createKeyboardEvent(events),
-      staticClass: 'weex-textarea weex-el',
-      staticStyle: extractComponentStyle(this)
-    })
-  },
-  _css
+      returnKeyType: String
+    },
+
+    render (createElement) {
+      /* istanbul ignore next */
+      // if (process.env.NODE_ENV === 'development') {
+      //   validateStyles('textarea', this.$vnode.data && this.$vnode.data.staticStyle)
+      // }
+      const events = extend(createEventMap(this), mapFormEvents(this))
+      return createElement('html:textarea', {
+        attrs: {
+          'weex-type': 'textarea',
+          value: this.value,
+          disabled: (this.disabled !== 'false' && this.disabled !== false),
+          autofocus: (this.autofocus !== 'false' && this.autofocus !== false),
+          placeholder: this.placeholder,
+          rows: this.rows,
+          'return-key-type': this.returnKeyType
+        },
+        domProps: {
+          value: this.value
+        },
+        on: this.createKeyboardEvent(events),
+        staticClass: 'weex-textarea weex-el',
+        staticStyle: extractComponentStyle(this)
+      })
+    },
+    _css
+  }
+}
+
+export default {
+  init (weex) {
+    weex.registerComponent('textarea', getTextarea(weex))
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/components/video.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/video.js b/html5/render/vue/components/video.js
index bd87a03..d292386 100644
--- a/html5/render/vue/components/video.js
+++ b/html5/render/vue/components/video.js
@@ -16,63 +16,70 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-// import { validateStyles } from '../validator'
-import { extractComponentStyle, createEventMap } from '../core'
 
-export default {
-  props: {
-    src: String,
-    playStatus: {
-      type: String,
-      default: 'pause',
-      validator (value) {
-        return ['play', 'pause'].indexOf(value) !== -1
+function getVideo (weex) {
+  const { extractComponentStyle, createEventMap } = weex
+
+  return {
+    name: 'weex-video',
+    props: {
+      src: String,
+      playStatus: {
+        type: String,
+        default: 'pause',
+        validator (value) {
+          return ['play', 'pause'].indexOf(value) !== -1
+        }
+      },
+      autoplay: {
+        type: [String, Boolean],
+        default: false
+      },
+      autoPlay: {
+        type: [String, Boolean],
+        default: false
+      },
+      playsinline: {
+        type: [String, Boolean],
+        default: true
+      },
+      controls: {
+        type: [String, Boolean],
+        default: false
       }
     },
-    autoplay: {
-      type: [String, Boolean],
-      default: false
-    },
-    autoPlay: {
-      type: [String, Boolean],
-      default: false
-    },
-    playsinline: {
-      type: [String, Boolean],
-      default: true
-    },
-    controls: {
-      type: [String, Boolean],
-      default: false
-    }
-  },
 
-  render (createElement) {
-    this._renderHook()
+    render (createElement) {
+      if (this.playStatus === 'play') {
+        this.$nextTick(function () {
+          this.$el && this.$el.play()
+        })
+      }
+      else if (this.playStatus === 'pause') {
+        this.$nextTick(function () {
+          this.$el && this.$el.pause()
+        })
+      }
 
-    if (this.playStatus === 'play') {
-      this.$nextTick(function () {
-        this.$el && this.$el.play()
-      })
-    }
-    else if (this.playStatus === 'pause') {
-      this.$nextTick(function () {
-        this.$el && this.$el.pause()
+      return createElement('html:video', {
+        attrs: {
+          'weex-type': 'video',
+          autoplay: ((this.autoplay !== 'false' && this.autoplay !== false)
+            || (this.autoPlay !== 'false' && this.autoPlay !== false)),
+          'webkit-playsinline': this.playsinline,
+          controls: this.controls,
+          src: this.src
+        },
+        on: createEventMap(this, ['start', 'pause', 'finish', 'fail']),
+        staticClass: 'weex-video weex-el',
+        staticStyle: extractComponentStyle(this)
       })
     }
+  }
+}
 
-    return createElement('html:video', {
-      attrs: {
-        'weex-type': 'video',
-        autoplay: ((this.autoplay !== 'false' && this.autoplay !== false)
-          || (this.autoPlay !== 'false' && this.autoPlay !== false)),
-        'webkit-playsinline': this.playsinline,
-        controls: this.controls,
-        src: this.src
-      },
-      on: createEventMap(this, ['start', 'pause', 'finish', 'fail']),
-      staticClass: 'weex-video weex-el',
-      staticStyle: extractComponentStyle(this)
-    })
+export default {
+  init (weex) {
+    weex.registerComponent('video', getVideo(weex))
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/components/web.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/web.js b/html5/render/vue/components/web.js
index c0f03a9..906fb03 100644
--- a/html5/render/vue/components/web.js
+++ b/html5/render/vue/components/web.js
@@ -16,9 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { extractComponentStyle, createEventMap } from '../core'
-import { createEvent } from '../utils'
-// import { validateStyles } from '../validator'
 
 const _css = `
 .weex-web {
@@ -30,54 +27,65 @@ const _css = `
 }
 `
 
-export default {
-  props: {
-    src: String
-  },
-  methods: {
-    // TODO: check cross-origin
-    goBack () {
-      if (this.$el) {
-        this.$el.contentWindow.history.back()
-      }
+function getWeb (weex) {
+  const { extractComponentStyle, createEventMap } = weex
+  const { createEvent } = weex.utils
+
+  return {
+    name: 'weex-web',
+    props: {
+      src: String
     },
-    goForward () {
-      if (this.$el) {
-        this.$el.contentWindow.history.forward()
+    methods: {
+      // TODO: check cross-origin
+      goBack () {
+        if (this.$el) {
+          this.$el.contentWindow.history.back()
+        }
+      },
+      goForward () {
+        if (this.$el) {
+          this.$el.contentWindow.history.forward()
+        }
+      },
+      reload () {
+        if (this.$el) {
+          this.$el.contentWindow.history.reload()
+        }
       }
     },
-    reload () {
+
+    mounted () {
       if (this.$el) {
-        this.$el.contentWindow.history.reload()
+        this.$emit('pagestart', createEvent(this.$el, 'pagestart', { url: this.src }))
+        this.$el.addEventListener('load', event => {
+          this.$emit('pagefinish', createEvent(this.$el, 'pagefinish', { url: this.src }))
+        })
       }
-    }
-  },
+    },
 
-  mounted () {
-    if (this.$el) {
-      this.$emit('pagestart', createEvent(this.$el, 'pagestart', { url: this.src }))
-      this.$el.addEventListener('load', event => {
-        this.$emit('pagefinish', createEvent(this.$el, 'pagefinish', { url: this.src }))
+    render (createElement) {
+      /* istanbul ignore next */
+      // if (process.env.NODE_ENV === 'development') {
+      //   validateStyles('web', this.$vnode.data && this.$vnode.data.staticStyle)
+      // }
+      return createElement('iframe', {
+        attrs: {
+          'weex-type': 'web',
+          src: this.src
+        },
+        on: createEventMap(this, ['error']),
+        staticClass: 'weex-web weex-el',
+        staticStyle: extractComponentStyle(this)
       })
-    }
-  },
-
-  render (createElement) {
-    /* istanbul ignore next */
-    // if (process.env.NODE_ENV === 'development') {
-    //   validateStyles('web', this.$vnode.data && this.$vnode.data.staticStyle)
-    // }
+    },
+    _css
+  }
+}
 
-    this._renderHook()
-    return createElement('iframe', {
-      attrs: {
-        'weex-type': 'web',
-        src: this.src
-      },
-      on: createEventMap(this, ['error']),
-      staticClass: 'weex-web weex-el',
-      staticStyle: extractComponentStyle(this)
-    })
-  },
-  _css
+export default {
+  init (weex) {
+    weex.registerComponent('web', getWeb(weex))
+  }
 }
+

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/core/style.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/core/style.js b/html5/render/vue/core/style.js
index 0531a73..691849b 100644
--- a/html5/render/vue/core/style.js
+++ b/html5/render/vue/core/style.js
@@ -311,38 +311,3 @@ export function extractComponentStyle (context) {
   return getComponentStyle(context, true)
 }
 
-/**
- * process sticky children in scrollable components.
- * current only support list and vertical scroller.
- */
-export function processSticky (context) {
-  /**
-   * current browser support 'sticky' or '-webkit-sticky', so there's no need
-   * to do further more.
-   */
-  if (supportSticky()) {
-    return
-  }
-  // current only support list and vertical scroller.
-  if (context.scrollDirection === 'horizontal') {
-    return
-  }
-  const stickyChildren = context._stickyChildren
-  const len = stickyChildren && stickyChildren.length || 0
-  if (len <= 0) { return }
-
-  const container = context.$el
-  if (!container) { return }
-  const scrollTop = container.scrollTop
-
-  let stickyChild
-  for (let i = 0; i < len; i++) {
-    stickyChild = stickyChildren[i]
-    if (stickyChild._initOffsetTop < scrollTop) {
-      stickyChild._addSticky()
-    }
-    else {
-      stickyChild._removeSticky()
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/env/global.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/env/global.js b/html5/render/vue/env/global.js
index e872c4f..7d1a479 100644
--- a/html5/render/vue/env/global.js
+++ b/html5/render/vue/env/global.js
@@ -19,6 +19,8 @@
 import weex from './weex'
 import * as core from '../core'
 
+import { inputCommon } from '../mixins'
+
 window.global = window
 window.weex = weex
 
@@ -30,3 +32,7 @@ weex._styleMap = {}
   'trimTextVNodes'].forEach(function (method) {
     weex[method] = core[method].bind(weex)
   })
+
+weex.mixins = {
+  inputCommon
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/index.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/index.js b/html5/render/vue/index.js
index 5795c6b..8617f2f 100644
--- a/html5/render/vue/index.js
+++ b/html5/render/vue/index.js
@@ -46,9 +46,9 @@ function init (Vue/*, options = {}*/) {
   Vue.config.parsePlatformTagName = tag => tag.replace(htmlRegex, '')
 
   // register sdk components.
-  for (const name in components) {
-    weex.registerComponent(name, components[name])
-  }
+  components.forEach(function (comp) {
+    weex.install(comp)
+  })
 
   /* istanbul ignore next */
   // if (process.env.NODE_ENV === 'development') {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/mixins/base.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/mixins/base.js b/html5/render/vue/mixins/base.js
index ff31cd0..8fec215 100644
--- a/html5/render/vue/mixins/base.js
+++ b/html5/render/vue/mixins/base.js
@@ -121,12 +121,6 @@ export default {
   },
 
   methods: {
-    _renderHook () {
-      if (!window._first_screen_detected) {
-        window._component_count++
-      }
-    },
-
     _getScopeIds () {
       const arr = []
       let ctx = this

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/mixins/index.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/mixins/index.js b/html5/render/vue/mixins/index.js
index 7807b1a..e2d0ced 100644
--- a/html5/render/vue/mixins/index.js
+++ b/html5/render/vue/mixins/index.js
@@ -18,13 +18,11 @@
  */
 import base from './base'
 import style from './style'
-import scrollable from './scrollable'
 import inputCommon from './input-common'
 import sticky from './sticky'
 
 export {
   base,
-  scrollable,
   style,
   inputCommon,
   sticky

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/mixins/scrollable.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/mixins/scrollable.js b/html5/render/vue/mixins/scrollable.js
deleted file mode 100644
index 54c87dd..0000000
--- a/html5/render/vue/mixins/scrollable.js
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { getThrottleLazyload, throttle, getRangeWidth } from '../utils'
-import { processSticky } from '../core'
-
-const DEFAULT_OFFSET_ACCURACY = 10
-const DEFAULT_LOADMORE_OFFSET = 0
-
-function getThrottledScroll (context) {
-  const scale = weex.config.env.scale
-  if (!context._throttleScroll) {
-    const wrapper = context.$refs.wrapper
-    const inner = context.$refs.inner
-    let preOffset = (context.scrollDirection === 'horizontal'
-        ? wrapper.scrollLeft
-        : wrapper.scrollTop)
-      || 0
-    context._throttleScroll = throttle(function (evt) {
-      const offset = context.scrollDirection === 'horizontal'
-        ? wrapper.scrollLeft
-        : wrapper.scrollTop
-      const indent = parseInt(context.offsetAccuracy) * scale
-      function triggerScroll () {
-        const rect = inner.getBoundingClientRect()
-        evt.contentSize = { width: rect.width, height: rect.height }
-        evt.contentOffset = {
-          x: wrapper.scrollLeft,
-          /**
-           * positive direciton for y-axis is down.
-           * so should use negative operation on scrollTop.
-           *
-           *  (0,0)---------------> x
-           *       |
-           *       |
-           *       |
-           *       |
-           *       v y
-           *
-           */
-          y: -wrapper.scrollTop
-        }
-        context.$emit('scroll', evt)
-      }
-      if (Math.abs(offset - preOffset) >= indent) {
-        triggerScroll()
-        preOffset = offset
-      }
-    }, 16, true)
-  }
-  return context._throttleScroll
-}
-
-export default {
-  props: {
-    loadmoreoffset: {
-      type: [String, Number],
-      default: DEFAULT_LOADMORE_OFFSET,
-      validator (value) {
-        const val = parseInt(value)
-        return !isNaN(val) && val >= DEFAULT_LOADMORE_OFFSET
-      }
-    },
-
-    offsetAccuracy: {
-      type: [Number, String],
-      default: DEFAULT_OFFSET_ACCURACY,
-      validator (value) {
-        const val = parseInt(value)
-        return !isNaN(val) && val >= DEFAULT_OFFSET_ACCURACY
-      }
-    }
-  },
-
-  created () {
-    // should call resetLoadmore() to enable loadmore event.
-    this._loadmoreReset = true
-  },
-
-  methods: {
-    updateLayout () {
-      const wrapper = this.$refs.wrapper
-      if (wrapper) {
-        const rect = wrapper.getBoundingClientRect()
-        this._wrapperWidth = rect.width
-        this._wrapperHeight = rect.height
-      }
-      const inner = this.$refs.inner
-      const children = inner && inner.children
-      if (inner) {
-        const rect = inner.getBoundingClientRect()
-        this._innerWidth = rect.width
-        this._innerHeight = rect.height
-      }
-      const loadingEl = this._loading && this._loading.$el
-      const refreshEl = this._refresh && this._refresh.$el
-      if (loadingEl) {
-        this._innerHeight -= loadingEl.getBoundingClientRect().height
-      }
-      if (refreshEl) {
-        this._innerHeight -= refreshEl.getBoundingClientRect().height
-      }
-      // inner width is always the viewport width somehow in horizontal
-      // scoller, therefore the inner width should be reclaculated.
-      if (this.scrollDirection === 'horizontal' && children) {
-        this._innerWidth = getRangeWidth(inner)
-      }
-    },
-
-    resetLoadmore () {
-      this._loadmoreReset = true
-    },
-
-    handleScroll (event) {
-      getThrottleLazyload(25, this.$el, 'scroll')()
-      getThrottledScroll(this)(event)
-
-      processSticky(this)
-
-      // fire loadmore event.
-      const inner = this.$refs.inner
-      if (inner) {
-        const innerLength = this.scrollDirection === 'horizontal'
-          ? this._innerWidth
-          : this._innerHeight
-        if (!this._innerLength) {
-          this._innerLength = innerLength
-        }
-        if (this._innerLength !== innerLength) {
-          this._innerLength = innerLength
-          this._loadmoreReset = true
-        }
-        if (this._loadmoreReset && this.reachBottom(this.loadmoreoffset)) {
-          this._loadmoreReset = false
-          this.$emit('loadmore', event)
-        }
-      }
-    },
-
-    reachTop () {
-      const wrapper = this.$refs.wrapper
-      return (!!wrapper) && (wrapper.scrollTop <= 0)
-    },
-
-    reachBottom (offset) {
-      const wrapper = this.$refs.wrapper
-      const inner = this.$refs.inner
-      offset = parseInt(offset || 0) * weex.config.env.scale
-
-      if (wrapper && inner) {
-        const key = this.scrollDirection === 'horizontal'
-          ? 'width'
-          : 'height'
-        const innerLength = this[`_inner${key[0].toUpperCase()}${key.substr(1)}`]
-        const wrapperLength = this[`_wrapper${key[0].toUpperCase()}${key.substr(1)}`]
-        const scrollOffset = this.scrollDirection === 'horizontal'
-          ? wrapper.scrollLeft
-          : wrapper.scrollTop
-        return scrollOffset >= innerLength - wrapperLength - offset
-      }
-      return false
-    },
-
-    handleTouchStart (event) {
-      // event.preventDefault()
-      // event.stopPropagation()
-      if (this._loading || this._refresh) {
-        const touch = event.changedTouches[0]
-        this._touchParams = {
-          reachTop: this.reachTop(),
-          reachBottom: this.reachBottom(),
-          startTouchEvent: touch,
-          startX: touch.pageX,
-          startY: touch.pageY,
-          timeStamp: event.timeStamp
-        }
-      }
-    },
-
-    handleTouchMove (event) {
-      // event.preventDefault()
-      // event.stopPropagation()
-      if (this._touchParams) {
-        const inner = this.$refs.inner
-        const { startY, reachTop, reachBottom } = this._touchParams
-        if (inner) {
-          const touch = event.changedTouches[0]
-          const offsetY = touch.pageY - startY
-          this._touchParams.offsetY = offsetY
-          if (reachTop && this._refresh) {
-            this._refresh.pullingDown(offsetY)
-          }
-          else if (reachBottom && this._loading) {
-            this._loading.pullingUp(-offsetY)
-          }
-        }
-      }
-    },
-
-    handleTouchEnd (event) {
-      // event.preventDefault()
-      // event.stopPropagation()
-      if (this._touchParams) {
-        const inner = this.$refs.inner
-        const { reachTop, reachBottom } = this._touchParams
-        if (inner) {
-          if (reachTop && this._refresh) {
-            this._refresh.pullingEnd()
-          }
-          else if (reachBottom && this._loading) {
-            this._loading.pullingEnd()
-          }
-        }
-      }
-      delete this._touchParams
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b1a7c02a/html5/render/vue/styles/base.css
----------------------------------------------------------------------
diff --git a/html5/render/vue/styles/base.css b/html5/render/vue/styles/base.css
index a9a41ff..33cb37d 100644
--- a/html5/render/vue/styles/base.css
+++ b/html5/render/vue/styles/base.css
@@ -64,55 +64,6 @@
   min-width: 0;
 }
 
-body > .weex-list,
-body > .weex-scroller,
-body > .weex-waterfall {
-  max-height: 100%;
-}
-
-.weex-list-wrapper,
-.weex-scroller-wrapper,
-.weex-waterfall-wrapper {
-  -webkit-overflow-scrolling: touch;
-}
-
-.weex-list-wrapper,
-.weex-waterfall-wrapper {
-  overflow-y: scroll !important;
-  overflow-x: hidden !important;
-}
-
-.weex-list-inner,
-.weex-scroller-inner,
-.weex-waterfall-inner {
-  -webkit-overflow-scrolling: touch;
-}
-
-.weex-waterfall-inner-columns {
-  -webkit-flex-direction: row;
-      -ms-flex-direction: row;
-          flex-direction: row;
-  -webkit-box-orient: horizontal;
-}
-
-.weex-scroller-wrapper.weex-scroller-vertical {
-  overflow-x: hidden;
-  overflow-y: scroll;
-}
-
-.weex-scroller-wrapper.weex-scroller-horizontal {
-  overflow-x: scroll;
-  overflow-y: hidden;
-}
-
-.weex-scroller-horizontal .weex-scroller-inner {
-  -webkit-flex-direction: row;
-      -ms-flex-direction: row;
-          flex-direction: row;
-  -webkit-box-orient: horizontal;
-  height: 100%;
-}
-
 .weex-ios-sticky {
   position: -webkit-sticky !important;
   position: sticky !important;
@@ -130,21 +81,3 @@ body > .weex-waterfall {
   top: 0;
   z-index: 9999;
 }
-
-.weex-cell {
-  width: 100%;
-}
-
-.weex-refresh,
-.weex-loading {
-  -webkit-box-align: center;
-  -webkit-align-items: center;
-      -ms-flex-align: center;
-          align-items: center;
-  -webkit-box-pack: center;
-  -webkit-justify-content: center;
-      -ms-flex-pack: center;
-          justify-content: center;
-  width: 100%;
-  overflow: hidden;
-}