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

[11/20] incubator-weex git commit: [WEEX-181] rm web renderer codes and scripts (resolve #958)

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/api/modal.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/api/modal.js b/html5/render/browser/extend/api/modal.js
deleted file mode 100644
index 691174e..0000000
--- a/html5/render/browser/extend/api/modal.js
+++ /dev/null
@@ -1,89 +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.
- */
-'use strict'
-
-import modal from 'modals'
-
-const msg = {
-
-  // duration: default is 0.8 seconds.
-  toast: function (config) {
-    modal.toast(config.message, config.duration)
-  },
-
-  // config:
-  //  - message: string
-  //  - okTitle: title of ok button
-  //  - callback
-  alert: function (config, callbackId) {
-    const sender = this.sender
-    config.callback = function () {
-      sender.performCallback(callbackId)
-    }
-    modal.alert(config)
-  },
-
-  // config:
-  //  - message: string
-  //  - okTitle: title of ok button
-  //  - cancelTitle: title of cancel button
-  //  - callback
-  confirm: function (config, callbackId) {
-    const sender = this.sender
-    config.callback = function (val) {
-      sender.performCallback(callbackId, val)
-    }
-    modal.confirm(config)
-  },
-
-  // config:
-  //  - message: string
-  //  - okTitle: title of ok button
-  //  - cancelTitle: title of cancel button
-  //  - callback
-  prompt: function (config, callbackId) {
-    const sender = this.sender
-    config.callback = function (val) {
-      sender.performCallback(callbackId, val)
-    }
-    modal.prompt(config)
-  }
-}
-
-const meta = {
-  modal: [{
-    name: 'toast',
-    args: ['object']
-  }, {
-    name: 'alert',
-    args: ['object', 'function']
-  }, {
-    name: 'confirm',
-    args: ['object', 'function']
-  }, {
-    name: 'prompt',
-    args: ['object', 'function']
-  }]
-}
-
-export default {
-  init: function (Weex) {
-    Weex.registerApiModule('modal', msg, meta)
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/api/navigator.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/api/navigator.js b/html5/render/browser/extend/api/navigator.js
deleted file mode 100644
index 8c16a4d..0000000
--- a/html5/render/browser/extend/api/navigator.js
+++ /dev/null
@@ -1,56 +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.
- */
-'use strict'
-
-const navigator = {
-
-  // config
-  //  - url: the url to push
-  //  - animated: this configuration item is native only
-  //  callback is not currently supported
-  push: function (config, callbackId) {
-    window.location.href = config.url
-    this.sender.performCallback(callbackId)
-  },
-
-  // config
-  //  - animated: this configuration item is native only
-  //  callback is note currently supported
-  pop: function (config, callbackId) {
-    window.history.back()
-    this.sender.performCallback(callbackId)
-  }
-
-}
-
-const meta = {
-  navigator: [{
-    name: 'push',
-    args: ['object', 'function']
-  }, {
-    name: 'pop',
-    args: ['object', 'function']
-  }]
-}
-
-export default {
-  init: function (Weex) {
-    Weex.registerApiModule('navigator', navigator, meta)
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/api/pageInfo.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/api/pageInfo.js b/html5/render/browser/extend/api/pageInfo.js
deleted file mode 100644
index dcc074d..0000000
--- a/html5/render/browser/extend/api/pageInfo.js
+++ /dev/null
@@ -1,44 +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.
- */
-'use strict'
-
-const pageInfo = {
-
-  setTitle: function (title) {
-    title = title || 'Weex HTML5'
-    try {
-      title = decodeURIComponent(title)
-    }
-    catch (e) {}
-    document.title = title
-  }
-}
-
-const meta = {
-  pageInfo: [{
-    name: 'setTitle',
-    args: ['string']
-  }]
-}
-
-export default {
-  init: function (Weex) {
-    Weex.registerApiModule('pageInfo', pageInfo, meta)
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/api/storage.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/api/storage.js b/html5/render/browser/extend/api/storage.js
deleted file mode 100644
index cb4de3b..0000000
--- a/html5/render/browser/extend/api/storage.js
+++ /dev/null
@@ -1,215 +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.
- */
-/* global localStorage */
-
-'use strict'
-
-let supportLocalStorage = false
-try {
-  supportLocalStorage = typeof localStorage !== 'undefined'
-}
-catch (err) {
-  // not support.
-}
-
-const SUCCESS = 'success'
-const FAILED = 'failed'
-const INVALID_PARAM = 'invalid_param'
-const UNDEFINED = 'undefined'
-
-function callFail (sender, callbackId, errorMsg) {
-  sender.performCallback(callbackId, {
-    result: FAILED,
-    data: errorMsg || UNDEFINED
-  })
-}
-
-function callNotSupportFail (sender, callbackId) {
-  sender.performCallback(callbackId, {
-    result: FAILED,
-    data: 'localStorage is disabled or not supported.'
-  })
-}
-
-const storage = {
-
-  /**
-   * When passed a key name and value, will add that key to the storage,
-   * or update that key's value if it already exists.
-   * @param {string} key
-   * @param {string} value not null nor undifined,but 0 works.
-   * @param {function} callbackId
-   */
-  setItem: function (key, value, callbackId) {
-    const sender = this.sender
-    if (!supportLocalStorage) {
-      return callNotSupportFail(sender, callbackId)
-    }
-    if (!key || (!value && value !== 0)) {
-      sender.performCallback(callbackId, {
-        result: 'failed',
-        data: INVALID_PARAM
-      })
-      return
-    }
-    try {
-      localStorage.setItem(key, value)
-      sender.performCallback(callbackId, {
-        result: SUCCESS,
-        data: UNDEFINED
-      })
-    }
-    catch (e) {
-      // accept any exception thrown during a storage attempt as a quota error
-      callFail(sender, callbackId)
-    }
-  },
-
-  /**
-   * When passed a key name, will return that key's value.
-   * @param {string} key
-   * @param {function} callbackId
-   */
-  getItem: function (key, callbackId) {
-    const sender = this.sender
-    if (!supportLocalStorage) {
-      return callNotSupportFail(sender, callbackId)
-    }
-    if (!key) {
-      sender.performCallback(callbackId, {
-        result: FAILED,
-        data: INVALID_PARAM
-      })
-      return
-    }
-    try {
-      const val = localStorage.getItem(key)
-      sender.performCallback(callbackId, {
-        result: val ? SUCCESS : FAILED,
-        data: val || UNDEFINED
-      })
-    }
-    catch (e) {
-      // accept any exception thrown during a storage attempt as a quota error
-      callFail(sender, callbackId)
-    }
-  },
-
-  /**
-   *When passed a key name, will remove that key from the storage.
-   * @param {string} key
-   * @param {function} callbackId
-   */
-  removeItem: function (key, callbackId) {
-    const sender = this.sender
-    if (!supportLocalStorage) {
-      return callNotSupportFail(sender, callbackId)
-    }
-    if (!key) {
-      sender.performCallback(callbackId, {
-        result: FAILED,
-        data: INVALID_PARAM
-      })
-      return
-    }
-    try {
-      localStorage.removeItem(key)
-      sender.performCallback(callbackId, {
-        result: SUCCESS,
-        data: UNDEFINED
-      })
-    }
-    catch (e) {
-      // accept any exception thrown during a storage attempt as a quota error
-      callFail(sender, callbackId)
-    }
-  },
-
-  /**
-   * Returns an integer representing the number of data items stored in the Storage object.
-   * @param {function} callbackId
-   */
-  length: function (callbackId) {
-    const sender = this.sender
-    if (!supportLocalStorage) {
-      return callNotSupportFail(sender, callbackId)
-    }
-    try {
-      const len = localStorage.length
-      sender.performCallback(callbackId, {
-        result: SUCCESS,
-        data: len
-      })
-    }
-    catch (e) {
-      // accept any exception thrown during a storage attempt as a quota error
-      callFail(sender, callbackId)
-    }
-  },
-
-  /**
-   * Returns an array that contains all keys stored in Storage object.
-   * @param {function} callbackId
-   */
-  getAllKeys: function (callbackId) {
-    const sender = this.sender
-    if (!supportLocalStorage) {
-      return callNotSupportFail(sender, callbackId)
-    }
-    try {
-      const _arr = []
-      for (let i = 0; i < localStorage.length; i++) {
-        _arr.push(localStorage.key(i))
-      }
-      sender.performCallback(callbackId, {
-        result: SUCCESS,
-        data: _arr
-      })
-    }
-    catch (e) {
-      // accept any exception thrown during a storage attempt as a quota error
-      callFail(sender, callbackId)
-    }
-  }
-}
-
-const meta = {
-  storage: [{
-    name: 'setItem',
-    args: ['string', 'string', 'function']
-  }, {
-    name: 'getItem',
-    args: ['string', 'function']
-  }, {
-    name: 'removeItem',
-    args: ['string', 'function']
-  }, {
-    name: 'length',
-    args: ['function']
-  }, {
-    name: 'getAllKeys',
-    args: ['function']
-  }]
-}
-
-export default {
-  init: function (Weex) {
-    Weex.registerApiModule('storage', storage, meta)
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/api/stream.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/api/stream.js b/html5/render/browser/extend/api/stream.js
deleted file mode 100644
index 79f507d..0000000
--- a/html5/render/browser/extend/api/stream.js
+++ /dev/null
@@ -1,327 +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.
- */
-/* global lib, XMLHttpRequest */
-/* deps: httpurl */
-
-'use strict'
-
-let utils
-
-import 'httpurl'
-import qs from 'query-string'
-
-let jsonpCnt = 0
-const ERROR_STATE = -1
-
-function _jsonp (config, callback, progressCallback) {
-  const cbName = config.jsonpCallbackName || 'jsonp_' + (++jsonpCnt)
-  let url
-
-  if (!config.url) {
-    console.error('[h5-render] config.url should be set in _jsonp for \'fetch\' API.')
-  }
-
-  global[cbName] = (function (cb) {
-    return function (response) {
-      callback({
-        status: 200,
-        ok: true,
-        statusText: 'OK',
-        data: response
-      })
-      delete global[cb]
-    }
-  })(cbName)
-
-  const script = document.createElement('script')
-  try {
-    url = lib.httpurl(config.url)
-  }
-  catch (err) {
-    console.error('[h5-render] invalid config.url in _jsonp for \'fetch\' API: '
-      + config.url)
-  }
-  url.params.callback = cbName
-  script.type = 'text/javascript'
-  script.src = url.toString()
-  // script.onerror is not working on IE or safari.
-  // but they are not considered here.
-  script.onerror = (function (cb) {
-    return function (err) {
-      console.error('[h5-render] unexpected error in _jsonp for \'fetch\' API', err)
-      callback({
-        status: ERROR_STATE,
-        ok: false,
-        statusText: '',
-        data: ''
-      })
-      delete global[cb]
-    }
-  })(cbName)
-  const head = document.getElementsByTagName('head')[0]
-  head.insertBefore(script, null)
-}
-
-function _xhr (config, callback, progressCallback) {
-  const xhr = new XMLHttpRequest()
-  xhr.responseType = config.type
-  xhr.open(config.method, config.url, true)
-
-  // cors cookie support
-  if (config.withCredentials === true) {
-    xhr.withCredentials = true
-  }
-
-  const headers = config.headers || {}
-  for (const k in headers) {
-    xhr.setRequestHeader(k, headers[k])
-  }
-
-  xhr.onload = function (res) {
-    callback({
-      status: xhr.status,
-      ok: xhr.status >= 200 && xhr.status < 300,
-      statusText: xhr.statusText,
-      data: xhr.response,
-      headers: xhr.getAllResponseHeaders().split('\n')
-        .reduce(function (obj, headerStr) {
-          const headerArr = headerStr.match(/(.+): (.+)/)
-          if (headerArr) {
-            obj[headerArr[1]] = headerArr[2]
-          }
-          return obj
-        }, {})
-    })
-  }
-
-  if (progressCallback) {
-    xhr.onprogress = function (e) {
-      progressCallback({
-        readyState: xhr.readyState,
-        status: xhr.status,
-        length: e.loaded,
-        total: e.total,
-        statusText: xhr.statusText,
-        headers: xhr.getAllResponseHeaders().split('\n')
-          .reduce(function (obj, headerStr) {
-            const headerArr = headerStr.match(/(.+): (.+)/)
-            if (headerArr) {
-              obj[headerArr[1]] = headerArr[2]
-            }
-            return obj
-          }, {})
-      })
-    }
-  }
-
-  xhr.onerror = function (err) {
-    console.error('[h5-render] unexpected error in _xhr for \'fetch\' API', err)
-    callback({
-      status: ERROR_STATE,
-      ok: false,
-      statusText: '',
-      data: ''
-    })
-  }
-
-  xhr.send(config.body || null)
-}
-
-const stream = {
-
-  /**
-   * sendHttp
-   * @deprecated
-   * Note: This API is deprecated. Please use stream.fetch instead.
-   * send a http request through XHR.
-   * @param  {obj} params
-   *  - method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'PATCH',
-   *  - url: url requested
-   * @param  {string} callbackId
-   */
-  sendHttp: function (param, callbackId) {
-    if (typeof param === 'string') {
-      try {
-        param = JSON.parse(param)
-      }
-      catch (e) {
-        return
-      }
-    }
-    if (typeof param !== 'object' || !param.url) {
-      return console.error(
-        '[h5-render] invalid config or invalid config.url for sendHttp API')
-    }
-
-    const sender = this.sender
-    const method = param.method || 'GET'
-    const xhr = new XMLHttpRequest()
-    xhr.open(method, param.url, true)
-    xhr.onload = function () {
-      sender.performCallback(callbackId, this.responseText)
-    }
-    xhr.onerror = function (error) {
-      return console.error('[h5-render] unexpected error in sendHttp API', error)
-      // sender.performCallback(
-      //   callbackId,
-      //   new Error('unexpected error in sendHttp API')
-      // )
-    }
-    xhr.send()
-  },
-
-  /**
-   * fetch
-   * use stream.fetch to request for a json file, a plain text file or
-   * a arraybuffer for a file stream. (You can use Blob and FileReader
-   * API implemented by most modern browsers to read a arraybuffer.)
-   * @param  {object} options config options
-   *   - method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'PATCH'
-   *   - headers {obj}
-   *   - url {string}
-   *   - mode {string} 'cors' | 'no-cors' | 'same-origin' | 'navigate'
-   *   - withCredentials {boolean}
-   *   - body
-   *   - type {string} 'json' | 'jsonp' | 'text'
-   * @param  {string} callbackId
-   * @param  {string} progressCallbackId
-   */
-  fetch: function (options, callbackId, progressCallbackId) {
-    const DEFAULT_METHOD = 'GET'
-    const DEFAULT_MODE = 'cors'
-    const DEFAULT_TYPE = 'text'
-
-    const methodOptions = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH']
-    const modeOptions = ['cors', 'no-cors', 'same-origin', 'navigate']
-    const typeOptions = ['text', 'json', 'jsonp', 'arraybuffer']
-
-    // const fallback = false  // fallback from 'fetch' API to XHR.
-    const sender = this.sender
-
-    const config = utils.extend({}, options)
-
-    // validate options.method
-    if (typeof config.method === 'undefined') {
-      config.method = DEFAULT_METHOD
-      console.warn('[h5-render] options.method for \'fetch\' API has been set to '
-        + 'default value \'' + config.method + '\'')
-    }
-    else if (methodOptions.indexOf((config.method + '')
-        .toUpperCase()) === -1) {
-      return console.error('[h5-render] options.method \''
-        + config.method
-        + '\' for \'fetch\' API should be one of '
-        + methodOptions + '.')
-    }
-
-    // validate options.url
-    if (!config.url) {
-      return console.error('[h5-render] options.url should be set for \'fetch\' API.')
-    }
-
-    // validate body content for method 'GET'.
-    if (config.method.toUpperCase() === 'GET') {
-      let body = config.body
-      if (utils.isPlainObject(body)) {
-        body = qs.stringify(body)
-      }
-      let url = config.url
-      let hashIdx = url.indexOf('#')
-      hashIdx <= -1 && (hashIdx = url.length)
-      let hash = url.substr(hashIdx)
-      if (hash && hash[0] === '#') {
-        hash = hash.substr(1)
-      }
-      url = url.substring(0, hashIdx)
-      if (body) {
-        url += (config.url.indexOf('?') <= -1 ? '?' : '&') + body
-      }
-      url += '#' + hash
-      config.url = url
-    }
-
-    // validate options.mode
-    if (typeof config.mode === 'undefined') {
-      config.mode = DEFAULT_MODE
-    }
-    else if (modeOptions.indexOf((config.mode + '').toLowerCase()) === -1) {
-      return console.error('[h5-render] options.mode \''
-        + config.mode
-        + '\' for \'fetch\' API should be one of '
-        + modeOptions + '.')
-    }
-
-    // validate options.type
-    if (typeof config.type === 'undefined') {
-      config.type = DEFAULT_TYPE
-      console.warn('[h5-render] options.type for \'fetch\' API has been set to '
-        + 'default value \'' + config.type + '\'.')
-    }
-    else if (typeOptions.indexOf((config.type + '').toLowerCase()) === -1) {
-      return console.error('[h5-render] options.type \''
-          + config.type
-          + '\' for \'fetch\' API should be one of '
-          + typeOptions + '.')
-    }
-
-    // validate options.headers
-    config.headers = config.headers || {}
-    if (!utils.isPlainObject(config.headers)) {
-      return console.error('[h5-render] options.headers should be a plain object')
-    }
-
-    // validate options.timeout
-    config.timeout = parseInt(config.timeout, 10) || 2500
-
-    const _callArgs = [config, function (res) {
-      sender.performCallback(callbackId, res)
-    }]
-    if (progressCallbackId) {
-      _callArgs.push(function (res) {
-        // Set 'keepAlive' to true for sending continuous callbacks
-        sender.performCallback(progressCallbackId, res, true)
-      })
-    }
-
-    if (config.type === 'jsonp') {
-      _jsonp.apply(this, _callArgs)
-    }
-    else {
-      _xhr.apply(this, _callArgs)
-    }
-  }
-
-}
-
-const meta = {
-  stream: [{
-    name: 'sendHttp',
-    args: ['object', 'function']
-  }, {
-    name: 'fetch',
-    args: ['object', 'function', 'function']
-  }]
-}
-
-export default {
-  init: function (Weex) {
-    utils = Weex.utils
-    Weex.registerApiModule('stream', stream, meta)
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/api/timer.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/api/timer.js b/html5/render/browser/extend/api/timer.js
deleted file mode 100644
index e01092f..0000000
--- a/html5/render/browser/extend/api/timer.js
+++ /dev/null
@@ -1,79 +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.
- */
-
-// const funcIdToTimerIdMap = {}
-// const funcIdToIntervalIdMap = {}
-
-// const timer = {
-
-//   setTimeout (funcId, delay) {
-//     const sender = this.sender
-//     delay < 0 && (delay = 0)
-//     const timerId = setTimeout(function () {
-//       delete funcIdToTimerIdMap[funcId]
-//       sender.performCallback(funcId)
-//     }, delay)
-//     funcIdToTimerIdMap[funcId] = timerId
-//     return funcId
-//   },
-
-//   clearTimeout (funcId) {
-//     clearTimeout(funcIdToTimerIdMap[funcId])
-//     delete funcIdToTimerIdMap[funcId]
-//   },
-
-//   setInterval (funcId, interval) {
-//     const sender = this.sender
-//     interval < 0 && (interval = 0)
-//     const timerId = setInterval(function () {
-//       delete funcIdToIntervalIdMap[funcId]
-//       sender.performCallback(funcId, null, true)
-//     })
-//     funcIdToIntervalIdMap[funcId] = timerId
-//     return funcId
-//   },
-
-//   clearInterval (funcId) {
-//     clearInterval(funcIdToIntervalIdMap[funcId])
-//     delete funcIdToIntervalIdMap[funcId]
-//   }
-
-// }
-
-// const meta = {
-//   timer: [{
-//     name: 'setTimeout',
-//     args: ['function', 'number']
-//   }, {
-//     name: 'clearTimeout',
-//     args: ['number']
-//   }, {
-//     name: 'setInterval',
-//     args: ['function', 'number']
-//   }, {
-//     name: 'clearInterval',
-//     args: ['number']
-//   }]
-// }
-
-// export default {
-//   init: function (Weex) {
-//     Weex.registerApiModule('timer', timer, meta)
-//   }
-// }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/api/webSocket.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/api/webSocket.js b/html5/render/browser/extend/api/webSocket.js
deleted file mode 100644
index 481c88f..0000000
--- a/html5/render/browser/extend/api/webSocket.js
+++ /dev/null
@@ -1,132 +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.
- */
-/* global WebSocket */
-
-'use strict'
-
-let instance
-let callback = { }
-
-const webSocketIns = {
-
-  WebSocket: function (url, protocol) {
-    if (instance) {
-      instance.close()
-      instance = undefined
-      callback = { }
-    }
-    if (protocol === '') {
-      protocol = undefined
-    }
-    const self = this
-    instance = new WebSocket(url, protocol)
-    instance.onopen = function (e) {
-      if (callback.onopen) {
-        self.sender.performCallback(callback.onopen, { type: e.type }, true)
-      }
-    }
-
-    instance.onmessage = function (e) {
-      if (callback.onmessage) {
-        self.sender.performCallback(callback.onmessage, { origin: e.origin, data: e.data, source: e.data }, true)
-      }
-    }
-
-    instance.onerror = function (e) {
-      if (callback.onerror) {
-        self.sender.performCallback(callback.onerror, { code: e.code, data: e.data })
-      }
-    }
-
-    instance.onclose = function (e) {
-      if (callback.onclose) {
-        self.sender.performCallback(callback.onclose, { data: e.data, code: e.code, reason: e.reason })
-      }
-    }
-  },
-
-  close: function (code, signal) {
-    if (instance) {
-      instance.close(code, signal)
-      instance = undefined
-      callback = { }
-    }
-  },
-
-  send: function (data) {
-    if (instance) {
-      instance.send(data)
-    }
-  },
-
-  onopen: function (func) {
-    if (instance) {
-      callback.onopen = func
-    }
-  },
-
-  onerror: function (func) {
-    if (instance) {
-      callback.onerror = func
-    }
-  },
-
-  onmessage: function (func) {
-    if (instance) {
-      callback.onmessage = func
-    }
-  },
-
-  onclose: function (func) {
-    if (instance) {
-      callback.onclose = func
-    }
-  }
-}
-
-const meta = {
-  webSocket: [{
-    name: 'WebSocket',
-    args: ['string', 'string']
-  }, {
-    name: 'close',
-    args: ['numble', 'string']
-  }, {
-    name: 'send',
-    args: ['string']
-  }, {
-    name: 'onopen',
-    args: ['function']
-  }, {
-    name: 'onmessage',
-    args: ['function']
-  }, {
-    name: 'onclose',
-    args: ['function']
-  }, {
-    name: 'onerror',
-    args: ['function']
-  }]
-}
-
-export default {
-  init: function (Weex) {
-    Weex.registerApiModule('webSocket', webSocketIns, meta)
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/api/webview.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/api/webview.js b/html5/render/browser/extend/api/webview.js
deleted file mode 100644
index 3fff8b2..0000000
--- a/html5/render/browser/extend/api/webview.js
+++ /dev/null
@@ -1,75 +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.
- */
-'use strict'
-
-const webview = {
-
-  // ref: ref of the web component.
-  goBack: function (ref) {
-    const webComp = this.getComponentManager().getComponent(ref)
-    if (!webComp.goBack) {
-      console.error('error: the specified component has no method of'
-          + ' goBack. Please make sure it is a webview component.')
-      return
-    }
-    webComp.goBack()
-  },
-
-  // ref: ref of the web component.
-  goForward: function (ref) {
-    const webComp = this.getComponentManager().getComponent(ref)
-    if (!webComp.goForward) {
-      console.error('error: the specified component has no method of'
-          + ' goForward. Please make sure it is a webview component.')
-      return
-    }
-    webComp.goForward()
-  },
-
-  // ref: ref of the web component.
-  reload: function (ref) {
-    const webComp = this.getComponentManager().getComponent(ref)
-    if (!webComp.reload) {
-      console.error('error: the specified component has no method of'
-          + ' reload. Please make sure it is a webview component.')
-      return
-    }
-    webComp.reload()
-  }
-
-}
-
-const meta = {
-  webview: [{
-    name: 'goBack',
-    args: ['string']
-  }, {
-    name: 'goForward',
-    args: ['string']
-  }, {
-    name: 'reload',
-    args: ['string']
-  }]
-}
-
-export default {
-  init: function (Weex) {
-    Weex.registerApiModule('webview', webview, meta)
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/a.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/a.js b/html5/render/browser/extend/components/a.js
deleted file mode 100644
index e8d995f..0000000
--- a/html5/render/browser/extend/components/a.js
+++ /dev/null
@@ -1,79 +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.
- */
-'use strict'
-
-function getProto (Weex) {
-  const Component = Weex.Component
-  return {
-    create () {
-      const node = document.createElement('a')
-      node.classList.add('weex-container')
-      node.style.textDecoration = 'none'
-      return node
-    },
-
-    bindEvents (evts) {
-      // event handler for click event will be processed
-      // before the url redirection.
-      Component.prototype.bindEvents.call(this, evts)
-      this.node.addEventListener('click', function (evt) {
-        if (evt._alreadyFired && evt.target !== this.node) {
-          // if the event target is this.node, then this is
-          // just another click event handler for the same
-          // target, not a handler for a bubbling up event,
-          // otherwise it is a bubbling up event, and it
-          // should be disregarded.
-          return
-        }
-        evt._alreadyFired = true
-        location.href = this.href
-      }.bind(this))
-    }
-  }
-}
-
-const attr = {
-  href: function (val) {
-    if (!val) {
-      return console.warn('[web-render] href of <a> should not be a null value.')
-    }
-    this.href = val
-    this.node.setAttribute('data-href', val)
-  }
-}
-
-function init (Weex) {
-  const Component = Weex.Component
-  const extend = Weex.utils.extend
-
-  // attrs:
-  //   - href
-  function A (data) {
-    Component.call(this, data)
-  }
-
-  A.prototype = Object.create(Component.prototype)
-  extend(A.prototype, getProto(Weex))
-  extend(A.prototype, { attr })
-
-  Weex.registerComponent('a', A)
-}
-
-export default { init }
-

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/countdown.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/countdown.js b/html5/render/browser/extend/components/countdown.js
deleted file mode 100644
index 9211e21..0000000
--- a/html5/render/browser/extend/components/countdown.js
+++ /dev/null
@@ -1,90 +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.
- */
-'use strict'
-
-import Kountdown from 'kountdown'
-
-const FORMATTER_REGEXP = /(\\)?(dd*|hh?|mm?|ss?)/gi
-
-function formatDateTime (data, formatter, timeColor) {
-  return formatter.replace(FORMATTER_REGEXP, function (m) {
-    const len = m.length
-    const firstChar = m.charAt(0)
-    // escape character
-    if (firstChar === '\\') {
-      return m.replace('\\', '')
-    }
-    const value = (firstChar === 'd' ? data.days :
-                firstChar === 'h' ? data.hours :
-                firstChar === 'm' ? data.minutes :
-                firstChar === 's' ? data.seconds : 0) + ''
-
-    // 5 zero should be enough
-    return '<span style="margin:4px;color:'
-      + timeColor + '" >'
-      + ('00000' + value).substr(-Math.max(value.length, len))
-      + '</span>'
-  })
-}
-
-const proto = {
-  create () {
-    const node = document.createElement('div')
-    node.classList.add('weex-element')
-    const data = this.data
-    const time = Number(data.attr.countdownTime) || 0
-    const endTime = Date.now() / 1000 + time
-    Kountdown({
-      endDate: endTime,
-      onUpdate: function (time) {
-        const timeColor = data.style.timeColor || '#000'
-        const result = formatDateTime(time, data.attr.formatterValue, timeColor)
-        node.innerHTML = result
-      },
-      onEnd: function () {
-      }
-    }).start()
-
-    return node
-  }
-}
-
-const style = {
-  textColor: function (value) {
-    this.node.style.color = value
-  }
-}
-
-function init (Weex) {
-  const Atomic = Weex.Atomic
-  const extend = Weex.utils.extend
-
-  function Countdown (data) {
-    Atomic.call(this, data)
-  }
-  Countdown.prototype = Object.create(Atomic.prototype)
-  extend(Countdown.prototype, proto)
-  extend(Countdown.prototype, {
-    style: extend(Object.create(Atomic.prototype.style), style)
-  })
-
-  Weex.registerComponent('countdown', Countdown)
-}
-
-export default { init }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/datepicker.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/datepicker.js b/html5/render/browser/extend/components/datepicker.js
deleted file mode 100644
index a3c58b2..0000000
--- a/html5/render/browser/extend/components/datepicker.js
+++ /dev/null
@@ -1,62 +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.
- */
-'use strict'
-
-const proto = {
-  create () {
-    const node = document.createElement('input')
-    const uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
-    this.className = 'weex-ipt-' + uuid
-    this.styleId = 'weex-style-' + uuid
-    node.classList.add(this.className)
-    node.setAttribute('type', 'date')
-    node.type = 'date'
-    // For the consistency of input component's width.
-    // The date and time type of input will have a bigger width
-    // when the 'box-sizing' is not set to 'border-box'
-    node.classList.add('weex-element')
-    return node
-  }
-}
-
-const attr = {
-  disabled: function (val) {
-    this.node.disabled = val && val !== 'false'
-  }
-}
-
-function init (Weex) {
-  const Atomic = Weex.Atomic
-  const extend = Weex.utils.extend
-
-  // attrs:
-  //   - value
-  //   - disabled
-  function Datepicker (data) {
-    Atomic.call(this, data)
-  }
-  Datepicker.prototype = Object.create(Atomic.prototype)
-  extend(Datepicker.prototype, proto)
-  extend(Datepicker.prototype, { attr })
-
-  Weex.registerComponent('datepicker', Datepicker)
-}
-
-export default { init }
-

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/embed.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/embed.js b/html5/render/browser/extend/components/embed.js
deleted file mode 100644
index 0caeea1..0000000
--- a/html5/render/browser/extend/components/embed.js
+++ /dev/null
@@ -1,100 +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.
- */
-'use strict'
-
-const ID_PREFIX = 'weex_embed_'
-
-let getRandom
-
-function _generateId () {
-  return ID_PREFIX + getRandom(10)
-}
-
-const proto = {
-  create () {
-    const node = document.createElement('div')
-    node.id = this.id
-    node.style.overflow = 'scroll'
-    return node
-  },
-
-  initWeex () {
-    this.id = _generateId()
-    this.node.id = this.id
-    const config = {
-      appId: this.id,
-      source: this.source,
-      bundleUrl: this.source,
-      loader: this.loader,
-      jsonpCallback: this.jsonpCallback,
-      width: this.node.getBoundingClientRect().width,
-      rootId: this.id,
-      embed: true
-    }
-    window.weex.init(config)
-  },
-
-  destroyWeex () {
-    this.id && window.destroyInstance(this.id)
-    // TODO: unbind events and clear doms.
-    this.node.innerHTML = ''
-  },
-
-  reloadWeex () {
-    if (this.id) {
-      this.destroyWeex()
-      this.id = null
-      this.node.id = null
-      this.node.innerHTML = ''
-    }
-    this.initWeex()
-  }
-}
-
-// not recommended, because of the leak of memory.
-const attr = {
-  src: function (value) {
-    this.source = value
-    this.reloadWeex()
-  }
-}
-
-function init (Weex) {
-  const Component = Weex.Component
-  const extend = Weex.utils.extend
-  getRandom = Weex.utils.getRandom
-
-  function Embed (data, nodeType) {
-    const attr = data.attr
-    if (attr) {
-      this.source = attr.src
-      this.loader = attr.loader || 'xhr'
-      this.jsonpCallback = attr.jsonpCallback
-    }
-    Component.call(this, data, nodeType)
-  }
-
-  Embed.prototype = Object.create(Component.prototype)
-  extend(Embed.prototype, proto)
-  extend(Embed.prototype, { attr })
-
-  Weex.registerComponent('embed', Embed)
-}
-
-export default { init }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/image/image.css
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/image/image.css b/html5/render/browser/extend/components/image/image.css
deleted file mode 100644
index b45e3b4..0000000
--- a/html5/render/browser/extend/components/image/image.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.weex-img {
-  background-repeat: no-repeat;
-  background-size: 100% 100%;
-  background-position: 50%;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/image/index.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/image/index.js b/html5/render/browser/extend/components/image/index.js
deleted file mode 100644
index a66e0d6..0000000
--- a/html5/render/browser/extend/components/image/index.js
+++ /dev/null
@@ -1,126 +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.
- */
-/* global lib */
-
-'use strict'
-
-import './image.css'
-
-const DEFAULT_SIZE = 200
-const RESIZE_MODES = ['stretch', 'cover', 'contain']
-const DEFAULT_RESIZE_MODE = 'stretch'
-
-let Atomic
-
-/**
- * resize: 'cover' | 'contain' | 'stretch', default is 'stretch'
- * src: url
- * placeholder / place-holder: url
- */
-const proto = {
-  create () {
-    const node = document.createElement('div')
-    node.classList.add('weex-img')
-    node.classList.add('weex-element')
-    return node
-  },
-
-  clearAttr () {
-    this.src = ''
-    this.node.style.backgroundImage = ''
-  }
-}
-
-const attr = {
-  src: function (val) {
-    if (!this.src) {
-      this.src = lib.img.defaultSrc
-      this.node.style.backgroundImage = 'url(' + this.src + ')'
-    }
-    this.enableLazyload(val)
-  },
-
-  placeholder: function (val) {
-    this.node.dataset.placeholder = val
-  },
-
-  // alias for placeholder (place-holder)
-  placeHolder: function (val) {
-    return this.attr.placeholder.call(this, val)
-  },
-
-  resize: function (val) {
-    if (RESIZE_MODES.indexOf(val) === -1) {
-      val = 'stretch'
-    }
-    this.node.style.backgroundSize = val === 'stretch'
-                                    ? '100% 100%'
-                                    : val
-  }
-}
-
-const style = {
-  width: function (val) {
-    val = parseFloat(val)
-    if (val < 0 || isNaN(val)) {
-      val = DEFAULT_SIZE
-    }
-    this.node.style.width = val + 'px'
-  },
-
-  height: function (val) {
-    val = parseFloat(val)
-    if (val < 0 || isNaN(val)) {
-      val = DEFAULT_SIZE
-    }
-    this.node.style.height = val + 'px'
-  }
-}
-
-const event = {
-  load: {
-    extra: function () {
-      const { naturalWidth, naturalHeight } = this.node
-      return {
-        naturalWidth, naturalHeight
-      }
-    }
-  }
-}
-
-function init (Weex) {
-  Atomic = Weex.Atomic
-  const extend = Weex.utils.extend
-
-  function Image (data) {
-    this.resize = DEFAULT_RESIZE_MODE
-    Atomic.call(this, data)
-  }
-  Image.prototype = Object.create(Atomic.prototype)
-  extend(Image.prototype, proto)
-  extend(Image.prototype, { attr })
-  extend(Image.prototype, {
-    style: extend(Object.create(Atomic.prototype.style), style)
-  })
-  extend(Image.prototype, { event })
-
-  Weex.registerComponent('image', Image)
-}
-
-export default { init }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/indicator/index.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/indicator/index.js b/html5/render/browser/extend/components/indicator/index.js
deleted file mode 100644
index 3801bc0..0000000
--- a/html5/render/browser/extend/components/indicator/index.js
+++ /dev/null
@@ -1,197 +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.
- */
-'use strict'
-
-import './indicator.css'
-
-const DEFAULT_ITEM_COLOR = '#999'
-const DEFAULT_ITEM_SELECTED_COLOR = '#0000ff'
-const DEFAULT_ITEM_SIZE = 20
-const DEFAULT_MARGIN_SIZE = 10
-
-function resetColor (indicator) {
-  const len = indicator.items.length
-  if (typeof indicator.index !== 'undefined' && len > indicator.index) {
-    for (let i = 0; i < len; i++) {
-      const item = indicator.items[i]
-      if (indicator.index === i) {
-        item.classList.add('active')
-        item.style.backgroundColor = indicator.itemSelectedColor
-      }
-      else {
-        item.style.backgroundColor = indicator.itemColor
-      }
-    }
-  }
-}
-
-function handleClick (indicator, idx, e) {
-  indicator.slider.slideTo(idx)
-}
-
-const proto = {
-  create () {
-    const node = document.createElement('div')
-    node.classList.add('weex-indicators')
-    node.classList.add('weex-element')
-    node.style.position = 'absolute'
-    this.node = node
-    this.style.itemSize.call(this, 0)
-    this.updateStyle({
-      left: 0,
-      top: 0,
-      itemSize: 0
-    })
-    return node
-  },
-
-  createChildren () {
-    const root = document.createDocumentFragment()
-    for (let i = 0; i < this.amount; i++) {
-      const indicator = document.createElement('div')
-      indicator.classList.add('weex-indicator')
-      indicator.style.boxSizing = 'border-box'
-      indicator.style.margin = '0 '
-                              + DEFAULT_MARGIN_SIZE
-                              + 'px'
-      indicator.style.width = this.itemSize + 'px'
-      indicator.style.height = this.itemSize + 'px'
-      indicator.setAttribute('index', i)
-      if (this.index === i) {
-        indicator.classList.add('active')
-        indicator.style.backgroundColor = this.itemSelectedColor
-      }
-      else {
-        indicator.style.backgroundColor = this.itemColor
-      }
-      indicator.addEventListener('click', handleClick.bind(null, this, i))
-      this.items[i] = indicator
-      root.appendChild(indicator)
-    }
-    this.node.appendChild(root)
-  },
-
-  setIndex (idx) {
-    if (idx >= this.amount) {
-      return
-    }
-    const prev = this.items[this.index]
-    const cur = this.items[idx]
-    prev.classList.remove('active')
-    prev.style.backgroundColor = this.itemColor
-    cur.classList.add('active')
-    cur.style.backgroundColor = this.itemSelectedColor
-    this.index = idx
-  }
-}
-
-const style = {
-  itemColor (val) {
-    this.itemColor = val || DEFAULT_ITEM_COLOR
-    resetColor(this)
-  },
-
-  itemSelectedColor (val) {
-    this.itemSelectedColor = val || DEFAULT_ITEM_SELECTED_COLOR
-    resetColor(this)
-  },
-
-  itemSize (val) {
-    val = parseInt(val) || DEFAULT_ITEM_SIZE
-    this.itemSize = val
-    this.node.style.height = val + 'px'
-    for (let i = 0, l = this.items.length; i < l; i++) {
-      this.items[i].style.width = val + 'px'
-      this.items[i].style.height = val + 'px'
-    }
-  },
-
-  width (val) {
-    val = parseInt(val) || parseInt(this.sliderWidth)
-    this.virtualWrapperWidth = val
-  },
-
-  height (val) {
-    val = parseInt(val) || parseInt(this.sliderHeight)
-    this.virtualWrapperHeight = val
-  },
-
-  top (val) {
-    val = this.virtualWrapperHeight / 2 - this.itemSize / 2 + val
-    this.node.style.bottom = ''
-    this.node.style.top = val + 'px'
-  },
-
-  bottom (val) {
-    val = this.virtualWrapperHeight / 2 - this.itemSize / 2 + val
-    this.node.style.top = ''
-    this.node.style.bottom = val + 'px'
-  },
-
-  left (val) {
-    val = this.virtualWrapperWidth / 2
-          - (this.itemSize + 2 * DEFAULT_MARGIN_SIZE) * this.amount / 2 + val
-    this.node.style.right = ''
-    this.node.style.left = val + 'px'
-  },
-
-  right (val) {
-    val = this.virtualWrapperWidth / 2
-          - (this.itemSize + 2 * DEFAULT_MARGIN_SIZE) * this.amount / 2 + val
-    this.node.style.left = ''
-    this.node.style.right = val + 'px'
-  }
-}
-
-function init (Weex) {
-  const Atomic = Weex.Atomic
-  const extend = Weex.utils.extend
-
-  // Style supported:
-  //   position: (default - absolute)
-  //   itemColor: color of indicator dots
-  //   itemSelectedColor: color of the selected indicator dot
-  //   itemSize: size of indicators
-  //   other layout styles
-  function Indicator (data) {
-    this.direction = 'row' // 'column' is not temporarily supported.
-    this.amount = data.extra.amount
-    this.index = data.extra.index
-    this.sliderWidth = data.extra.width
-    this.sliderHeight = data.extra.height
-    const styles = data.style || {}
-    this.data = data
-    this.style.width.call(this, styles.width)
-    this.style.height.call(this, styles.height)
-    this.itemColor = styles.itemColor || DEFAULT_ITEM_COLOR
-    this.itemSelectedColor = styles.itemSelectedColor
-      || DEFAULT_ITEM_SELECTED_COLOR
-    this.items = []
-    Atomic.call(this, data)
-  }
-  Indicator.prototype = Object.create(Atomic.prototype)
-  extend(Indicator.prototype, proto)
-  extend(Indicator.prototype, {
-    style: extend(Object.create(Atomic.prototype.style), style)
-  })
-
-  Weex.registerComponent('indicator', Indicator)
-}
-
-export default { init }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/indicator/indicator.css
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/indicator/indicator.css b/html5/render/browser/extend/components/indicator/indicator.css
deleted file mode 100644
index 8c3b9bf..0000000
--- a/html5/render/browser/extend/components/indicator/indicator.css
+++ /dev/null
@@ -1,8 +0,0 @@
-.weex-indicators {
-  position: absolute;
-  white-space: nowrap;
-}
-.weex-indicators .weex-indicator {
-  float: left;
-  border-radius: 50%;
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/input.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/input.js b/html5/render/browser/extend/components/input.js
deleted file mode 100644
index e867f82..0000000
--- a/html5/render/browser/extend/components/input.js
+++ /dev/null
@@ -1,192 +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.
- */
-'use strict'
-import { findEnterKeyType } from '../../utils/index'
-
-let appendStyle
-
-const availableTypes = ['text', 'password', 'tel', 'email', 'url', 'date', 'time']
-const DEFAULT_TYPE = 'text'
-
-function setPlaceholderColor (input, placeholderColor) {
-  if (!placeholderColor) {
-    return
-  }
-  const vendors = [
-    '::-webkit-input-placeholder',
-    ':-moz-placeholder',
-    '::-moz-placeholder',
-    ':-ms-input-placeholder',
-    ':placeholder-shown'
-  ]
-  let css = ''
-  const cssRule = 'color: ' + placeholderColor + ';'
-  for (let i = 0, l = vendors.length; i < l; i++) {
-    css += '.' + input.className + vendors[i] + '{'
-           + cssRule + '}'
-  }
-  appendStyle(css, input.styleId, true)
-}
-
-const proto = {
-  create () {
-    const node = document.createElement('input')
-    const uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
-    this.className = 'weex-ipt-' + uuid
-    this.styleId = 'weex-style-' + uuid
-    node.classList.add(this.className)
-    node.classList.add('weex-element')
-    this.placeholder && (node.placeholder = this.placeholder)
-    this.createKeybordEvent(node)
-    return node
-  },
-
-  // support enter key envent
-  createKeybordEvent (node) {
-    if (Array.isArray(this.data.event) && this.data.event.indexOf('return') > -1) {
-      node.addEventListener('keyup', (ev) => {
-        const code = ev.keyCode
-        let key = ev.key
-        if (code === 13) {
-          if (key.toLowerCase() === 'tab') {
-            key = 'next'
-          }
-          const rightKeyType = findEnterKeyType(this.data.attr['returnKeyType'])
-          this.dispatchEvent('return', { returnKeyType: rightKeyType })
-        }
-      }, false)
-    }
-  },
-
-  focus () {
-    this.node.focus()
-  },
-
-  blur () {
-    this.node.blur()
-  }
-}
-
-// updatable attributes
-const attr = {
-  disabled (val) {
-    this.node.disabled = !!val
-  },
-
-  placeholder (val) {
-    this.node.placeholder = val || ''
-  },
-
-  value (val) {
-    this.node.value = val || ''
-  },
-
-  autofocus (val) {
-    this.node.autofocus = !!val
-  },
-
-  type (val) {
-    this.node.type = availableTypes.indexOf(val) !== -1
-      ? val
-      : DEFAULT_TYPE
-  },
-
-  returnKeyType (val) {
-    this.node.returnKeyType = val || ''
-  }
-}
-
-// updatable styles
-const style = {
-  placeholderColor: function (val) {
-    setPlaceholderColor(this, val)
-  }
-}
-
-// events configurations
-const event = {
-  input: {
-    updator () {
-      return {
-        attrs: {
-          value: this.node.value
-        }
-      }
-    },
-    extra () {
-      return {
-        value: this.node.value,
-        timestamp: Date.now()
-      }
-    }
-  },
-
-  change: {
-    updator: function () {
-      return {
-        attrs: {
-          value: this.node.value
-        }
-      }
-    },
-    extra: function () {
-      return {
-        value: this.node.value,
-        timestamp: Date.now()
-      }
-    }
-  },
-
-  return: {
-    updator: function (obj) {
-      return {
-        attrs: {
-          value: this.node.value
-        }
-      }
-    }
-  }
-}
-
-function init (Weex) {
-  const Atomic = Weex.Atomic
-  const extend = Weex.utils.extend
-  appendStyle = Weex.utils.appendStyle
-
-  // attrs:
-  //   - type: text|password|tel|email|url
-  //   - value
-  //   - placeholder
-  //   - disabled
-  //   - autofocus
-  function Input (data) {
-    Atomic.call(this, data)
-  }
-  Input.prototype = Object.create(Atomic.prototype)
-  extend(Input.prototype, proto)
-  extend(Input.prototype, { attr })
-  extend(Input.prototype, {
-    style: extend(Object.create(Atomic.prototype.style), style)
-  })
-  extend(Input.prototype, { event })
-
-  Weex.registerComponent('input', Input)
-}
-
-export default { init }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/marquee.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/marquee.js b/html5/render/browser/extend/components/marquee.js
deleted file mode 100644
index 0e5d659..0000000
--- a/html5/render/browser/extend/components/marquee.js
+++ /dev/null
@@ -1,301 +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.
- */
-'use strict'
-
-const proto = {
-  create () {
-    const node = document.createElement('div')
-    node.classList.add('weex-container')
-    node.style.overflow = 'hidden'
-    // fix page shaking during slider's playing
-    node.style.webkitTransform = 'translate3D(0,0,0)'
-    node.addEventListener('webkitTransitionEnd', this.end.bind(this), false)
-    return node
-  },
-
-  createChildren () {
-    // first run:
-    // - create each child
-    // - append to parentNode
-    // - find current and next
-    // - set current and next shown and others hidden
-    const children = this.data.children
-    const parentRef = this.data.ref
-    const instanceId = this.data.instanceId
-    const items = []
-    const componentManager = this.getComponentManager()
-
-    let fragment, isFlex, child, i
-
-    if (children && children.length) {
-      fragment = document.createDocumentFragment()
-      isFlex = false
-      for (i = 0; i < children.length; i++) {
-        children[i].instanceId = instanceId
-        child = componentManager.createElement(children[i])
-        child.parentRef = parentRef
-        this.initChild(child)
-        // append and push
-        items.push(child)
-        fragment.appendChild(child.node)
-        if (!isFlex && child.data.style.hasOwnProperty('flex')) {
-          isFlex = true
-        }
-      }
-      this.node.appendChild(fragment)
-    }
-
-    // set items
-    this.items = items
-
-    // reset the clock for first transition
-    this.reset()
-  },
-
-  appendChild (data) {
-    // dom + items
-    const componentManager = this.getComponentManager()
-    // const componentManager = ComponentManager.getInstance(this.data.instanceId)
-    const child = componentManager.createElement(data)
-    this.initChild(child)
-    this.node.appendChild(child.node)
-    this.items.push(child)
-    this.reset()
-    return child // @todo redesign Component#appendChild(component)
-  },
-
-  insertBefore (child, before) {
-    // dom + items
-    const index = this.items.indexOf(before)
-    this.items.splice(index, 0, child)
-    this.initChild(child)
-    this.node.insertBefore(child.node, before.node)
-    this.reset()
-  },
-
-  removeChild (child) {
-    // dom + items
-    const index = this.items.indexOf(child)
-    this.items.splice(index, 1)
-    this.node.removeChild(child.node)
-    this.reset()
-  },
-
-  initChild (child) {
-    const node = child.node
-    node.style.position = 'absolute'
-    node.style.top = '0'
-    node.style.left = '0'
-  },
-
-  /**
-   * status: {
-   *   current: {translateY: 0, shown: true},
-   *   next: {translateY: height, shown: true},
-   *   others[]: {shown: false}
-   *   index: index
-   * }
-   */
-  reset () {
-    const interval = this.interval - 0
-    const delay = this.delay - 0
-    const items = this.items
-    const self = this
-
-    const loop = function () {
-      self.next()
-      self.timerId = setTimeout(loop, self.interval)
-    }
-
-    // reset display and transform
-    items.forEach(function (item, index) {
-      const node = item.node
-      // set non-current(0)|next(1) item hidden
-      node.style.display = index > 1 ? 'none' : ''
-      // set next(1) item translateY
-      // TODO: it supposed to use item.data.style
-      // but somehow the style object is empty.
-      // This problem relies on jsframework's bugfix.
-
-      // node.style.transform = index === 1
-      //     ? 'translate3D(0,' + item.data.style.height + 'px,0)'
-      //     : ''
-      // node.style.webkitTransform = index === 1
-      //     ? 'translate3D(0,' + item.data.style.height + 'px,0)'
-      //     : ''
-      node.style.transform = index === 1
-          ? 'translate3D(0,' + self.data.style.height + 'px,0)'
-          : ''
-      node.style.webkitTransform = index === 1
-          ? 'translate3D(0,' + self.data.style.height + 'px,0)'
-          : ''
-    })
-
-    setTimeout(function () {
-      // reset current, next, index
-      self.currentItem = items[0]
-      self.nextItem = items[1]
-      self.currentIndex = 0
-
-      items.forEach(function (item, index) {
-        const node = item.node
-        // set transition
-        node.style.transition = 'transform '
-            + self.transitionDuration
-            + 'ms ease'
-        node.style.webkitTransition = '-webkit-transform '
-            + self.transitionDuration
-            + 'ms ease'
-      })
-
-      clearTimeout(self.timerId)
-
-      if (items.length > 1) {
-        self.timerId = setTimeout(loop, delay + interval)
-      }
-    }, 13)
-  },
-
-  /**
-   * next:
-   * - current: {translateY: -height}
-   * - next: {translateY: 0}
-   */
-  next () {
-    // - update state
-    //   - set current and next transition
-    //   - hide current when transition end
-    //   - set next to current
-    //   - find new next
-    const next = this.nextItem.node
-    const current = this.currentItem.node
-    this.transitionIndex = this.currentIndex
-
-    // Use setTimeout to fix the problem that when the
-    // page recover from backstage, the slider will
-    // not work any longer.
-    setTimeout(function () {
-      next.style.transform = 'translate3D(0,0,0)'
-      next.style.webkitTransform = 'translate3D(0,0,0)'
-      current.style.transform = 'translate3D(0,-'
-          + this.data.style.height
-          + 'px,0)'
-      current.style.webkitTransform = 'translate3D(0,-'
-          + this.data.style.height
-          + 'px,0)'
-      this.fireEvent('change')
-    }.bind(this), 300)
-  },
-
-  fireEvent (type) {
-    const length = this.items.length
-    const nextIndex = (this.currentIndex + 1) % length
-    const evt = document.createEvent('HTMLEvents')
-    evt.initEvent(type, false, false)
-    evt.data = {
-      prevIndex: this.currentIndex,
-      index: nextIndex
-    }
-    this.node.dispatchEvent(evt)
-  },
-
-  /**
-   * end:
-   * - old current: {shown: false}
-   * - old current: {translateY: 0}
-   * - index++ % length
-   * - new current = old next
-   * - new next = items[index+1 % length]
-   * - new next: {translateY: height}
-   * - new next: {shown: true}
-   */
-  end (e) {
-    const items = this.items
-    const length = items.length
-    let currentIndex
-
-    currentIndex = this.transitionIndex
-
-    if (isNaN(currentIndex)) {
-      return
-    }
-    delete this.transitionIndex
-
-    const current = this.currentItem.node
-    current.style.display = 'none'
-    current.style.webkitTransform = ''
-
-    currentIndex = (currentIndex + 1) % length
-    const nextIndex = (currentIndex + 1) % length
-
-    this.currentIndex = currentIndex
-    this.currentItem = this.nextItem
-    this.nextItem = items[nextIndex]
-
-    setTimeout(function () {
-      const next = this.nextItem.node
-      // TODO: it supposed to use this.nextItem.data.style
-      // but somehow the style object is empty.
-      // This problem relies on jsframework's bugfix.
-
-      next.style.webkitTransform = 'translate3D(0,'
-          + this.data.style.height
-          + 'px,0)'
-      next.style.display = ''
-      this.fireLazyload(next)
-    }.bind(this))
-  },
-
-  clearAttr () {
-    this.interval = 5 * 1000
-    this.transitionDuration = 500
-    this.delay = 0
-  }
-}
-
-const attr = {
-  interval: function (value) {
-    this.interval = value
-  },
-  transitionDuration: function (value) {
-    this.transitionDuration = value
-  },
-  delay: function (value) {
-    this.delay = value
-  }
-}
-
-function init (Weex) {
-  const Component = Weex.Component
-  const extend = Weex.utils.extend
-
-  function Marquee (data) {
-    this.interval = Number(data.attr.interval) || 5 * 1000
-    this.transitionDuration = Number(data.attr.transitionDuration) || 500
-    this.delay = Number(data.attr.delay) || 0
-    Component.call(this, data)
-  }
-  Marquee.prototype = Object.create(Component.prototype)
-  extend(Marquee.prototype, proto)
-  extend(Marquee.prototype, { attr })
-
-  Weex.registerComponent('marquee', Marquee)
-}
-
-export default { init }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/neighbor/index.js
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/neighbor/index.js b/html5/render/browser/extend/components/neighbor/index.js
deleted file mode 100644
index da06d79..0000000
--- a/html5/render/browser/extend/components/neighbor/index.js
+++ /dev/null
@@ -1,656 +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.
- */
-/* global lib */
-
-'use strict'
-
-import './neighbor.css'
-
-const DEFAULT_INTERVAL = 3000
-const DEFAULT_NEIGHBOR_SPACE = 20
-const DEFAULT_NEIGHBOR_ALPHA = 0.6
-const DEFAULT_NEIGHBOR_SCALE = 0.8
-
-const TRANSITION_DURATION = 400
-
-const MAIN_SLIDE_SCALE = 0.9
-const MAIN_SLIDE_OPACITY = 1
-
-let extend, Component
-
-function idleWhenPageDisappear (slider) {
-  function handlePageShow () {
-    slider.isPageShow = true
-    slider.autoPlay && !slider.isDomRendering && slider.play()
-  }
-  function handlePageHide () {
-    slider.isPageShow = false
-    slider.stop()
-  }
-  global.addEventListener('pageshow', handlePageShow)
-  global.addEventListener('pagehide', handlePageHide)
-  document.addEventListener('visibilitychange', function () {
-    if (document.visibilityState === 'visible') {
-      handlePageShow()
-    }
-    else if (document.visibilityState === 'hidden') {
-      handlePageHide()
-    }
-  })
-}
-
-function idleWhenDomRendering (slider) {
-  global.addEventListener('renderend', function () {
-    slider.isDomRendering = false
-    slider.autoPlay && slider.isPageShow && slider.play()
-  })
-  global.addEventListener('renderbegin', function () {
-    slider.isDomRendering = true
-    slider.stop()
-  })
-}
-
-function _renderIndicators (slider, ct, data) {
-  data.extra.width = data.style.width || slider.width
-  data.extra.height = data.style.height || slider.height
-  const indicator = slider.getComponentManager().createElement(data)
-  indicator.parentRef = slider.data.ref
-  indicator.slider = slider
-  slider.indicator = indicator
-  ct.appendChild(indicator.node)
-}
-
-function renderIndicators (slider, ct, data) {
-  setTimeout(() => _renderIndicators(slider, ct, data), 0)
-}
-
-function updateIndicators (slider) {
-  slider.indicator && slider.indicator.setIndex(slider.currentIndex)
-}
-
-function transitionOnce (node, duration, timingFunc) {
-  const transitionStr = `all ${duration}ms ${timingFunc}`
-  node.style.webkitTransition = transitionStr
-  node.style.transition = transitionStr
-  setTimeout(function () {
-    node.style.webkitTransition = ''
-    node.style.transition = ''
-  }, duration)
-}
-
-function animateTransform (node, style, duration, timeFunction) {
-  transitionOnce(node, duration || TRANSITION_DURATION, timeFunction || 'ease')
-  for (const k in style) {
-    node.style[k] = style[k]
-  }
-}
-
-function transformSlide (slider, index) {
-  const node = slider.slides[index].node
-  node.style.opacity = slider.neighborAlpha
-  const transformStr = `scale(${slider.neighborScale})`
-  node.style.webkitTransform = transformStr
-  node.style.transform = transformStr
-  node.style.width = slider.width + 'px'
-  node.style.height = slider.height + 'px'
-  node.style.position = 'absolute'
-  node.style.top = '0px'
-  node.style.left = '0px'
-}
-
-function loadImg (slider) {
-  const imgs1 = slider.node.querySelectorAll('[img-src]') || []
-  const imgs2 = slider.node.querySelectorAll('[i-lazy-src]') || []
-  function load (node) {
-    const src = node.getAttribute('img-src') || node.getAttribute('i-lazy-src')
-    lib.img.applySrc(node, src, node.dataset.placeholder)
-  }
-  for (let i = 0; i < imgs1.length; i++) {
-    load(imgs1[i])
-  }
-  for (let i = 0; i < imgs2.length; i++) {
-    load(imgs2[i])
-  }
-}
-
-function _doRender (slider) {
-  loadImg(slider)
-  slider.total = slider.slides.length
-  slider.currentIndex = 0
-  const width = slider.data.style.width || 0
-  const height = slider.data.style.height || 0
-  slider.width = parseFloat(width) || slider.node.getBoundingClientRect().width
-  slider.height = parseFloat(height) || slider.node.getBoundingClientRect().height
-
-  const l = slider.slides.length
-  for (let i = 0; i < l; i++) {
-    transformSlide(slider, i)
-  }
-
-  setTimeout(() => slider.slideTo(0), 0)
-}
-
-function doRender (slider) {
-  setTimeout(_doRender.bind(null, slider), 0)
-}
-
-function loopIndex (idx, total) {
-  if (total === 0) {
-    return 0
-  }
-  return (total + idx) % total
-}
-
-function autoPlay (slider) {
-  const next = slider.currentIndex + 1
-  setTimeout(() => slider.slideTo(next), 0)
-  slider.playTimer = setTimeout(() => autoPlay(slider), slider.interval + TRANSITION_DURATION)
-}
-
-function useGesture (slider) {
-  const node = slider.node
-  let displacement, panning
-
-  node.addEventListener('panstart', function (e) {
-    if (!e.isVertical) {
-      e.preventDefault()
-      e.stopPropagation()
-      slider.stop()
-      panning = true
-      displacement = 0
-    }
-  })
-
-  node.addEventListener('panmove', function (e) {
-    if (!e.isVertical && panning) {
-      e.preventDefault()
-      e.stopPropagation()
-      const displacement = e.displacementX
-      moveSlides(slider, displacement)
-    }
-  })
-
-  node.addEventListener('panend', function (e) {
-    if (!e.isVertical && panning) {
-      e.preventDefault()
-      e.stopPropagation()
-      displacement = e.displacementX
-      if (e.isSwipe) {
-        if (displacement < 0) {
-          slider.slideToNext()
-        }
-        else {
-          slider.slideToPrev()
-        }
-      }
-      else {
-        if (Math.abs(displacement) < slider.width / 2) {
-          slider.slideTo(slider.currentIndex)
-        }
-        else if (displacement < 0) {
-          slider.slideToNext()
-        }
-        else {
-          slider.slideToPrev()
-        }
-      }
-      panning = false
-      slider.play()
-    }
-  })
-
-  node.addEventListener('swipe', function (e) {
-    if (!e.isVertical) {
-      e.preventDefault()
-      e.stopPropagation()
-    }
-  })
-}
-
-function moveSlides (slider, offset) {
-  const mainTransformStr = `translate(${offset}px, 0px) scale(${MAIN_SLIDE_SCALE})`
-  const mainNode = slider.mainSlide.node
-  mainNode.style.webkitTransform = mainTransformStr
-  mainNode.style.transform = mainTransformStr
-
-  const leftTransformStr = `translate(${slider.leftTranslate + offset}px, 0px) scale(${slider.neighborScale})`
-  const leftNode = slider.leftSlide.node
-  leftNode.style.webkitTransform = leftTransformStr
-  leftNode.style.transform = leftTransformStr
-
-  const rightTransformStr = `translate(${slider.rightTranslate + offset}px, 0px) scale(${slider.neighborScale})`
-  const rightNode = slider.rightSlide.node
-  rightNode.style.webkitTransform = rightTransformStr
-  rightNode.style.transform = rightTransformStr
-}
-
-function resetSideSlidePos (slider, side) {
-  const signMap = { left: '-', right: '' }
-  const transformStr = `translate(${signMap[side] + slider.width}px, 0px)`
-  const node = slider[side + 'Slide'].node
-  node.style.webkitTransform = transformStr
-  node.style.transform = transformStr
-}
-
-function resetOutsideSlides (slider, indexArr) {
-  indexArr = indexArr || []
-  const l = slider.slides.length
-  for (let i = 0; i < l; i++) {
-    if (indexArr.indexOf(i) <= -1) {
-      slider.slides[i].node.style.opacity = 0
-    }
-  }
-}
-
-const proto = {
-  create () {
-    const node = document.createElement('div')
-    this.node = node
-    node.classList.add('slider-neighbor')
-    node.classList.add('weex-container')
-    this.style.flexDirection.call(this, 'row')
-    node.style.position = 'relative'
-    node.style.overflow = 'hidden'
-    return node
-  },
-
-  createChildren () {
-    const componentManager = this.getComponentManager()
-
-    const children = this.data.children
-    const fragment = document.createDocumentFragment()
-
-    if (children && children.length) {
-      for (let i = 0; i < children.length; i++) {
-        let child
-        const data = children[i]
-        data.instanceId = this.data.instanceId
-        // 'indicator' maybe the last child of this component.
-        if (data.type !== 'indicator') {
-          child = componentManager.createElement(data)
-          child.node.classList.add('weex-neighbor-item')
-          const width = (data.style || {}).width || this.data.style.width
-          const height = (data.style || {}).height || this.data.style.height
-          child.node.style.marginTop = -(height / 2) + 'px'
-          child.node.style.marginLeft = -(width / 2) + 'px'
-          this.slides.push(child)
-          fragment.appendChild(child.node)
-          child.parentRef = this.data.ref
-        }
-        else {
-          renderIndicators(this, fragment, extend(data, {
-            extra: {
-              amount: children.length - 1,
-              index: 0
-            }
-          }))
-        }
-      }
-      resetOutsideSlides(this, [])
-      this.node.appendChild(fragment)
-      doRender(this)
-    }
-  },
-
-  appendChild (data) {
-    const children = this.data.children
-    const componentManager = this.getComponentManager()
-    let child
-
-    if (data.type === 'indicator') {
-      renderIndicators(this, this.node, extend(data, {
-        extra: {
-          amount: children.length,
-          index: this.currentIndex
-        }
-      }))
-    }
-    else {
-      child = componentManager.createElement(data)
-      child.node.classList.add('weex-neighbor-item')
-      const width = (data.style || {}).width || this.data.style.width
-      const height = (data.style || {}).height || this.data.style.height
-      child.node.style.marginTop = -(height / 2) + 'px'
-      child.node.style.marginLeft = -(width / 2) + 'px'
-      this.slides.push(child)
-      resetOutsideSlides(this, [])
-      this.node.appendChild(child.node)
-    }
-
-    doRender(this)
-
-    if (!children || !children.length) {
-      this.data.children = [data]
-    }
-    else {
-      children.push(data)
-    }
-
-    return child || this.indicator
-  },
-
-  insertBefore (child, before) {
-    const children = this.data.children
-    let i = 0
-    let slidesIdx = 0
-    let isAppend = false
-    if (!children || !children.length || !before) {
-      isAppend = true
-    }
-    else {
-      let l
-      for (l = children.length; i < l; i++) {
-        if (children[i].ref === before.data.ref) {
-          break
-        }
-        if (children[i].type !== 'indicator') {
-          slidesIdx++
-        }
-      }
-      if (i === l) {
-        isAppend = true
-      }
-    }
-
-    child.node.classList.add('weex-neighbor-item')
-    const data = child.data
-    const width = (data.style || {}).width || this.data.style.width
-    const height = (data.style || {}).height || this.data.style.height
-    child.node.style.marginTop = -(height / 2) + 'px'
-    child.node.style.marginLeft = -(width / 2) + 'px'
-    if (isAppend) {
-      this.node.appendChild(child.node)
-      this.slides.push(child)
-      resetOutsideSlides(this, [])
-      children.push(child.data)
-    }
-    else {
-      this.node.insertBefore(child.node, before.node)
-      this.slides.splice(slidesIdx, 0, child)
-      children.splice(i, 0, child.data)
-    }
-
-    doRender(this)
-  },
-
-  removeChild (child) {
-    const children = this.data.children
-    let i = 0
-    let slidesIdx = 0
-    if (children && children.length) {
-      let l
-      for (l = children.length; i < l; i++) {
-        if (children[i].ref === child.data.ref) {
-          break
-        }
-        if (children[i].type !== 'indicator') {
-          slidesIdx++
-        }
-      }
-      if (i < l) {
-        children.splice(i, 1)
-        this.slides.splice(slidesIdx, 1)
-        resetOutsideSlides(this, [])
-      }
-    }
-
-    this.getComponentManager().removeComponent(child.data.ref)
-    child.node.parentNode.removeChild(child.node)
-
-    doRender(this)
-  },
-
-  onAppend () {
-    this.slideTo(0)
-    useGesture(this)
-    Component.prototype.onAppend.call(this)
-  },
-
-  play () {
-    // start playing
-    this.playTimer && clearTimeout(this.playTimer)
-    if (this.playstatus/* && !this.toggleOff*/) {
-      this.playTimer = setTimeout(autoPlay.bind(null, this), this.interval)
-    }
-  },
-
-  stop () {
-    // stop playing
-    this.playTimer && clearTimeout(this.playTimer)
-  },
-
-  slideTo (index, restartAutoplay) {
-    const total = this.slides.length
-    if (total === 0) {
-      return
-    }
-    if (restartAutoplay) {
-      this.stop()
-      setTimeout(() => this.play(), 100)
-    }
-    const origIdx = index
-    index = loopIndex(origIdx, total)
-    const leftIndex = loopIndex(index - 1, total)
-    const rightIndex = loopIndex(index + 1, total)
-
-    this.mainSlide = this.slides[index]
-    this.leftSlide = this.slides[loopIndex(index - 1, total)]
-    this.rightSlide = this.slides[loopIndex(index + 1, total)]
-
-    const mainTransformStr = `translate(0px, 0px) scale(${MAIN_SLIDE_SCALE})`
-    setTimeout(() => animateTransform(this.mainSlide.node, {
-      webkitTransform: mainTransformStr,
-      transform: mainTransformStr,
-      opacity: MAIN_SLIDE_OPACITY,
-      zIndex: 99
-    }), 100)
-
-    const translateX = this.width
-      - this.width * (1 - this.neighborScale) / 2
-      - this.neighborSpace
-    this.leftTranslate = -translateX
-    this.rightTranslate = translateX
-
-    if (origIdx > this.currentIndex) {
-      resetSideSlidePos(this, 'right')
-    }
-    else if (origIdx < this.currentIndex) {
-      resetSideSlidePos(this, 'left')
-    }
-
-    const leftTransformStr = `translate(${-translateX + 'px'}, 0px) scale(${this.neighborScale})`
-    setTimeout(() => animateTransform(this.leftSlide.node, {
-      webkitTransform: leftTransformStr,
-      transform: leftTransformStr,
-      opacity: this.neighborAlpha,
-      zIndex: 1
-    }), 100)
-
-    const rightTransformStr = `translate(${translateX + 'px'}, 0px) scale(${this.neighborScale})`
-    setTimeout(() => animateTransform(this.rightSlide.node, {
-      webkitTransform: rightTransformStr,
-      transform: rightTransformStr,
-      opacity: this.neighborAlpha,
-      zIndex: 1
-    }), 100)
-
-    resetOutsideSlides(this, [index, leftIndex, rightIndex])
-
-    this.currentIndex = index
-    updateIndicators(this)
-    this.dispatchEvent('change', { index: this.currentIndex })
-  },
-
-  slideToPrev () {
-    this.slideTo(this.currentIndex - 1)
-  },
-
-  slideToNext () {
-    this.slideTo(this.currentIndex + 1)
-  }
-}
-
-const attr = {
-  interval: function (val) {
-    this.interval = parseInt(val) || DEFAULT_INTERVAL
-  },
-
-  index: function (val) {
-    const _this = this
-    function doSlide (index) {
-      index = parseInt(index)
-      if (index < 0 || isNaN(index)) {
-        return console.error('[h5-render] invalid index ', index)
-      }
-      _this.stop()
-      _this.slideTo(index)
-      _this.autoPlay && _this.isPageShow && _this.play()
-      if (_this._updateIndex) {
-        window.removeEventListener('renderend', _this._updateIndex)
-      }
-    }
-    if (this.isDomRendering) {
-      const pre = !!this._updateIndex
-      this._updateIndex = function () {
-        doSlide(val)
-      }
-      !pre && window.addEventListener('renderend', this._updateIndex)
-    }
-    else {
-      doSlide(val)
-    }
-  },
-
-  playstatus: function (val) {
-    const _this = this
-    this.playstatus = val && val !== 'false'
-    this.autoPlay = this.playstatus
-
-    function doPlay () {
-      _this.isPageShow && _this.play()
-      if (_this._updatePlaystatus) {
-        window.removeEventListener('renderend', _this._updatePlaystatus)
-      }
-    }
-
-    if (this.playstatus) {
-      if (this.isDomRendering) {
-        const pre = !!this._updatePlaystatus
-        this._updatePlaystatus = function () {
-          doPlay()
-        }
-        !pre && window.addEventListener('renderend', this._updatePlaystatus)
-      }
-      else {
-        doPlay()
-      }
-    }
-    else {
-      this.stop()
-    }
-  },
-
-  // support playstatus' alias auto-play for compatibility
-  autoPlay: function (val) {
-    this.attr.playstatus.call(this, val)
-  },
-
-  neighborSpace (val) {
-    const ns = parseFloat(val)
-    if (!isNaN(ns) && ns >= 0) {
-      this.neighborSpace = ns
-    }
-    else {
-      console.warn(`[h5-render] invalid value for 'neighbor-space' of slider-neighbor: ${val}.`)
-    }
-  },
-
-  neighborAlpha (val) {
-    const na = parseFloat(val)
-    if (!isNaN(na) && na >= 0 && na <= 1) {
-      this.neighborAlpha = na
-    }
-    else {
-      console.warn(`[h5-render] invalid value for 'neighbor-alpha' of slider-neighbor: ${val}.`)
-    }
-  },
-
-  neighborScale (val) {
-    const ns = parseFloat(val)
-    if (!isNaN(ns) && ns >= 0 && ns <= 1) {
-      this.neighborScale = ns
-    }
-    else {
-      console.warn(`[h5-render] invalid value for 'neighbor-scale' of slider-neighbor: ${val}.`)
-    }
-  }
-}
-
-const event = {
-  change: {
-    updator: function () {
-      return {
-        attrs: {
-          index: this.currentIndex
-        }
-      }
-    }
-  }
-}
-
-function init (Weex) {
-  Component = Weex.Component
-  extend = Weex.utils.extend
-
-  /**
-   * data.attr
-   * support slider's attributes and three
-   * @param {number} neighbor-space 0 - 375, the exposing width of slides on both other sides.
-   * @param {number} neighbor-alpha 0 - 1, opacity of both other sides of slides, default is 0.6.
-   * @param {number} neighbor-scale 0 - 1, the scale of both other sides of slides, default is 0.8.
-   */
-  function SliderNeighbor (data) {
-    this.autoPlay = false  // default value is false.
-    this.interval = DEFAULT_INTERVAL
-    this.direction = 'row' // 'column' is not temporarily supported.
-    this.slides = []
-    this.isPageShow = true
-    this.isDomRendering = true
-    this.currentIndex = 0
-
-    this.neighborSpace = DEFAULT_NEIGHBOR_SPACE
-    this.neighborAlpha = DEFAULT_NEIGHBOR_ALPHA
-    this.neighborScale = DEFAULT_NEIGHBOR_SCALE
-
-    // bind event 'pageshow', 'pagehide' and 'visibilitychange' on window.
-    idleWhenPageDisappear(this)
-    // bind event 'renderBegin' and 'renderEnd' on window.
-    idleWhenDomRendering(this)
-
-    Component.call(this, data)
-  }
-  SliderNeighbor.prototype = Object.create(Component.prototype)
-  extend(SliderNeighbor.prototype, proto)
-  extend(SliderNeighbor.prototype, { attr })
-  extend(SliderNeighbor.prototype, { event })
-
-  Weex.registerComponent('slider-neighbor', SliderNeighbor)
-}
-
-export default { init }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ceef728d/html5/render/browser/extend/components/neighbor/neighbor.css
----------------------------------------------------------------------
diff --git a/html5/render/browser/extend/components/neighbor/neighbor.css b/html5/render/browser/extend/components/neighbor/neighbor.css
deleted file mode 100644
index 09a6382..0000000
--- a/html5/render/browser/extend/components/neighbor/neighbor.css
+++ /dev/null
@@ -1,11 +0,0 @@
-.weex-neighbor-item {
-  position: absolute !important;
-  top: 50% !important;
-  left: 50% !important;
-  -webkit-box-align: center;
-  -webkit-align-items: center;
-  align-items: center;
-  -webkit-box-pack: center;
-  -webkit-justify-content: center;
-  justify-content: center;
-}