You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by fk...@apache.org on 2017/04/12 08:27:46 UTC

[03/17] incubator-weex git commit: * [html5] change viewport adapter, add unit tests for new adapting methods.

* [html5] change viewport adapter, add unit tests for new adapting methods.


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/38f1a971
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/38f1a971
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/38f1a971

Branch: refs/heads/0.11-dev
Commit: 38f1a971def5fcc0d471be36777f4719a6019dd1
Parents: 8309bf6
Author: MrRaindrop <te...@gmail.com>
Authored: Thu Apr 6 15:36:08 2017 +0800
Committer: MrRaindrop <te...@gmail.com>
Committed: Thu Apr 6 15:36:08 2017 +0800

----------------------------------------------------------------------
 .gitignore                                      |   2 +-
 build/karma.vue.conf.js                         |  11 +-
 build/webpack.examples.web.config.js            |  31 +-
 build/webpack.test.web.config.js                |  81 +++
 examples/vue/components/slider.vue              |   1 +
 examples/vue/hello.vue                          |  20 +-
 examples/vue/showcase/itemlist.vue              |  11 +-
 examples/vue/style/index.vue                    |   2 +-
 .../npm/karma-rollup-preprocessor_vx.x.x.js     |  53 ++
 flow-typed/npm/karma-sinon-chai_vx.x.x.js       |  38 ++
 html5/render/vue/components/a.js                |  13 +-
 html5/render/vue/components/div.js              |   4 +-
 html5/render/vue/components/image.js            |  13 +-
 html5/render/vue/components/input.js            |   4 +-
 .../render/vue/components/scrollable/header.js  |   4 +-
 .../vue/components/scrollable/list/cell.js      |   4 +-
 .../vue/components/scrollable/list/index.js     |   4 +-
 .../components/scrollable/loading-indicator.js  |   5 +-
 .../render/vue/components/scrollable/loading.js |   6 +-
 .../render/vue/components/scrollable/refresh.js |   6 +-
 .../vue/components/scrollable/scroller.js       |   6 +-
 html5/render/vue/components/slider/index.js     |   4 +-
 html5/render/vue/components/slider/indicator.js |  26 +-
 html5/render/vue/components/switch.js           |   6 +-
 html5/render/vue/components/text.js             |  10 +-
 html5/render/vue/components/textarea.js         |   4 +-
 html5/render/vue/components/video.js            |   4 +-
 html5/render/vue/components/web.js              |   4 +-
 html5/render/vue/core/index.js                  |   1 +
 html5/render/vue/core/style.js                  | 186 +++++++
 html5/render/vue/env/index.js                   |   4 +-
 html5/render/vue/env/viewport.js                | 162 ++++--
 html5/render/vue/env/weex.js                    |   2 +-
 html5/render/vue/env/wx-env.js                  |  80 +--
 html5/render/vue/mixins/base.js                 |  13 -
 html5/render/vue/mixins/style.js                |  14 +
 html5/render/vue/styles/base.css                | 513 ++++++++++++++++++
 html5/render/vue/styles/components.css          | 513 ------------------
 html5/render/vue/utils/style.js                 | 110 ++++
 html5/test/render/vue/components/image.js       |   4 +-
 html5/test/render/vue/core/scope-style-map.js   |  16 +
 html5/test/render/vue/core/style.js             |  59 +++
 .../vue/data/build/dotvue/scoped-style.js       | 525 +++++++++++++++++++
 html5/test/render/vue/data/css/head1.css        |  38 ++
 html5/test/render/vue/data/css/head10.css       |  14 +
 html5/test/render/vue/data/css/head11.css       |   2 +
 html5/test/render/vue/data/css/head12.css       |   2 +
 html5/test/render/vue/data/css/head2.css        |  11 +
 html5/test/render/vue/data/css/head3.css        |  25 +
 html5/test/render/vue/data/css/head4.css        |  56 ++
 html5/test/render/vue/data/css/head5.css        | 153 ++++++
 html5/test/render/vue/data/css/head6.css        |   4 +
 html5/test/render/vue/data/css/head7.css        |  61 +++
 html5/test/render/vue/data/css/head8.css        | 507 ++++++++++++++++++
 html5/test/render/vue/data/css/head9.css        | 173 ++++++
 .../render/vue/data/dotvue/scoped-style.vue     |  13 +
 html5/test/render/vue/data/head-css.js          |  12 +
 html5/test/render/vue/data/head-map.js          | 247 +++++++++
 html5/test/render/vue/helper.js                 | 140 -----
 html5/test/render/vue/helper/env.js             |  20 +
 html5/test/render/vue/helper/index.js           | 113 ++++
 html5/test/render/vue/helper/runtime.js         |  80 +++
 html5/test/render/vue/helper/utils.js           |   8 +
 html5/test/render/vue/utils.js                  |  47 --
 html5/test/render/vue/utils/func.js             |  50 ++
 html5/test/render/vue/utils/style.js            |  68 +++
 package.json                                    |   2 +-
 vue.html                                        |   9 +-
 68 files changed, 3572 insertions(+), 862 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index dc96cc2..50e9ce3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,7 @@
 
 # Created by Builder
 examples/build
-examples/web-entry
+web-entry
 test/build
 weex_tmp
 coverage

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/build/karma.vue.conf.js
----------------------------------------------------------------------
diff --git a/build/karma.vue.conf.js b/build/karma.vue.conf.js
index 50c22fd..c78b10a 100644
--- a/build/karma.vue.conf.js
+++ b/build/karma.vue.conf.js
@@ -44,16 +44,19 @@ module.exports = function (config) {
     frameworks: ['mocha', 'sinon-chai'],
     browsers: ['PhantomJS'],
     files: [
+      // '../html5/test/render/vue/components/*.js'
       '../html5/test/render/vue/**/*.js'
     ],
 
     exclude: [
       '../html5/test/render/vue/helper.js',
-      '../html5/test/render/vue/vender/**/*.js'
+      '../html5/test/render/vue/helper/*.js',
+      '../html5/test/render/vue/vender/**/*.js',
+      '../html5/test/render/vue/data/**/*.js'
     ],
 
-    // singleRun: false,
-    singleRun: true,
+    singleRun: false,
+    // singleRun: true,
 
     reporters: ['mocha', 'coverage'],
     coverageReporter: {
@@ -65,7 +68,7 @@ module.exports = function (config) {
 
     preprocessors: {
       '../html5/test/**/*.js': ['rollup'],
-      '../html5/test/**/!(components|examples)/*.js': ['rollup', 'coverage']
+      '../html5/test/**/!(components|examples|core)/*.js': ['rollup', 'coverage']
     },
     rollupPreprocessor: rollupConfig,
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/build/webpack.examples.web.config.js
----------------------------------------------------------------------
diff --git a/build/webpack.examples.web.config.js b/build/webpack.examples.web.config.js
index 5aa04c7..fdf2f6f 100644
--- a/build/webpack.examples.web.config.js
+++ b/build/webpack.examples.web.config.js
@@ -48,7 +48,6 @@ var bannerPlugin = new webpack.BannerPlugin(banner, {
   exclude: bannerExcludeFiles
 })
 
-
 module.exports = {
   entry: entry,
   output: {
@@ -67,20 +66,20 @@ module.exports = {
       }
     ]
   },
-  vue: {
-    /**
-     * important! should use postTransformNode to add $processStyle for
-     * inline style prefixing.
-     */
-    compilerModules: [
-      {
-        postTransformNode: el => {
-          el.staticStyle = `$processStyle(${el.staticStyle})`
-          el.styleBinding = `$processStyle(${el.styleBinding})`
-        }
-      }
-    ],
-    postcss: [require('autoprefixer')()]
-  },
+  // vue: {
+  //   /**
+  //    * important! should use postTransformNode to add $processStyle for
+  //    * inline style prefixing.
+  //    */
+  //   compilerModules: [
+  //     {
+  //       postTransformNode: el => {
+  //         el.staticStyle = `$processStyle(${el.staticStyle})`
+  //         el.styleBinding = `$processStyle(${el.styleBinding})`
+  //       }
+  //     }
+  //   ],
+  //   postcss: [require('autoprefixer')()]
+  // },
   plugins: [bannerPlugin]
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/build/webpack.test.web.config.js
----------------------------------------------------------------------
diff --git a/build/webpack.test.web.config.js b/build/webpack.test.web.config.js
new file mode 100644
index 0000000..6b55480
--- /dev/null
+++ b/build/webpack.test.web.config.js
@@ -0,0 +1,81 @@
+var path = require('path');
+var fs = require('fs-extra');
+var webpack = require('webpack');
+
+var entry = {};
+// var bannerExcludeFiles = [];
+var webSrcDirectory = path.join(__dirname, '../html5/test/render/vue/data/dotvue');
+
+// function getEntryFileContent (entryPath, vueFilePath) {
+//   const relativePath = path.relative(path.join(entryPath, '../'), vueFilePath);
+//   return 'var App = require(\'' + relativePath + '\')\n'
+//     + 'App.el = \'#root\'\n'
+//     + 'new Vue(App)\n'
+// }
+
+function walk(dir) {
+  dir = dir || '.';
+  var directory = path.join(__dirname, '../html5/test/render/vue/data', dir);
+  var entryDirectory = path.join(webSrcDirectory, dir);
+  fs.readdirSync(directory)
+    .forEach(function(file) {
+      var fullpath = path.join(directory, file);
+      var stat = fs.statSync(fullpath);
+      var extname = path.extname(fullpath);
+      if (stat.isFile() && extname === '.vue') {
+        // var entryFile = path.join(entryDirectory, path.basename(file, extname) + '.js');
+        // fs.outputFileSync(entryFile, getEntryFileContent(entryFile, fullpath));
+        var name = path.join('html5/test/render/vue/data', 'build', dir, path.basename(file, extname));
+        entry[name] = fullpath
+      } else if (stat.isDirectory() && file !== 'build' && file !== 'include') {
+        var subdir = path.join(dir, file);
+        walk(subdir);
+      }
+    });
+}
+
+walk();
+
+// var banner = '// NOTE: for vue2.0 and platform:web only.\n'
+// var bannerPlugin = new webpack.BannerPlugin({
+//   banner,
+//   raw: true,
+//   exclude: bannerExcludeFiles
+// })
+
+module.exports = {
+  entry: entry,
+  output: {
+    path: path.resolve(__dirname, '../'),
+    libraryTarget: 'umd',
+    filename: '[name].js'
+  },
+  module: {
+    loaders: [
+      {
+        test: /\.js$/,
+        loaders: ['babel-loader'],
+        exclude: /node_modules/
+      }, {
+        test: /\.vue(\?[^?]+)?$/,
+        loaders: ['vue-loader']
+      }
+    ]
+  },
+  // vue: {
+    /**
+     * important! should use postTransformNode to add $processStyle for
+     * inline style prefixing.
+     */
+    // compilerModules: [
+    //   {
+    //     postTransformNode: el => {
+    //       el.staticStyle = `$processStyle(${el.staticStyle})`
+    //       el.styleBinding = `$processStyle(${el.styleBinding})`
+    //     }
+    //   }
+    // ],
+    // postcss: [require('autoprefixer')()]
+  // }
+  // plugins: [bannerPlugin]
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/examples/vue/components/slider.vue
----------------------------------------------------------------------
diff --git a/examples/vue/components/slider.vue b/examples/vue/components/slider.vue
index 5985b68..fac0d26 100644
--- a/examples/vue/components/slider.vue
+++ b/examples/vue/components/slider.vue
@@ -18,6 +18,7 @@
         </slider>
       </panel>
     </panel>
+    <panel style="height:1000px;"></panel>
     <panel :title="'Event, ' + eventCnt + ' change'" type="primary">
       <slider class="slider" append="tree"
         :interval="sliders[0].interval"

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/examples/vue/hello.vue
----------------------------------------------------------------------
diff --git a/examples/vue/hello.vue b/examples/vue/hello.vue
index 462ccd9..0004900 100644
--- a/examples/vue/hello.vue
+++ b/examples/vue/hello.vue
@@ -1,5 +1,23 @@
 <template>
   <div>
-    <text style="font-size: 100px;">Hello World.</text>
+    <div ref="foo" :style="{height: '200px'}" class="ct"></div>
   </div>
 </template>
+
+<style scoped>
+.ct {
+  width: 200px;
+  flex: 1;
+  flex-direction: row;
+  transform: translate3d(100px, 100px, 0);
+  background-color: red;
+}
+</style>
+
+<script>
+  module.exports = {
+    mounted () {
+      console.log(this.$refs.foo.$el)
+    }
+  }
+</script>

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/examples/vue/showcase/itemlist.vue
----------------------------------------------------------------------
diff --git a/examples/vue/showcase/itemlist.vue b/examples/vue/showcase/itemlist.vue
index eced86e..02fb33a 100644
--- a/examples/vue/showcase/itemlist.vue
+++ b/examples/vue/showcase/itemlist.vue
@@ -1,11 +1,11 @@
 <template>
   <list class="list" @loadmore="loadmore" loadmoreoffset=2000>
-    <cell class="cell" v-for="(item,i) in shopList" :key="i" :scope="item.scopeValue" @click="oncellclick(item.id)">
+    <cell class="cell" v-for="item in shopList" :scope="item.scopeValue" @click="oncellclick(item.id)">
       <div class="shopDiv">
         <div class="shopHeader" style="flex-direction:row;">
           <div style="flex:2;flex-direction:row;">
             <div>
-              <image style="width:60px;height:60px;" :src="item.PersonPhoto"></image>
+              <image class="test" :src="item.PersonPhoto"></image>
             </div>
             <div style="flex-direction:column;margin-left:5px;">
               <div style="margin-top:5px;">
@@ -78,7 +78,7 @@
             <text class="shopDesc" style="font-size:25px;">{{item.shopDesc}}</text>
           </div>
           <div style="flex-direction:row;">
-            <div class="imgDiv" style="flex:1;flex-direction:column;margin:10px;" v-for="img in item.shopImgList">
+            <div class="imgDiv" style="flex:1;height:300px;flex-direction:column;margin:10px;" v-for="img in item.shopImgList">
               <div>
                 <image class="shopImg" :style="{ width: img.shopImgWidth, height: img.shopImgHeight }" :src="img.shopImg"></image>
               </div>
@@ -180,6 +180,11 @@
     width: 750px;
   }
 
+  .test {
+    width:60px;
+    height:60px;
+  }
+
   .shopDiv {
     flex-direction: column;
     background-color: #ffffff;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/examples/vue/style/index.vue
----------------------------------------------------------------------
diff --git a/examples/vue/style/index.vue b/examples/vue/style/index.vue
index 99ce7bc..abee8e7 100644
--- a/examples/vue/style/index.vue
+++ b/examples/vue/style/index.vue
@@ -1,5 +1,5 @@
 <template>
-  <scroller>
+  <scroller style="overflow-x:hidden;">
     <style-box></style-box>
     <style-flex></style-flex>
     <panel title="opacity" type="primary">

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/flow-typed/npm/karma-rollup-preprocessor_vx.x.x.js
----------------------------------------------------------------------
diff --git a/flow-typed/npm/karma-rollup-preprocessor_vx.x.x.js b/flow-typed/npm/karma-rollup-preprocessor_vx.x.x.js
new file mode 100644
index 0000000..3dc7ce2
--- /dev/null
+++ b/flow-typed/npm/karma-rollup-preprocessor_vx.x.x.js
@@ -0,0 +1,53 @@
+// flow-typed signature: 9b5b1885bf45d4adf8ce0d3ca9ab51b1
+// flow-typed version: <<STUB>>/karma-rollup-preprocessor_v^3.0.3/flow_v0.42.0
+
+/**
+ * This is an autogenerated libdef stub for:
+ *
+ *   'karma-rollup-preprocessor'
+ *
+ * Fill this stub out by replacing all the `any` types.
+ *
+ * Once filled out, we encourage you to share your work with the 
+ * community by sending a pull request to: 
+ * https://github.com/flowtype/flow-typed
+ */
+
+declare module 'karma-rollup-preprocessor' {
+  declare module.exports: any;
+}
+
+/**
+ * We include stubs for each file inside this npm package in case you need to
+ * require those files directly. Feel free to delete any files that aren't
+ * needed.
+ */
+declare module 'karma-rollup-preprocessor/karma.conf' {
+  declare module.exports: any;
+}
+
+declare module 'karma-rollup-preprocessor/lib/index' {
+  declare module.exports: any;
+}
+
+declare module 'karma-rollup-preprocessor/test/helper' {
+  declare module.exports: any;
+}
+
+declare module 'karma-rollup-preprocessor/test/main' {
+  declare module.exports: any;
+}
+
+// Filename aliases
+declare module 'karma-rollup-preprocessor/karma.conf.js' {
+  declare module.exports: $Exports<'karma-rollup-preprocessor/karma.conf'>;
+}
+declare module 'karma-rollup-preprocessor/lib/index.js' {
+  declare module.exports: $Exports<'karma-rollup-preprocessor/lib/index'>;
+}
+declare module 'karma-rollup-preprocessor/test/helper.js' {
+  declare module.exports: $Exports<'karma-rollup-preprocessor/test/helper'>;
+}
+declare module 'karma-rollup-preprocessor/test/main.js' {
+  declare module.exports: $Exports<'karma-rollup-preprocessor/test/main'>;
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/flow-typed/npm/karma-sinon-chai_vx.x.x.js
----------------------------------------------------------------------
diff --git a/flow-typed/npm/karma-sinon-chai_vx.x.x.js b/flow-typed/npm/karma-sinon-chai_vx.x.x.js
new file mode 100644
index 0000000..9c0219e
--- /dev/null
+++ b/flow-typed/npm/karma-sinon-chai_vx.x.x.js
@@ -0,0 +1,38 @@
+// flow-typed signature: 0953d9baac8251cc38f40d1011955980
+// flow-typed version: <<STUB>>/karma-sinon-chai_v^1.2.4/flow_v0.42.0
+
+/**
+ * This is an autogenerated libdef stub for:
+ *
+ *   'karma-sinon-chai'
+ *
+ * Fill this stub out by replacing all the `any` types.
+ *
+ * Once filled out, we encourage you to share your work with the 
+ * community by sending a pull request to: 
+ * https://github.com/flowtype/flow-typed
+ */
+
+declare module 'karma-sinon-chai' {
+  declare module.exports: any;
+}
+
+/**
+ * We include stubs for each file inside this npm package in case you need to
+ * require those files directly. Feel free to delete any files that aren't
+ * needed.
+ */
+declare module 'karma-sinon-chai/chai-adapter' {
+  declare module.exports: any;
+}
+
+// Filename aliases
+declare module 'karma-sinon-chai/chai-adapter.js' {
+  declare module.exports: $Exports<'karma-sinon-chai/chai-adapter'>;
+}
+declare module 'karma-sinon-chai/index' {
+  declare module.exports: $Exports<'karma-sinon-chai'>;
+}
+declare module 'karma-sinon-chai/index.js' {
+  declare module.exports: $Exports<'karma-sinon-chai'>;
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/a.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/a.js b/html5/render/vue/components/a.js
index aa973fd..f0a28e5 100644
--- a/html5/render/vue/components/a.js
+++ b/html5/render/vue/components/a.js
@@ -1,5 +1,12 @@
+import { extractComponentStyle } from '../core'
 // import { validateStyles } from '../validator'
 
+const defaultStyle = `
+.weex-a {
+  text-decoration: none;
+}
+`
+
 export default {
   name: 'weex-a',
   props: {
@@ -16,7 +23,9 @@ export default {
         href: this.href
       },
       on: this._createEventMap(),
-      staticClass: 'weex-a weex-ct'
+      staticClass: 'weex-a weex-ct',
+      staticStyle: extractComponentStyle(this)
     }, this._trimTextNodeChildren(this.$slots.default))
-  }
+  },
+  _d_style: defaultStyle
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/div.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/div.js b/html5/render/vue/components/div.js
index 033ba9d..fd8ed3c 100644
--- a/html5/render/vue/components/div.js
+++ b/html5/render/vue/components/div.js
@@ -1,4 +1,5 @@
 // import { validateStyles } from '../validator'
+import { extractComponentStyle } from '../core'
 
 export default {
   name: 'weex-div',
@@ -10,7 +11,8 @@ export default {
     return createElement('html:div', {
       attrs: { 'weex-type': 'div' },
       on: this._createEventMap(),
-      staticClass: 'weex-div weex-ct'
+      staticClass: 'weex-div weex-ct',
+      staticStyle: extractComponentStyle(this)
     }, this._trimTextNodeChildren(this.$slots.default))
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/image.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/image.js b/html5/render/vue/components/image.js
index 5f4a786..f4980d6 100644
--- a/html5/render/vue/components/image.js
+++ b/html5/render/vue/components/image.js
@@ -1,8 +1,10 @@
+import { extractComponentStyle } from '../core/style'
+import { extend } from '../utils'
 /**
  * get resize (stetch|cover|contain) related styles.
  */
 function getResizeStyle (context) {
-  const stretch = '100%'
+  const stretch = '100% 100%'
   const resize = context.resize || stretch
   const bgSize = ['cover', 'contain', stretch].indexOf(resize) > -1 ? resize : stretch
   // compatibility: http://caniuse.com/#search=background-size
@@ -49,16 +51,17 @@ export default {
     //   validateStyles('image', this.$vnode.data && this.$vnode.data.staticStyle)
     // }
     // const style = this._normalizeInlineStyles(this.$vnode.data)
-    const wh = this._getSize(this.$vnode.data)
+    const resizeStyle = getResizeStyle(this)
+    const style = extractComponentStyle(this)
     return createElement('figure', {
       attrs: {
         'weex-type': 'image',
-        'img-src': preProcessSrc(this, this.src, wh),
-        'img-placeholder': preProcessSrc(this, this.placeholder, wh)
+        'img-src': preProcessSrc(this, this.src, style),
+        'img-placeholder': preProcessSrc(this, this.placeholder, style)
       },
       on: this._createEventMap(['load', 'error']),
       staticClass: 'weex-image weex-el',
-      staticStyle: getResizeStyle(this)
+      staticStyle: extend(style, resizeStyle)
     })
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/input.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/input.js b/html5/render/vue/components/input.js
index 22a600c..d65ce79 100644
--- a/html5/render/vue/components/input.js
+++ b/html5/render/vue/components/input.js
@@ -2,6 +2,7 @@
  * @fileOverview Input component.
  * Support v-model only if vue version is large than 2.2.0
  */
+import { extractComponentStyle } from '../core'
 import { inputCommon } from '../mixins'
 import { extend, mapFormEvents } from '../utils'
 // import { validateStyles } from '../validator'
@@ -56,7 +57,8 @@ export default {
         value: this.value
       },
       on: this.createKeyboardEvent(events),
-      staticClass: 'weex-input weex-el'
+      staticClass: 'weex-input weex-el',
+      staticStyle: extractComponentStyle(this)
     })
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/scrollable/header.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/scrollable/header.js b/html5/render/vue/components/scrollable/header.js
index f8d206c..64ebd77 100644
--- a/html5/render/vue/components/scrollable/header.js
+++ b/html5/render/vue/components/scrollable/header.js
@@ -1,5 +1,6 @@
 // import { validateStyles } from '../../validator'
 import { supportSticky } from '../../utils/style'
+import { extractComponentStyle } from '../../core'
 
 export default {
   data () {
@@ -51,7 +52,8 @@ export default {
       on: this._createEventMap(),
       ref: 'header',
       staticClass: 'weex-header weex-ct',
-      class: { sticky: this.sticky, iossticky: this.supportSticky }
+      class: { sticky: this.sticky, iossticky: this.supportSticky },
+      staticStyle: extractComponentStyle(this)
     }, this.$slots.default)
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/scrollable/list/cell.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/scrollable/list/cell.js b/html5/render/vue/components/scrollable/list/cell.js
index 3650aec..32ec1f9 100644
--- a/html5/render/vue/components/scrollable/list/cell.js
+++ b/html5/render/vue/components/scrollable/list/cell.js
@@ -1,4 +1,5 @@
 // import { validateStyles } from '../../../validator'
+import { extractComponentStyle } from '../../../core'
 
 export default {
   render (createElement) {
@@ -9,7 +10,8 @@ export default {
     return createElement('section', {
       attrs: { 'weex-type': 'cell' },
       on: this._createEventMap(),
-      staticClass: 'weex-cell weex-ct'
+      staticClass: 'weex-cell weex-ct',
+      staticStyle: extractComponentStyle(this)
     }, this.$slots.default)
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/scrollable/list/index.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/scrollable/list/index.js b/html5/render/vue/components/scrollable/list/index.js
index f48a6c8..2db5239 100644
--- a/html5/render/vue/components/scrollable/list/index.js
+++ b/html5/render/vue/components/scrollable/list/index.js
@@ -1,3 +1,4 @@
+import { extractComponentStyle } from '../../../core'
 import { scrollable } from '../../../mixins'
 // import { validateStyles } from '../../../validator'
 import { extend } from '../../../utils'
@@ -61,7 +62,8 @@ export default {
         touchstart: this.handleTouchStart,
         touchmove: this.handleTouchMove,
         touchend: this.handleTouchEnd
-      })
+      }),
+      staticStyle: extractComponentStyle(this)
     }, this.createChildren(createElement))
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/scrollable/loading-indicator.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/scrollable/loading-indicator.js b/html5/render/vue/components/scrollable/loading-indicator.js
index 28ee909..e1f9854 100644
--- a/html5/render/vue/components/scrollable/loading-indicator.js
+++ b/html5/render/vue/components/scrollable/loading-indicator.js
@@ -1,9 +1,12 @@
+import { extractComponentStyle } from '../../core'
+
 export default {
   render (createElement) {
     this.weexType = 'loading-indicator'
     return createElement('mark', {
       attrs: { 'weex-type': 'loading-indicator' },
-      staticClass: 'weex-loading-indicator weex-ct'
+      staticClass: 'weex-loading-indicator weex-ct',
+      staticStyle: extractComponentStyle(this)
     })
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/scrollable/loading.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/scrollable/loading.js b/html5/render/vue/components/scrollable/loading.js
index ebf99d3..8f01fde 100644
--- a/html5/render/vue/components/scrollable/loading.js
+++ b/html5/render/vue/components/scrollable/loading.js
@@ -1,3 +1,4 @@
+import { extractComponentStyle } from '../../core'
 import LoadingIndicator from './loading-indicator'
 
 export default {
@@ -30,7 +31,7 @@ export default {
   },
   watch: {
     height (val) {
-      this.$el.style.height = val + 'px'
+      this.$el.style.height = val * weex.config.env.scale + 'px'
     },
     display (val) {
       if (val === 'hide') {
@@ -75,7 +76,8 @@ export default {
     return createElement('aside', {
       ref: 'loading',
       attrs: { 'weex-type': 'loading' },
-      staticClass: 'weex-loading weex-ct'
+      staticClass: 'weex-loading weex-ct',
+      staticStyle: extractComponentStyle(this)
     }, this.getChildren())
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/scrollable/refresh.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/scrollable/refresh.js b/html5/render/vue/components/scrollable/refresh.js
index 884f2ee..1d941d4 100644
--- a/html5/render/vue/components/scrollable/refresh.js
+++ b/html5/render/vue/components/scrollable/refresh.js
@@ -1,3 +1,4 @@
+import { extractComponentStyle } from '../../core'
 import LoadingIndicator from './loading-indicator'
 import { createEvent } from '../../utils'
 
@@ -32,7 +33,7 @@ export default {
   },
   watch: {
     height (val) {
-      this.$el.style.height = val + 'px'
+      this.$el.style.height = val * weex.config.env.scale + 'px'
     },
     display (val) {
       if (val === 'hide') {
@@ -83,7 +84,8 @@ export default {
     return createElement('aside', {
       ref: 'refresh',
       attrs: { 'weex-type': 'refresh' },
-      staticClass: 'weex-refresh weex-ct'
+      staticClass: 'weex-refresh weex-ct',
+      staticStyle: extractComponentStyle(this)
     }, this.getChildren())
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/scrollable/scroller.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/scrollable/scroller.js b/html5/render/vue/components/scrollable/scroller.js
index 1636270..ee117e2 100644
--- a/html5/render/vue/components/scrollable/scroller.js
+++ b/html5/render/vue/components/scrollable/scroller.js
@@ -1,3 +1,4 @@
+import { extractComponentStyle } from '../../core'
 import { scrollable } from '../../mixins'
 // import { validateStyles } from '../../validator'
 import { extend } from '../../utils'
@@ -75,13 +76,14 @@ export default {
     return createElement('main', {
       ref: 'wrapper',
       attrs: { 'weex-type': 'scroller' },
-      staticClass: this.wrapperClass,
       on: extend(this._createEventMap(), {
         scroll: this.handleScroll,
         touchstart: this.handleTouchStart,
         touchmove: this.handleTouchMove,
         touchend: this.handleTouchEnd
-      })
+      }),
+      staticClass: this.wrapperClass,
+      staticStyle: extractComponentStyle(this)
     }, this.createChildren(createElement))
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/slider/index.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/slider/index.js b/html5/render/vue/components/slider/index.js
index cb82b86..b2f4a90 100644
--- a/html5/render/vue/components/slider/index.js
+++ b/html5/render/vue/components/slider/index.js
@@ -1,4 +1,5 @@
 // import { validateStyles } from '../../validator'
+import { extractComponentStyle } from '../../core'
 import { throttle, bind, extend, fireLazyload } from '../../utils'
 import indicator from './indicator'
 import slideMixin from './slideMixin'
@@ -127,7 +128,8 @@ export default {
           touchstart: this.handleTouchStart,
           touchmove: throttle(bind(this.handleTouchMove, this), 25),
           touchend: this.handleTouchEnd
-        })
+        }),
+        staticStyle: extractComponentStyle(this)
       },
       [
         createElement('ul', {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/slider/indicator.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/slider/indicator.js b/html5/render/vue/components/slider/indicator.js
index 65d3700..3340cfd 100644
--- a/html5/render/vue/components/slider/indicator.js
+++ b/html5/render/vue/components/slider/indicator.js
@@ -1,21 +1,23 @@
+import { extractComponentStyle } from '../../core'
 import { extend, extendKeys } from '../../utils'
 
 function getIndicatorItemStyle (spec, isActive) {
   const style = {}
-  style['background-color'] = spec[isActive ? 'item-selected-color' : 'item-color']
-  style['width'] = style['height'] = spec['item-size']
+  style['background-color'] = spec[isActive ? 'itemSelectedColor' : 'itemColor']
+  style['width'] = style['height'] = spec['itemSize']
   return style
 }
 
 function _render (context, h) {
   const children = []
-  const mergedStyle = context._getComponentStyle(context.$vnode.data)
-  context.$vnode.data.cached = {}
-  extendKeys(context.$vnode.data.cached, mergedStyle, ['width', 'height'])
+  const mergedStyle = extractComponentStyle(context)
+  // const mergedStyle = context._getComponentStyle(context.$vnode.data)
+  // context.$vnode.data.cached = {}
+  // extendKeys(context.$vnode.data.cached, mergedStyle, ['width', 'height'])
   const indicatorSpecStyle = extendKeys(
       {},
       mergedStyle,
-      ['item-color', 'item-selected-color', 'item-size']
+      ['itemColor', 'itemSelectedColor', 'itemSize']
     )
   for (let i = 0; i < Number(context.count); ++i) {
     const classNames = ['weex-indicator-item weex-el']
@@ -29,11 +31,9 @@ function _render (context, h) {
       staticStyle: getIndicatorItemStyle(indicatorSpecStyle, isActive)
     }))
   }
-  if (!context.$vnode.context._isMounted) {
-    context.$nextTick(function () {
-      _reLayout(this, _getVirtualRect(this, mergedStyle), _getLtbr(this, mergedStyle))
-    })
-  }
+  context.$nextTick(function () {
+    _reLayout(this, _getVirtualRect(this, mergedStyle), _getLtbr(this, mergedStyle))
+  })
   return h('nav', {
     attrs: { 'weex-type': 'indicator' },
     staticClass: 'weex-indicator weex-ct',
@@ -117,10 +117,6 @@ export default {
     count: [Number, String],
     active: [Number, String]
   },
-  updated () {
-    const mergedStyle = this._getComponentStyle(this.$vnode.data)
-    _reLayout(this, _getVirtualRect(this, mergedStyle), _getLtbr(this, mergedStyle))
-  },
   render (createElement) {
     return _render(this, createElement)
   }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/switch.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/switch.js b/html5/render/vue/components/switch.js
index 63ff8f9..b04bf90 100644
--- a/html5/render/vue/components/switch.js
+++ b/html5/render/vue/components/switch.js
@@ -1,4 +1,5 @@
 // import { validateStyles } from '../validator'
+import { extractComponentStyle } from '../core'
 
 export default {
   props: {
@@ -42,13 +43,14 @@ export default {
     // }
     return createElement('span', {
       attrs: { 'weex-type': 'switch' },
-      staticClass: this.wrapperClass,
       on: {
         click: event => {
           this.$emit('click', event)
           this.toggle()
         }
-      }
+      },
+      staticClass: this.wrapperClass,
+      staticStyle: extractComponentStyle(this)
     }, [createElement('small', { staticClass: 'weex-switch-inner' })])
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/text.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/text.js b/html5/render/vue/components/text.js
index 3d8a129..5ecdffa 100644
--- a/html5/render/vue/components/text.js
+++ b/html5/render/vue/components/text.js
@@ -6,10 +6,13 @@
  * be clipped according to the 'lines'. Otherwise, it'll be the 'height'.
  */
 
+import { extractComponentStyle } from '../core'
+import { extend } from '../utils'
+
 /**
  * Get text special styles (lines and text-overflow).
  */
-function getTextSpecStyle (context = {}, ms = {}) {
+function getTextSpecStyle (ms = {}) {
   const lines = parseInt(ms.lines) || 0
   const overflow = ms['text-overflow'] || 'ellipsis'
   if (lines > 0) {
@@ -32,12 +35,13 @@ export default {
     // if (process.env.NODE_ENV === 'development') {
     //   validateStyles('text', this.$vnode.data && this.$vnode.data.staticStyle)
     // }
-    const ms = this._getComponentStyle(this.$vnode.data)
+    const style = extractComponentStyle(this)
+    const textSpecStyle = getTextSpecStyle(style)
     return createElement('p', {
       attrs: { 'weex-type': 'text' },
       on: this._createEventMap(),
       staticClass: 'weex-text weex-el',
-      staticStyle: getTextSpecStyle(this, ms)
+      staticStyle: extend(style, textSpecStyle)
     }, this.$slots.default || [this.value])
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/textarea.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/textarea.js b/html5/render/vue/components/textarea.js
index c419642..d170051 100644
--- a/html5/render/vue/components/textarea.js
+++ b/html5/render/vue/components/textarea.js
@@ -1,3 +1,4 @@
+import { extractComponentStyle } from '../core'
 import { inputCommon } from '../mixins'
 import { extend, mapFormEvents } from '../utils'
 // import { validateStyles } from '../validator'
@@ -42,7 +43,8 @@ export default {
         value: this.value
       },
       on: this.createKeyboardEvent(events),
-      staticClass: 'weex-textarea weex-el'
+      staticClass: 'weex-textarea weex-el',
+      staticStyle: extractComponentStyle(this)
     })
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/video.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/video.js b/html5/render/vue/components/video.js
index a256aad..5d8c312 100644
--- a/html5/render/vue/components/video.js
+++ b/html5/render/vue/components/video.js
@@ -1,4 +1,5 @@
 // import { validateStyles } from '../validator'
+import { extractComponentStyle } from '../core'
 
 export default {
   props: {
@@ -46,7 +47,8 @@ export default {
         src: this.src
       },
       on: this._createEventMap(['start', 'pause', 'finish', 'fail']),
-      staticClass: 'weex-video weex-el'
+      staticClass: 'weex-video weex-el',
+      staticStyle: extractComponentStyle(this)
     })
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/components/web.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/components/web.js b/html5/render/vue/components/web.js
index 06da79a..cccda37 100644
--- a/html5/render/vue/components/web.js
+++ b/html5/render/vue/components/web.js
@@ -1,3 +1,4 @@
+import { extractComponentStyle } from '../core'
 import { createEvent } from '../utils'
 // import { validateStyles } from '../validator'
 
@@ -45,7 +46,8 @@ export default {
         src: this.src
       },
       on: this._createEventMap(['error']),
-      staticClass: 'weex-web weex-el'
+      staticClass: 'weex-web weex-el',
+      staticStyle: extractComponentStyle(this)
     })
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/core/index.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/core/index.js b/html5/render/vue/core/index.js
new file mode 100644
index 0000000..57fe34e
--- /dev/null
+++ b/html5/render/vue/core/index.js
@@ -0,0 +1 @@
+export * from './style'

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/core/style.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/core/style.js b/html5/render/vue/core/style.js
new file mode 100644
index 0000000..0f3a814
--- /dev/null
+++ b/html5/render/vue/core/style.js
@@ -0,0 +1,186 @@
+import {
+  camelizeKeys,
+  // hyphenateKeys,
+  extend,
+  trimComment,
+  normalizeStyle
+} from '../utils'
+import { tagBegin, tagEnd } from '../utils/perf'
+/* istanbul ignore next */
+import addPrefix from 'inline-style-prefixer/static'
+
+/**
+ * get scoped class style map from stylesheets in <head>.
+ */
+export function getHeadStyleMap () {
+  if (process.env.NODE_ENV === 'development') {
+    tagBegin('getHeadStyleMap')
+  }
+  const res = Array.from(document.styleSheets || [])
+    .reduce((pre, styleSheet) => {
+      // why not using styleSheet.rules || styleSheet.cssRules to get css rules ?
+      // because weex's components defined non-standard style attributes, which is
+      // auto ignored when access rule.cssText.
+      const strArr = trimComment(styleSheet.ownerNode.textContent.trim()).split(/}/)
+      const len = strArr.length
+      const rules = []
+      for (let i = 0; i < len; i++) {
+        const str = strArr[i]
+        if (!str || str.match(/^\s*$/)) {
+          continue
+        }
+        /**
+         * should match these cases:
+         * .a[data-v-xxx] { color: red }
+         * .a[data-v-xxx], .b[data-v-xxx] { color: red; }
+         *
+         * should not match these cases:
+         * .a { color: red; }
+         * etc.
+         */
+        const match = str.match(/((?:,?\s*\.[\w-]+\[data-v-\w+\])+)\s*({[^}]+)/)
+        if (!match) {
+          // not the vue static class styles map. so acquire no rules for this styleSheet.
+          // just jump through this styleSheet and go to analyzing next.
+          return pre
+        }
+        const clsNms = match[1].split(',').map(n => n.trim())
+        const cssText = match[2].replace(/[{}]/g, '').trim()
+        let clsNmsIdx = 0
+        const clsNmsLen = clsNms.length
+        while (clsNmsIdx < clsNmsLen) {
+          rules.push({
+            selectorText: clsNms[clsNmsIdx],
+            cssText
+          })
+          clsNmsIdx++
+        }
+      }
+      Array.from(rules).forEach(rule => {
+        const selector = rule.selectorText || ''
+        pre[selector] = trimComment(rule.cssText).split(';')
+          .reduce((styleObj, statement) => {
+            statement = statement.trim()
+            if (statement && statement.indexOf('/*') <= -1) {
+              const resArr = statement.split(':').map((part) => part.trim())
+              styleObj[resArr[0]] = resArr[1]
+            }
+            return styleObj
+          }, {})
+      })
+      return pre
+    }, {})
+  if (process.env.NODE_ENV === 'development') {
+    tagEnd('getHeadStyleMap')
+  }
+  return res
+}
+
+export function getScopeIds (context) {
+  const arr = []
+  let ctx = context
+  let scopeId
+  while (ctx) {
+    scopeId = ctx.$options._scopeId
+    scopeId && arr.push(scopeId)
+    ctx = ctx.$options.parent
+  }
+  return arr
+}
+
+export function setDefaultStyle () {
+  
+}
+
+/**
+ * get style in <style scoped> tags for this component.
+ */
+export function getScopeStyle (context, classNames) {
+  const scopeIds = getScopeIds(context)
+  const style = {}
+  const styleMap = weex.styleMap
+  let map
+  let cls
+  let clsNmsIdx
+  let scpIdsIdx
+  const clsNmsLen = classNames.length
+  const scpIdsLen = scopeIds.length
+  if (clsNmsLen <= 0) {
+    return {}
+  }
+  clsNmsIdx = 0
+  while (clsNmsIdx < clsNmsLen) {
+    scpIdsIdx = 0
+    while (scpIdsIdx < scpIdsLen) {
+      cls = `.${classNames[clsNmsIdx]}[${scopeIds[scpIdsIdx]}]`
+      map = styleMap[cls]
+      if (!map) {
+        scpIdsIdx++
+        continue
+      }
+      for (const k in map) {
+        style[k] = map[k]
+      }
+      scpIdsIdx++
+    }
+    clsNmsIdx++
+  }
+  return style
+}
+
+/**
+ * get style merged with static styles, binding styles, and scoped class styles,
+ * with keys in camelcase.
+ */
+export function getComponentStyle (context) {
+  if (!context.$vnode) {
+    if (process.env.NODE_ENV === 'development') {
+      return console.error('[vue-render] getComponentStyle failed: no $vnode in context.')
+    }
+    return {}
+  }
+  const cached = context.$vnode.data.cached
+  const data = context.$vnode.data
+  const staticClassNames = (typeof data.staticClass === 'string') ? data.staticClass.split(' ') : (data.staticClass || [])
+  const classNames = (typeof data.class === 'string') ? data.class.split(' ') : (data.class || [])
+  const clsNms = staticClassNames.concat(classNames)
+  const style = getScopeStyle(context, clsNms)
+  const res = extend(style, cached, data.staticStyle, data.style)
+  context.$vnode.data.cached = res
+  return addPrefix(normalizeStyle(camelizeKeys(res)))
+}
+
+export function extractComponentStyle (context) {
+  const style = getComponentStyle(context)
+  if (style) {
+    delete context.$vnode.data.staticStyle
+    delete context.$vnode.data.style
+  }
+  return style
+}
+
+/**
+ * get { width, height } (size) of current component from components' styles.
+ */
+export function getSize (context) {
+  if (!context.$vnode) {
+    if (process.env.NODE_ENV === 'development') {
+      return console.error('[vue-render] getComponentStyle failed: no $vnode in context.')
+    }
+    return {}
+  }
+  const data = context.$vnode.data
+  const wh = {}
+  const classes = typeof data.class === 'string' ? data.class.split(' ') : (data.class || [])
+  const staticClass = typeof data.staticClass === 'string' ? data.staticClass.split(' ') : (data.class || [])
+  const clsNms = staticClass.concat(classes)
+  function extendWHFrom (to, from) {
+    if (!from) { return }
+    from.width && (to.width = from.width)
+    from.height && (to.height = from.height)
+  }
+  extendWHFrom(wh, this._getScopeStyle(clsNms))
+  extendWHFrom(wh, data.staticStyle)
+  extendWHFrom(wh, data.style)
+  return wh
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/env/index.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/env/index.js b/html5/render/vue/env/index.js
index d273ee1..1eb3d21 100644
--- a/html5/render/vue/env/index.js
+++ b/html5/render/vue/env/index.js
@@ -1,5 +1,5 @@
-import '../styles/reset.css'
-import '../styles/components.css'
+import css from '../styles/reset.css'
+import '../styles/base.css'
 
 // import 'lazyimg'
 import '../../browser/render/gesture'

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/env/viewport.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/env/viewport.js b/html5/render/vue/env/viewport.js
index db68c82..5a80893 100644
--- a/html5/render/vue/env/viewport.js
+++ b/html5/render/vue/env/viewport.js
@@ -1,3 +1,7 @@
+// @flow
+
+import { extend } from '../utils/func'
+
 /**
  * viewport priority:
  *
@@ -6,65 +10,159 @@
  * 3. process.env.VIEWPORT_WIDTH (buid time)
  *
  */
-let viewportWidth = process.env.VIEWPORT_WIDTH
+let isInited = false
+const DEFAULT_VIEWPORT_WIDTH = 750
+
+/**
+ * get viewport width from weex-viewport meta.
+ */
+const envViewportWidth = parseInt(process.env.VIEWPORT_WIDTH)
+let width: number = !isNaN(envViewportWidth) && envViewportWidth > 0
+  ? envViewportWidth
+  : DEFAULT_VIEWPORT_WIDTH
 
-const wxViewportMeta = document.querySelector('meta[name="weex-viewport"]')
+let wxViewportMeta = document.querySelector('meta[name="weex-viewport"]')
 const metaWidth = wxViewportMeta && parseInt(wxViewportMeta.getAttribute('content'))
-if (metaWidth && !isNaN(metaWidth) && metaWidth > 0) { viewportWidth = metaWidth }
+if (metaWidth && !isNaN(metaWidth) && metaWidth > 0) {
+  width = metaWidth
+}
+
+let dpr: number = 0
+let deRect: mixed = null
+let screenWidth: number = 0
+let screenHeight: number = 0
+
+const info: {
+  dpr: number,
+  scale: number,
+  rem: number,
+  deviceWidth: number,
+  deviceHeight: number
+} = {
+  dpr,
+  scale: 0,
+  rem: 0,
+  deviceWidth: 0,
+  deviceHeight: 0
+}
 
 /**
  * set root font-size for rem units. If already been set, just skip this.
  */
-function setRootFont (doc, width) {
+function setRootFont (width: number): void {
+  const doc = window.document
+  const rem = width / 10
+  if (!doc.documentElement) { return }
   const rootFontSize = doc.documentElement.style.fontSize
   if (!rootFontSize) {
-    doc.documentElement.style.fontSize = width / 10 + 'px'
+    doc.documentElement.style.fontSize = rem + 'px'
+    info.rem = rem
   }
 }
 
-export function setViewport (config = {}) {
-  const doc = window.document
+function setMetaViewport (width: number): void {
+  if (!wxViewportMeta) {
+    wxViewportMeta = document.createElement('meta')
+    wxViewportMeta.setAttribute('name', 'weex-viewport')
+  }
+  else {
+    const metaWidth = parseInt(wxViewportMeta.getAttribute('content'))
+    if (metaWidth === width) {
+      return
+    }
+  }
+  wxViewportMeta.setAttribute('content', width + '')
+}
+
+/**
+ * export viewport info.
+ */
+export function init (viewportWidth: number = width): ?{
+  dpr: number,
+  scale: number,
+  rem: number,
+  deviceWidth: number,
+  deviceHeight: number
+} {
+  if (!isInited) {
+    isInited = true
+
+    const doc = window.document
+    if (!doc) {
+      console.error('[vue-render] window.document is undfined.')
+      return
+    }
+    if (!doc.documentElement) {
+      console.error('[vue-render] document.documentElement is undfined.')
+      return
+    }
+
+    dpr = info.dpr = window.devicePixelRatio
+    deRect = doc.documentElement.getBoundingClientRect()
+    screenWidth = deRect.width
+    screenHeight = deRect.height
 
-  if (doc) {
     // set root font for rem.
-    setRootFont(doc, viewportWidth)
+    setRootFont(screenWidth)
+    setMetaViewport(viewportWidth)
 
     /**
      * why not to use window.screen.width to get screenWidth ? Because in some
      * old webkit browser on android system it get the device pixel width, which
      * is the screenWidth multiply by the device pixel ratio.
+     * e.g. ip6 -> get 375 for virtual screen width.
      */
-    const deRect = document.documentElement.getBoundingClientRect()
-    const screenWidth = deRect.width
-    const screenHeight = deRect.height
     const scale = screenWidth / viewportWidth
-
     /**
-     * if set initial/maximum/mimimum-scale some how the page will have a bounce
+     * 1. if set initial/maximum/mimimum-scale some how the page will have a bounce
      * effect when user drag the page towards horizontal axis.
+     * 2. Due to compatibility reasons, not to use viewport meta anymore. Just bring
+     * a parameter scale into the style value processing.
      */
-    const contents = [
-      `width=${viewportWidth}`,
-      // `initial-scale=${scale}`,
-      // `maximum-scale=${scale}`,
-      // `minimum-scale=${scale}`,
-      `user-scalable=no`
-    ]
-
-    let meta = doc.querySelector('meta[name="viewport"]')
-    if (!meta) {
-      meta = doc.createElement('meta')
-      meta.setAttribute('name', 'viewport')
-      document.querySelector('head').appendChild(meta)
-    }
-    meta.setAttribute('content', contents.join(','))
 
-    const dpr = window.devicePixelRatio
+    // const contents = [
+    //   `width=${viewportWidth}`,
+    //   `initial-scale=${scale}`,
+    //   `maximum-scale=${scale}`,
+    //   `minimum-scale=${scale}`,
+    //   `user-scalable=no`
+    // ]
+
+    // let meta = doc.querySelector('meta[name="viewport"]')
+    // if (!meta) {
+    //   meta = doc.createElement('meta')
+    //   meta.setAttribute('name', 'viewport')
+    //   document.querySelector('head').appendChild(meta)
+    // }
+    // meta.setAttribute('content', contents.join(','))
 
-    return {
+    extend(info, {
       scale,
       deviceWidth: screenWidth * dpr,
       deviceHeight: screenHeight * dpr
-    }
+    })
   }
+
+  return info
+}
+
+/**
+ * reset viewport width and scale.
+ * @return new scale.
+ */
+export function resetViewport (viewportWidth: number): number {
+  setMetaViewport(viewportWidth)
+  const newScale = screenWidth / viewportWidth
+  info.scale = newScale
+  return newScale
+}
+
+export function getViewportInfo (): {
+  dpr: number,
+  scale: number,
+  rem: number,
+  deviceWidth: number,
+  deviceHeight: number
+} {
+  return info
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/env/weex.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/env/weex.js b/html5/render/vue/env/weex.js
index 685e5b3..8b2c7d5 100644
--- a/html5/render/vue/env/weex.js
+++ b/html5/render/vue/env/weex.js
@@ -8,7 +8,7 @@ const weexModules = {}
 const weex = {
   __vue__: null,
   utils,
-  units: window.CSS_UNIT,
+  // units: window.CSS_UNIT,
   config: {
     env: window.WXEnvironment,
     bundleUrl: location.href

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/env/wx-env.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/env/wx-env.js b/html5/render/vue/env/wx-env.js
index 4c5f8e4..011b412 100644
--- a/html5/render/vue/env/wx-env.js
+++ b/html5/render/vue/env/wx-env.js
@@ -1,48 +1,52 @@
 import 'envd'
 
-import { setViewport } from './viewport'
+import { init as initViewport } from './viewport'
 import { extend } from '../utils'
 
-const scaleInfo = setViewport()
-
-const lib = window.lib
-const env = {
-  platform: 'Web',
-  // weexVersion: '0.10.0', // TODO: get version from package.json (not sure)
-  weexVersion: 'process.env.WEEX_VERSION',
-  userAgent: navigator.userAgent,
-  appName: lib.env.aliapp ? lib.env.aliapp.appname : navigator.appName,
-  appVersion: lib.env.aliapp ? lib.env.aliapp.version.val : null,
-  osName: lib.env.browser ? lib.env.browser.name : null,
-  osVersion: lib.env.browser ? lib.env.browser.version.val : null,
-  deviceModel: lib.env.os.name || null
-}
-
 /**
- * scaleInfo: scale, deviceWidth, deviceHeight.
+ * get WXEnvironment info.
+ * @param  {object} viewportInfo: info about viewport.
+ * @param  {object} envInfo: info parsed from lib.env.
  */
-extend(env, scaleInfo)
-
-// 750 by default currently
-const scale = env.scale
-
-const units = {
-  REM: 12 * scale,
-  VW: env.deviceWidth / 100,
-  VH: env.deviceHeight / 100,
-  VMIN: Math.min(env.deviceWidth, env.deviceHeight) / 100,
-  VMAX: Math.max(env.deviceWidth, env.deviceHeight) / 100,
-  CM: 96 / 2.54 * scale,
-  MM: 96 / 25.4 * scale,
-  Q: 96 / 25.4 / 4 * scale,
-  IN: 96 * scale,
-  PT: 96 / 72 * scale,
-  PC: 96 / 6 * scale,
-  PX: scale
+export function initEnv (viewportInfo, envInfo) {
+  const env = {
+    platform: 'Web',
+    weexVersion: 'process.env.WEEX_VERSION',
+    userAgent: navigator.userAgent,
+    appName: envInfo.aliapp ? envInfo.aliapp.appname : navigator.appName,
+    appVersion: envInfo.aliapp ? envInfo.aliapp.version.val : null,
+    osName: envInfo.browser ? envInfo.browser.name : null,
+    osVersion: envInfo.browser ? envInfo.browser.version.val : null,
+    deviceModel: envInfo.os.name || null
+  }
+  /**
+   * viewportInfo: scale, deviceWidth, deviceHeight. dpr
+   */
+  return extend(env, viewportInfo)
 }
 
-Object.freeze(units)
+// const viewportInfo = initViewport()
+
+// 750 by default currently
+// const scale = viewportInfo.scale
+
+// const units = {
+//   REM: 12 * scale,
+//   VW: viewportInfo.deviceWidth / 100,
+//   VH: viewportInfo.deviceHeight / 100,
+//   VMIN: Math.min(viewportInfo.deviceWidth, viewportInfo.deviceHeight) / 100,
+//   VMAX: Math.max(viewportInfo.deviceWidth, viewportInfo.deviceHeight) / 100,
+//   CM: 96 / 2.54 * scale,
+//   MM: 96 / 25.4 * scale,
+//   Q: 96 / 25.4 / 4 * scale,
+//   IN: 96 * scale,
+//   PT: 96 / 72 * scale,
+//   PC: 96 / 6 * scale,
+//   PX: scale
+// }
+
+// Object.freeze(units)
 // Object.freeze(env)
 
-window.CSS_UNIT = units
-window.WXEnvironment = env
+// window.CSS_UNIT = units
+window.WXEnvironment = initEnv(initViewport(), window.lib.env)

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/mixins/base.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/mixins/base.js b/html5/render/vue/mixins/base.js
index dba7688..ca30e0c 100644
--- a/html5/render/vue/mixins/base.js
+++ b/html5/render/vue/mixins/base.js
@@ -23,16 +23,6 @@ function watchLazyload () {
   })
 }
 
-let warned = false
-const notePage = 'https://github.com/MrRaindrop/weex/issues/14'
-function warnProcessStyle () {
-  if (!warned) {
-    warned = true
-    console.warn(`[vue-render] warn: should add loader config using $processStyle to enable`
-      + ` inline styles's auto-prefixing. see ${notePage}. If already did it, please ignore this.`)
-  }
-}
-
 export default {
   beforeCreate () {
     if (!lazyloadWatched) {
@@ -48,9 +38,6 @@ export default {
       weex._root = this.$root.$el
       weex._root.classList.add('weex-root')
     }
-    if (!warned && !window._style_processing_added) {
-      warnProcessStyle()
-    }
     watchAppear(this)
     if (process.env.NODE_ENV === 'development') {
       tagMounted()

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/mixins/style.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/mixins/style.js b/html5/render/vue/mixins/style.js
index 5d841f2..051e6e3 100644
--- a/html5/render/vue/mixins/style.js
+++ b/html5/render/vue/mixins/style.js
@@ -3,6 +3,7 @@ import {
   hyphenateKeys,
   extend,
   trimComment
+  // normalizeStyle
 } from '../utils'
 import { tagBegin, tagEnd } from '../utils/perf'
 import addPrefix from 'inline-style-prefixer/static'
@@ -90,6 +91,19 @@ export default {
       return hyphenateKeys(addPrefix(camelizeKeys(style)))
     },
 
+    _mergeStyle (data) {
+      const res = {}
+      const style = data.style
+      const staticStyle = data.staticStyle
+      const classes = typeof data.class === 'string' ? data.class.split(' ') : (data.class || [])
+      const staticClass = typeof data.staticClass === 'string' ? data.staticClass.split(' ') : (data.class || [])
+      const clsNms = staticClass.concat(classes)
+      extend(res, this._getScopeStyle(clsNms))
+      extend(res, staticStyle)
+      extend(res, style)
+      return hyphenateKeys(addPrefix(camelizeKeys(res)))
+    },
+
     _getScopeStyle (classNames) {
       const scopeIds = this._getScopeIds()
       const style = {}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/styles/base.css
----------------------------------------------------------------------
diff --git a/html5/render/vue/styles/base.css b/html5/render/vue/styles/base.css
new file mode 100644
index 0000000..656f3b3
--- /dev/null
+++ b/html5/render/vue/styles/base.css
@@ -0,0 +1,513 @@
+.weex-root * {
+  border-width: 0;
+  border-color: inherit;
+  border-style: solid;
+}
+
+.weex-flex-ct {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: flex;
+}
+
+.weex-ct {
+  box-sizing: border-box;
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: flex;
+  position: relative;
+  -webkit-box-orient: vertical;
+  -webkit-flex-direction: column;
+  flex-direction: column;
+  -webkit-flex-shrink: 0;
+  -ms-flex-negative: 0;
+  flex-shrink: 0;
+  -webkit-flex-grow: 0;
+  -ms-flex-grow: 0;
+  flex-grow: 0;
+  -webkit-flex-basis: auto;
+  flex-basis: auto;
+  -webkit-box-align: stretch;
+  -webkit-align-items: stretch;
+  -ms-flex-align: stretch;
+  align-items: stretch;
+  -webkit-align-content: flex-start;
+  -ms-flex-line-pack: start;
+  align-content: flex-start;
+  border: 0 solid black;
+  margin: 0;
+  padding: 0;
+  min-width: 0;
+}
+
+.weex-ct.horizontal {
+  -webkit-box-orient: horizontal;
+  -webkit-flex-direction: row;
+  flex-direction: row;
+}
+
+.weex-el {
+  display: block;
+  box-sizing: border-box;
+  position: relative;
+  -webkit-flex-shrink: 0;
+  -ms-flex-negative: 0;
+  flex-shrink: 0;
+  -webkit-flex-grow: 0;
+  -ms-flex-grow: 0;
+  flex-grow: 0;
+  -webkit-flex-basis: auto;
+  flex-basis: auto;
+  border: 0 solid black;
+  margin: 0;
+  padding: 0;
+  min-width: 0;
+}
+
+
+
+body > .weex-div {
+  min-height: 100%;
+}
+
+.weex-input, .weex-textarea {
+  font-size: 0.426667rem;
+}
+.weex-input:focus, .weex-textarea:focus {
+  outline: none;
+}
+
+.weex-image, .weex-img {
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+}
+
+.weex-toast {
+  font-size: 0.426667rem;
+  line-height: 0.426667rem;
+  position: fixed;
+  z-index: 1999999999;
+  box-sizing: border-box;
+  max-width: 80%;
+  bottom: 50%;
+  left: 50%;
+  padding: 0.213333rem;
+  background-color: #000;
+  color: #fff;
+  text-align: center;
+  opacity: 0.6;
+  -webkit-transition: all 0.4s ease-in-out;
+          transition: all 0.4s ease-in-out;
+  border-radius: 0.066667rem;
+  -webkit-transform: translateX(-50%);
+  -ms-transform: translateX(-50%);
+      transform: translateX(-50%);
+}
+
+.weex-toast.hide {
+  opacity: 0;
+}
+
+.weex-alert .weex-alert-ok {
+  width: 100%;
+}
+
+.weex-confirm .btn-group .btn {
+  float: left;
+  width: 50%;
+}
+
+.weex-confirm .btn-group .btn.btn-ok {
+  border-right: 0.013333rem solid #ddd;
+}
+
+.weex-modal-wrap {
+  display: none;
+  position: fixed;
+  z-index: 999999999;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: #000;
+  opacity: 0.5;
+}
+
+.weex-modal-node {
+  position: fixed;
+  z-index: 9999999999;
+  top: 50%;
+  left: 50%;
+  width: 6.666667rem;
+  min-height: 2.666667rem;
+  border-radius: 0.066667rem;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+      transform: translate(-50%, -50%);
+  background-color: #fff;
+}
+
+.weex-modal-node.hide {
+  display: none;
+}
+
+.weex-modal-node .content {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-box-orient: vertical;
+  -webkit-flex-direction: column;
+  -ms-flex-direction: column;
+      flex-direction: column;
+  -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%;
+  min-height: 1.866667rem;
+  box-sizing: border-box;
+  font-size: 0.426667rem;
+  line-height: 0.426667rem;
+  padding: 0.213333rem;
+  border-bottom: 0.013333rem solid #ddd;
+}
+
+.weex-modal-node .btn-group {
+  width: 100%;
+  height: 0.8rem;
+  font-size: 0.373333rem;
+  text-align: center;
+  margin: 0;
+  padding: 0;
+  border: none;
+}
+
+.amfe-modal-node .btn-group .btn {
+  text-align: center;
+}
+
+.weex-modal-node .btn-group .btn {
+  box-sizing: border-box;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  margin: 0;
+  padding: 0;
+  border: none;
+  background: none;
+  text-align: center;
+}
+
+.weex-prompt .input-wrap {
+  box-sizing: border-box;
+  width: 100%;
+  margin-top: 0.133333rem;
+  height: 0.96rem;
+}
+
+.weex-prompt .input-wrap .input {
+  box-sizing: border-box;
+  width: 100%;
+  height: 0.56rem;
+  line-height: 0.56rem;
+  font-size: 0.426667rem;
+  border: 0.013333rem solid #999;
+}
+
+.weex-prompt .btn-group .btn {
+  float: left;
+  width: 50%;
+}
+
+.weex-prompt .btn-group .btn.btn-ok {
+  border-right: 0.013333rem solid #ddd;
+}
+
+body > .weex-list,
+body > .weex-scroller {
+  max-height: 100%;
+}
+
+.weex-list-wrapper,
+.weex-scroller-wrapper {
+  -webkit-overflow-scrolling: touch;
+}
+
+.weex-list-wrapper {
+  overflow-y: scroll !important;
+}
+
+.weex-list-inner,
+.weex-scroller-inner {
+  -webkit-overflow-scrolling: touch;
+  width: 100%;
+}
+
+.weex-scroller-inner::-webkit-scrollbar {
+    width: 0;
+}
+
+.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%;
+}
+
+.iossticky {
+  position: -webkit-sticky !important;
+  position: sticky !important;
+  z-index: 9999;
+  top: 0;
+}
+
+.sticky {
+  position: fixed;
+  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;
+}
+
+.weex-slider-wrapper {
+  overflow: hidden;
+}
+
+.weex-slider-inner {
+  position: absolute;
+  height: 100%;
+  top: 0;
+  left: 0;
+}
+
+.weex-slider-cell {
+  display: block;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  margin: 0;
+  padding: 0;
+  height: 100%;
+  overflow: hidden;
+}
+
+.weex-indicator {
+  position: absolute;
+  z-index: 10;
+  -webkit-flex-direction: row;
+  -ms-flex-direction: row;
+  flex-direction: row;
+  -webkit-box-orient: horizontal;
+  margin: 0;
+  padding: 0;
+}
+
+.weex-indicator-item {
+  display: inline-block;
+  position: relative;
+  border-radius: 50%;
+  width: 0.266667rem;
+  height: 0.266667rem;
+  background-color: #BBBBBB;
+}
+.weex-indicator-item + .weex-indicator-item {
+  margin-left: 0.133333rem;
+}
+
+.weex-indicator-item-active {
+  background-color: blue;
+}
+
+.weex-refresh-indicator,
+.weex-loading-indicator {
+  width: 1.0rem;
+  height: 1.0rem;
+  -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;
+  overflow: visible;
+  background: none;
+}
+.weex-refresh-indicator:before,
+.weex-loading-indicator:before {
+  display: block;
+  content: '';
+  font-size: 0.16rem;
+  width: 1em;
+  height: 1em;
+  left: -60%;
+  top: 40%;
+  border-radius: 50%;
+  position: relative;
+  text-indent: -9999em;
+  -webkit-animation: weex-spinner 1.1s infinite ease;
+          animation: weex-spinner 1.1s infinite ease;
+  -webkit-transform: translate3d(1.0rem, 0, 0);
+          transform: translate3d(1.0rem, 0, 0);
+}
+
+@-webkit-keyframes weex-spinner {
+  0%,
+  100% {
+    box-shadow: 0em -2.6em 0em 0em #ffffff, 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.5), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7);
+  }
+  12.5% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7), 1.8em -1.8em 0 0em #ffffff, 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5);
+  }
+  25% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), 2.5em 0em 0 0em #ffffff, 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  37.5% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5), 2.5em 0em 0 0em rgba(255, 255, 255, 0.7), 1.75em 1.75em 0 0em #ffffff, 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  50% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.5), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), 0em 2.5em 0 0em #ffffff, -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  62.5% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5), 0em 2.5em 0 0em rgba(255, 255, 255, 0.7), -1.8em 1.8em 0 0em #ffffff, -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  75% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.5), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), -2.6em 0em 0 0em #ffffff, -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  87.5% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5), -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
+  }
+}
+
+@keyframes weex-spinner {
+  0%,
+  100% {
+    box-shadow: 0em -2.6em 0em 0em #ffffff, 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.5), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7);
+  }
+  12.5% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7), 1.8em -1.8em 0 0em #ffffff, 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5);
+  }
+  25% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), 2.5em 0em 0 0em #ffffff, 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  37.5% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5), 2.5em 0em 0 0em rgba(255, 255, 255, 0.7), 1.75em 1.75em 0 0em #ffffff, 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  50% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.5), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), 0em 2.5em 0 0em #ffffff, -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  62.5% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5), 0em 2.5em 0 0em rgba(255, 255, 255, 0.7), -1.8em 1.8em 0 0em #ffffff, -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  75% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.5), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), -2.6em 0em 0 0em #ffffff, -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
+  }
+  87.5% {
+    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5), -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
+  }
+}
+.weex-switch {
+  border: 0.013333rem solid #dfdfdf;
+  cursor: pointer;
+  display: inline-block;
+  position: relative;
+  vertical-align: middle;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  box-sizing: content-box;
+  background-clip: content-box;
+  color: #64bd63;
+  width: 1.333333rem;
+  height: 0.8rem;
+  background-color: white;
+  border-color: #dfdfdf;
+  box-shadow: #dfdfdf 0 0 0 0 inset;
+  border-radius: 0.8rem;
+  -webkit-transition: border 0.4s, box-shadow 0.4s, background-color 1.2s;
+          transition: border 0.4s, box-shadow 0.4s, background-color 1.2s;
+}
+
+.weex-switch-checked {
+  background-color: #64bd63;
+  border-color: #64bd63;
+  box-shadow: #64bd63 0 0 0 0.533333rem inset;
+}
+
+.weex-switch-checked.weex-switch-disabled {
+  background-color: #A0CCA0;
+  box-shadow: #A0CCA0 0 0 0 0.533333rem inset;
+}
+
+.weex-switch-disabled {
+  background-color: #EEEEEE;
+}
+
+.weex-switch-inner {
+  width: 0.8rem;
+  height: 0.8rem;
+  background: #fff;
+  border-radius: 100%;
+  box-shadow: 0 0.013333rem 0.04rem rgba(0, 0, 0, 0.4);
+  position: absolute;
+  top: 0;
+  left: 0;
+  -webkit-transition: background-color 0.4s, left 0.2s;
+          transition: background-color 0.4s, left 0.2s;
+}
+
+.weex-switch-checked > .weex-switch-inner {
+  left: 0.533333rem;
+}
+
+.weex-text {
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  position: relative;
+  white-space: pre-wrap;  /* not using 'pre': support auto line feed. */
+  font-size: 0.426667rem;
+  word-wrap: break-word;
+  overflow: hidden; /* it'll be clipped if the height is not high enough. */
+}
+
+.weex-web {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  border: none;
+  box-sizing: border-box;
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/38f1a971/html5/render/vue/styles/components.css
----------------------------------------------------------------------
diff --git a/html5/render/vue/styles/components.css b/html5/render/vue/styles/components.css
deleted file mode 100644
index 47d2f2a..0000000
--- a/html5/render/vue/styles/components.css
+++ /dev/null
@@ -1,513 +0,0 @@
-.weex-root * {
-  border-width: 0;
-  border-color: inherit;
-  border-style: solid;
-}
-
-.weex-flex-ct {
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: flex;
-}
-
-.weex-ct {
-  box-sizing: border-box;
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: flex;
-  position: relative;
-  -webkit-box-orient: vertical;
-  -webkit-flex-direction: column;
-  flex-direction: column;
-  -webkit-flex-shrink: 0;
-  -ms-flex-negative: 0;
-  flex-shrink: 0;
-  -webkit-flex-grow: 0;
-  -ms-flex-grow: 0;
-  flex-grow: 0;
-  -webkit-flex-basis: auto;
-  flex-basis: auto;
-  -webkit-box-align: stretch;
-  -webkit-align-items: stretch;
-  -ms-flex-align: stretch;
-  align-items: stretch;
-  -webkit-align-content: flex-start;
-  -ms-flex-line-pack: start;
-  align-content: flex-start;
-  border: 0 solid black;
-  margin: 0;
-  padding: 0;
-  min-width: 0;
-}
-
-.weex-ct.horizontal {
-  -webkit-box-orient: horizontal;
-  -webkit-flex-direction: row;
-  flex-direction: row;
-}
-
-.weex-el {
-  display: block;
-  box-sizing: border-box;
-  position: relative;
-  -webkit-flex-shrink: 0;
-  -ms-flex-negative: 0;
-  flex-shrink: 0;
-  -webkit-flex-grow: 0;
-  -ms-flex-grow: 0;
-  flex-grow: 0;
-  -webkit-flex-basis: auto;
-  flex-basis: auto;
-  border: 0 solid black;
-  margin: 0;
-  padding: 0;
-  min-width: 0;
-}
-
-.weex-a {
-  text-decoration: none;
-}
-
-body > .weex-div {
-  min-height: 100%;
-}
-
-.weex-input, .weex-textarea {
-  font-size: 0.426667rem;
-}
-.weex-input:focus, .weex-textarea:focus {
-  outline: none;
-}
-
-.weex-image, .weex-img {
-  background-repeat: no-repeat;
-  background-position: 50% 50%;
-}
-
-.weex-toast {
-  font-size: 0.426667rem;
-  line-height: 0.426667rem;
-  position: fixed;
-  z-index: 1999999999;
-  box-sizing: border-box;
-  max-width: 80%;
-  bottom: 50%;
-  left: 50%;
-  padding: 0.213333rem;
-  background-color: #000;
-  color: #fff;
-  text-align: center;
-  opacity: 0.6;
-  -webkit-transition: all 0.4s ease-in-out;
-          transition: all 0.4s ease-in-out;
-  border-radius: 0.066667rem;
-  -webkit-transform: translateX(-50%);
-  -ms-transform: translateX(-50%);
-      transform: translateX(-50%);
-}
-
-.weex-toast.hide {
-  opacity: 0;
-}
-
-.weex-alert .weex-alert-ok {
-  width: 100%;
-}
-
-.weex-confirm .btn-group .btn {
-  float: left;
-  width: 50%;
-}
-
-.weex-confirm .btn-group .btn.btn-ok {
-  border-right: 0.013333rem solid #ddd;
-}
-
-.weex-modal-wrap {
-  display: none;
-  position: fixed;
-  z-index: 999999999;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  background-color: #000;
-  opacity: 0.5;
-}
-
-.weex-modal-node {
-  position: fixed;
-  z-index: 9999999999;
-  top: 50%;
-  left: 50%;
-  width: 6.666667rem;
-  min-height: 2.666667rem;
-  border-radius: 0.066667rem;
-  -webkit-transform: translate(-50%, -50%);
-  -ms-transform: translate(-50%, -50%);
-      transform: translate(-50%, -50%);
-  background-color: #fff;
-}
-
-.weex-modal-node.hide {
-  display: none;
-}
-
-.weex-modal-node .content {
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -ms-flexbox;
-  display: flex;
-  -webkit-box-orient: vertical;
-  -webkit-flex-direction: column;
-  -ms-flex-direction: column;
-      flex-direction: column;
-  -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%;
-  min-height: 1.866667rem;
-  box-sizing: border-box;
-  font-size: 0.426667rem;
-  line-height: 0.426667rem;
-  padding: 0.213333rem;
-  border-bottom: 0.013333rem solid #ddd;
-}
-
-.weex-modal-node .btn-group {
-  width: 100%;
-  height: 0.8rem;
-  font-size: 0.373333rem;
-  text-align: center;
-  margin: 0;
-  padding: 0;
-  border: none;
-}
-
-.amfe-modal-node .btn-group .btn {
-  text-align: center;
-}
-
-.weex-modal-node .btn-group .btn {
-  box-sizing: border-box;
-  height: 0.8rem;
-  line-height: 0.8rem;
-  margin: 0;
-  padding: 0;
-  border: none;
-  background: none;
-  text-align: center;
-}
-
-.weex-prompt .input-wrap {
-  box-sizing: border-box;
-  width: 100%;
-  margin-top: 0.133333rem;
-  height: 0.96rem;
-}
-
-.weex-prompt .input-wrap .input {
-  box-sizing: border-box;
-  width: 100%;
-  height: 0.56rem;
-  line-height: 0.56rem;
-  font-size: 0.426667rem;
-  border: 0.013333rem solid #999;
-}
-
-.weex-prompt .btn-group .btn {
-  float: left;
-  width: 50%;
-}
-
-.weex-prompt .btn-group .btn.btn-ok {
-  border-right: 0.013333rem solid #ddd;
-}
-
-body > .weex-list,
-body > .weex-scroller {
-  max-height: 100%;
-}
-
-.weex-list-wrapper,
-.weex-scroller-wrapper {
-  -webkit-overflow-scrolling: touch;
-}
-
-.weex-list-wrapper {
-  overflow-y: scroll !important;
-}
-
-.weex-list-inner,
-.weex-scroller-inner {
-  -webkit-overflow-scrolling: touch;
-  width: 100%;
-}
-
-.weex-scroller-inner::-webkit-scrollbar {
-    width: 0;
-}
-
-.weex-scroller-wrapper.weex-scroller-vertical {
-  overflow-y: scroll;
-}
-
-.weex-scroller-wrapper.weex-scroller-horizontal {
-  overflow-x: scroll;
-}
-
-.weex-scroller-horizontal .weex-scroller-inner {
-  -webkit-flex-direction: row;
-      -ms-flex-direction: row;
-          flex-direction: row;
-  -webkit-box-orient: horizontal;
-  height: 100%;
-}
-
-.iossticky {
-  position: -webkit-sticky !important;
-  position: sticky !important;
-  z-index: 9999;
-  top: 0;
-}
-
-.sticky {
-  position: fixed;
-  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;
-}
-
-.weex-slider-wrapper {
-  overflow: hidden;
-}
-
-.weex-slider-inner {
-  position: absolute;
-  height: 100%;
-  top: 0;
-  left: 0;
-}
-
-.weex-slider-cell {
-  display: block;
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  margin: 0;
-  padding: 0;
-  height: 100%;
-  overflow: hidden;
-}
-
-.weex-indicator {
-  position: absolute;
-  z-index: 10;
-  -webkit-flex-direction: row;
-  -ms-flex-direction: row;
-  flex-direction: row;
-  -webkit-box-orient: horizontal;
-  margin: 0;
-  padding: 0;
-}
-
-.weex-indicator-item {
-  display: inline-block;
-  position: relative;
-  border-radius: 50%;
-  width: 0.266667rem;
-  height: 0.266667rem;
-  background-color: #BBBBBB;
-}
-.weex-indicator-item + .weex-indicator-item {
-  margin-left: 0.133333rem;
-}
-
-.weex-indicator-item-active {
-  background-color: blue;
-}
-
-.weex-refresh-indicator,
-.weex-loading-indicator {
-  width: 1.0rem;
-  height: 1.0rem;
-  -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;
-  overflow: visible;
-  background: none;
-}
-.weex-refresh-indicator:before,
-.weex-loading-indicator:before {
-  display: block;
-  content: '';
-  font-size: 0.16rem;
-  width: 1em;
-  height: 1em;
-  left: -60%;
-  top: 40%;
-  border-radius: 50%;
-  position: relative;
-  text-indent: -9999em;
-  -webkit-animation: weex-spinner 1.1s infinite ease;
-          animation: weex-spinner 1.1s infinite ease;
-  -webkit-transform: translate3d(1.0rem, 0, 0);
-          transform: translate3d(1.0rem, 0, 0);
-}
-
-@-webkit-keyframes weex-spinner {
-  0%,
-  100% {
-    box-shadow: 0em -2.6em 0em 0em #ffffff, 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.5), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7);
-  }
-  12.5% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7), 1.8em -1.8em 0 0em #ffffff, 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5);
-  }
-  25% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), 2.5em 0em 0 0em #ffffff, 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  37.5% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5), 2.5em 0em 0 0em rgba(255, 255, 255, 0.7), 1.75em 1.75em 0 0em #ffffff, 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  50% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.5), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), 0em 2.5em 0 0em #ffffff, -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  62.5% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5), 0em 2.5em 0 0em rgba(255, 255, 255, 0.7), -1.8em 1.8em 0 0em #ffffff, -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  75% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.5), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), -2.6em 0em 0 0em #ffffff, -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  87.5% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5), -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
-  }
-}
-
-@keyframes weex-spinner {
-  0%,
-  100% {
-    box-shadow: 0em -2.6em 0em 0em #ffffff, 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.5), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7);
-  }
-  12.5% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7), 1.8em -1.8em 0 0em #ffffff, 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5);
-  }
-  25% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), 2.5em 0em 0 0em #ffffff, 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  37.5% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5), 2.5em 0em 0 0em rgba(255, 255, 255, 0.7), 1.75em 1.75em 0 0em #ffffff, 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  50% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.5), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), 0em 2.5em 0 0em #ffffff, -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  62.5% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5), 0em 2.5em 0 0em rgba(255, 255, 255, 0.7), -1.8em 1.8em 0 0em #ffffff, -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  75% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.5), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), -2.6em 0em 0 0em #ffffff, -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
-  }
-  87.5% {
-    box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5), -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
-  }
-}
-.weex-switch {
-  border: 0.013333rem solid #dfdfdf;
-  cursor: pointer;
-  display: inline-block;
-  position: relative;
-  vertical-align: middle;
-  -webkit-user-select: none;
-     -moz-user-select: none;
-      -ms-user-select: none;
-          user-select: none;
-  box-sizing: content-box;
-  background-clip: content-box;
-  color: #64bd63;
-  width: 1.333333rem;
-  height: 0.8rem;
-  background-color: white;
-  border-color: #dfdfdf;
-  box-shadow: #dfdfdf 0 0 0 0 inset;
-  border-radius: 0.8rem;
-  -webkit-transition: border 0.4s, box-shadow 0.4s, background-color 1.2s;
-          transition: border 0.4s, box-shadow 0.4s, background-color 1.2s;
-}
-
-.weex-switch-checked {
-  background-color: #64bd63;
-  border-color: #64bd63;
-  box-shadow: #64bd63 0 0 0 0.533333rem inset;
-}
-
-.weex-switch-checked.weex-switch-disabled {
-  background-color: #A0CCA0;
-  box-shadow: #A0CCA0 0 0 0 0.533333rem inset;
-}
-
-.weex-switch-disabled {
-  background-color: #EEEEEE;
-}
-
-.weex-switch-inner {
-  width: 0.8rem;
-  height: 0.8rem;
-  background: #fff;
-  border-radius: 100%;
-  box-shadow: 0 0.013333rem 0.04rem rgba(0, 0, 0, 0.4);
-  position: absolute;
-  top: 0;
-  left: 0;
-  -webkit-transition: background-color 0.4s, left 0.2s;
-          transition: background-color 0.4s, left 0.2s;
-}
-
-.weex-switch-checked > .weex-switch-inner {
-  left: 0.533333rem;
-}
-
-.weex-text {
-  display: -webkit-box;
-  -webkit-box-orient: vertical;
-  position: relative;
-  white-space: pre-wrap;  /* not using 'pre': support auto line feed. */
-  font-size: 0.426667rem;
-  word-wrap: break-word;
-  overflow: hidden; /* it'll be clipped if the height is not high enough. */
-}
-
-.weex-web {
-  position: relative;
-  width: 100%;
-  height: 100%;
-  border: none;
-  box-sizing: border-box;
-}