Przeglądaj źródła

restructure (build pass)

Evan You 10 lat temu
rodzic
commit
955e2f8391
63 zmienionych plików z 256 dodań i 169 usunięć
  1. 4 4
      build/build.js
  2. 46 4
      src/compiler/codegen.js
  3. 0 6
      src/compiler/codegen/directives/html.js
  4. 0 43
      src/compiler/codegen/directives/index.js
  5. 0 6
      src/compiler/codegen/directives/text.js
  6. 1 1
      src/compiler/directives/ref.js
  7. 1 1
      src/compiler/events.js
  8. 17 10
      src/compiler/index.js
  9. 6 4
      src/compiler/optimizer.js
  10. 9 16
      src/compiler/parser/index.js
  11. 14 0
      src/core/config.js
  12. 2 2
      src/core/global-api/assets.js
  13. 0 0
      src/core/global-api/extend.js
  14. 1 2
      src/core/global-api/index.js
  15. 0 0
      src/core/global-api/mixin.js
  16. 0 0
      src/core/global-api/use.js
  17. 0 0
      src/core/index.js
  18. 0 0
      src/core/instance/events.js
  19. 0 0
      src/core/instance/index.js
  20. 2 3
      src/core/instance/lifecycle.js
  21. 0 0
      src/core/instance/proxy.js
  22. 0 0
      src/core/instance/render.js
  23. 0 0
      src/core/instance/state.js
  24. 0 0
      src/core/observer/array.js
  25. 0 0
      src/core/observer/batcher.js
  26. 0 0
      src/core/observer/dep.js
  27. 0 0
      src/core/observer/index.js
  28. 0 0
      src/core/observer/watcher.js
  29. 0 0
      src/core/util/debug.js
  30. 2 4
      src/core/util/env.js
  31. 0 1
      src/core/util/index.js
  32. 0 9
      src/core/util/lang.js
  33. 3 3
      src/core/util/options.js
  34. 0 0
      src/core/util/props.js
  35. 0 0
      src/core/vdom/create-component.js
  36. 4 3
      src/core/vdom/create-element.js
  37. 0 0
      src/core/vdom/helpers.js
  38. 0 0
      src/core/vdom/modules/directives.js
  39. 5 0
      src/core/vdom/modules/index.js
  40. 1 1
      src/core/vdom/patch.js
  41. 0 0
      src/core/vdom/vnode.js
  42. 18 0
      src/entries/web-compiler.js
  43. 4 3
      src/entries/web-runtime-with-compiler.js
  44. 23 3
      src/entries/web-runtime.js
  45. 6 0
      src/platforms/web/compiler/directives/html.js
  46. 9 0
      src/platforms/web/compiler/directives/index.js
  47. 2 2
      src/platforms/web/compiler/directives/model.js
  48. 6 0
      src/platforms/web/compiler/directives/text.js
  49. 1 1
      src/platforms/web/runtime/class-util.js
  50. 0 0
      src/platforms/web/runtime/directives/index.js
  51. 1 1
      src/platforms/web/runtime/directives/model.js
  52. 2 2
      src/platforms/web/runtime/directives/show.js
  53. 1 1
      src/platforms/web/runtime/modules/attrs.js
  54. 1 1
      src/platforms/web/runtime/modules/class.js
  55. 1 1
      src/platforms/web/runtime/modules/events.js
  56. 15 0
      src/platforms/web/runtime/modules/index.js
  57. 0 0
      src/platforms/web/runtime/modules/props.js
  58. 2 2
      src/platforms/web/runtime/modules/style.js
  59. 3 1
      src/platforms/web/runtime/modules/transition.js
  60. 0 0
      src/platforms/web/runtime/node-ops.js
  61. 21 6
      src/platforms/web/util.js
  62. 0 22
      src/runtime/dom/index.js
  63. 22 0
      src/shared/util.js

+ 4 - 4
build/build.js

@@ -16,9 +16,9 @@ var banner =
 
 // Update main file
 var main = fs
-  .readFileSync('src/runtime/index.js', 'utf-8')
+  .readFileSync('src/core/index.js', 'utf-8')
   .replace(/Vue\.version = '[\d\.]+'/, "Vue.version = '" + version + "'")
-fs.writeFileSync('src/runtime/index.js', main)
+fs.writeFileSync('src/core/index.js', main)
 
 build([
   // Runtime only, CommonJS build. Used by bundlers e.g. Webpack & Browserify
@@ -56,9 +56,9 @@ build([
       entities: './entity-decoder'
     }
   },
-  // Compiler standalone build, for npm distribution.
+  // Web compiler standalone build, for npm distribution.
   {
-    entry: 'src/compiler/index',
+    entry: 'src/entries/web-compiler.js',
     format: 'cjs',
     external: ['entities'],
     out: 'dist/compiler/compiler.js'

+ 46 - 4
src/compiler/codegen/index.js → src/compiler/codegen.js

@@ -1,10 +1,22 @@
-import { genDirectives, genHandlers } from './directives/index'
-import { isReservedTag } from '../../runtime/util/dom'
+import { genHandlers } from './events'
+import { ref } from './directives/ref'
 
+const baseDirectives = {
+  ref,
+  cloak: function () {} // noop
+}
+
+// platform-injected utils
+let platformDirectives
+let isPlatformReservedTag
+
+// reset on each call
 let staticRenderFns
 
-export function generate (ast) {
+export function generate (ast, options) {
   staticRenderFns = []
+  platformDirectives = options.directives || {}
+  isPlatformReservedTag = options.isReservedTag || (() => false)
   const code = ast ? genElement(ast) : '__h__("div")'
   return {
     render: `with (this) { return ${code}}`,
@@ -28,7 +40,7 @@ function genElement (el) {
   } else {
     // if the element is potentially a component,
     // wrap its children as a thunk.
-    const children = genChildren(el, !isReservedTag(el.tag) /* asThunk */)
+    const children = genChildren(el, !isPlatformReservedTag(el.tag) /* asThunk */)
     const code = `__h__('${el.tag}', ${genData(el)}, ${children}, '${el.ns || ''}')`
     if (el.staticRoot) {
       // hoist static sub-trees out
@@ -135,6 +147,36 @@ function genData (el) {
   return data.replace(/,$/, '') + '}'
 }
 
+function genDirectives (el) {
+  const dirs = el.directives
+  let res = 'directives:['
+  let hasRuntime = false
+  let i, l, dir, needRuntime
+  for (i = 0, l = dirs.length; i < l; i++) {
+    dir = dirs[i]
+    needRuntime = true
+    let gen = platformDirectives[dir.name] || baseDirectives[dir.name]
+    if (gen) {
+      // compile-time directive that manipulates AST.
+      // returns true if it also needs a runtime counterpart.
+      needRuntime = !!gen(el, dir)
+    }
+    if (needRuntime) {
+      hasRuntime = true
+      res += `{def:__resolveDirective__("${dir.name}")${
+        dir.value ? `,value:(${dir.value})` : ''
+      }${
+        dir.arg ? `,arg:"${dir.arg}"` : ''
+      }${
+        dir.modifiers ? `,modifiers:${JSON.stringify(dir.modifiers)}` : ''
+      }},`
+    }
+  }
+  if (hasRuntime) {
+    return res.slice(0, -1) + ']'
+  }
+}
+
 function genChildren (el, asThunk) {
   if (!el.children.length) {
     return 'undefined'

+ 0 - 6
src/compiler/codegen/directives/html.js

@@ -1,6 +0,0 @@
-import { addProp } from '../../helpers'
-
-export function html (el, dir) {
-  if (!dir.value) return
-  addProp(el, 'innerHTML', `(${dir.value})`)
-}

+ 0 - 43
src/compiler/codegen/directives/index.js

@@ -1,43 +0,0 @@
-import { model } from './model'
-import { text } from './text'
-import { html } from './html'
-import { ref } from './ref'
-export { genHandlers } from './on'
-
-export const directives = {
-  model,
-  text,
-  html,
-  ref,
-  cloak: function () {} // noop
-}
-
-export function genDirectives (el) {
-  const dirs = el.directives
-  let res = 'directives:['
-  let hasRuntime = false
-  let i, l, dir, needRuntime
-  for (i = 0, l = dirs.length; i < l; i++) {
-    dir = dirs[i]
-    needRuntime = true
-    let gen = directives[dir.name]
-    if (gen) {
-      // compile-time directive that manipulates AST.
-      // returns true if it also needs a runtime counterpart.
-      needRuntime = !!gen(el, dir)
-    }
-    if (needRuntime) {
-      hasRuntime = true
-      res += `{def:__resolveDirective__("${dir.name}")${
-        dir.value ? `,value:(${dir.value})` : ''
-      }${
-        dir.arg ? `,arg:"${dir.arg}"` : ''
-      }${
-        dir.modifiers ? `,modifiers:${JSON.stringify(dir.modifiers)}` : ''
-      }},`
-    }
-  }
-  if (hasRuntime) {
-    return res.slice(0, -1) + ']'
-  }
-}

+ 0 - 6
src/compiler/codegen/directives/text.js

@@ -1,6 +0,0 @@
-import { addProp } from '../../helpers'
-
-export function text (el, dir) {
-  if (!dir.value) return
-  addProp(el, 'textContent', `__toString__(${dir.value})`)
-}

+ 1 - 1
src/compiler/codegen/directives/ref.js → src/compiler/directives/ref.js

@@ -1,4 +1,4 @@
-import { addHook } from '../../helpers'
+import { addHook } from '../helpers'
 
 export function ref (el, dir) {
   // go up and check if this node is inside a v-for

+ 1 - 1
src/compiler/codegen/directives/on.js → src/compiler/events.js

@@ -1,4 +1,4 @@
-import { isArray } from '../../../shared/util'
+import { isArray } from '../shared/util'
 const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/
 
 // keyCode aliases

+ 17 - 10
src/compiler/index.js

@@ -1,14 +1,21 @@
 import { parse } from './parser/index'
-import { optimize } from './optimizer/index'
-import { generate } from './codegen/index'
-import { directives } from './codegen/directives/index'
+import { optimize } from './optimizer'
+import { generate } from './codegen'
 
-export function compile (html, options) {
-  const ast = parse(html.trim(), options)
-  optimize(ast)
-  return generate(ast)
-}
+/**
+ * Compile a template.
+ *
+ * @param {String} template
+ * @param {Object} options
+ *                 - warn
+ *                 - directives
+ *                 - isReservedTag
+ *                 - mustUseProp
+ *                 - getTagNamespace
+ */
 
-export function registerDirective (name, fn) {
-  directives[name] = fn
+export function compile (template, options) {
+  const ast = parse(template.trim(), options)
+  optimize(ast, options)
+  return generate(ast, options)
 }

+ 6 - 4
src/compiler/optimizer/index.js → src/compiler/optimizer.js

@@ -1,5 +1,6 @@
-import { makeMap } from '../../shared/util'
-import { isReservedTag, isBuiltInTag } from '../../runtime/util/dom'
+import { makeMap, isBuiltInTag } from '../shared/util'
+
+let isPlatformReservedTag
 
 /**
  * Goal of the optimizier: walk the generated template AST tree
@@ -13,7 +14,8 @@ import { isReservedTag, isBuiltInTag } from '../../runtime/util/dom'
  * 2. Completely skip them in the patching process.
  */
 
-export function optimize (root) {
+export function optimize (root, options) {
+  isPlatformReservedTag = options.isReservedTag || (() => false)
   // first pass: mark all non-static nodes.
   markStatic(root)
   // second pass: mark static roots.
@@ -53,7 +55,7 @@ const isStaticKey = makeMap(
 function isStatic (node) {
   return !!(node.text || node.pre || (
     !node.expression && // not text with interpolation
-    (!node.tag || isReservedTag(node.tag)) && // not a component
+    (!node.tag || isPlatformReservedTag(node.tag)) && // not a component
     !isBuiltInTag(node.tag) && // not a built-in
     (node.plain || Object.keys(node).every(isStaticKey)) // no dynamic bindings
   ))

+ 9 - 16
src/compiler/parser/index.js

@@ -1,7 +1,7 @@
 import { decodeHTML } from 'entities'
 import { parseHTML } from './html-parser'
 import { parseText } from './text-parser'
-import { hyphenate, makeMap, cached } from '../../shared/util'
+import { hyphenate, cached } from '../../shared/util'
 import {
   getAndRemoveAttr,
   addProp,
@@ -23,22 +23,14 @@ const camelRE = /[a-z\d][A-Z]/
 
 const decodeHTMLCached = cached(decodeHTML)
 
-// attributes that should be using props for binding
-const mustUseProp = makeMap('value,selected,checked,muted')
-
-// this map covers namespace elements that can appear as template root nodes
-const isSVG = makeMap('svg,g,defs,symbol,use,image,text,circle,ellipse,line,path,polygon,polyline,rect', true)
-
-function getTagNamespace (tag) {
-  if (isSVG(tag)) {
-    return 'svg'
-  }
-}
-
 // make warning customizable depending on environment.
 let warn
 const baseWarn = msg => console.error(`[Vue parser]: ${msg}`)
 
+// platform-injected util functions
+let platformGetTagNamespace
+let platformMustUseProp
+
 /**
  * Convert HTML string to AST.
  *
@@ -48,8 +40,9 @@ const baseWarn = msg => console.error(`[Vue parser]: ${msg}`)
  */
 
 export function parse (template, options) {
-  options = options || {}
   warn = options.warn || baseWarn
+  platformGetTagNamespace = options.getTagNamespace || (() => null)
+  platformMustUseProp = options.mustUseProp || (() => false)
   const stack = []
   let root
   let currentParent
@@ -81,7 +74,7 @@ export function parse (template, options) {
       }
 
       // check namespace
-      const namespace = getTagNamespace(tag)
+      const namespace = platformGetTagNamespace(tag)
       if (inNamespace) {
         element.ns = currentNamespace
       } else if (namespace) {
@@ -345,7 +338,7 @@ function processAttrs (el) {
       }
       if (bindRE.test(name)) { // v-bind
         name = name.replace(bindRE, '')
-        if (mustUseProp(name)) {
+        if (platformMustUseProp(name)) {
           addProp(el, name, value)
         } else {
           addAttr(el, name, value)

+ 14 - 0
src/runtime/config.js → src/core/config.js

@@ -14,6 +14,20 @@ export default {
 
   silent: false,
 
+  /**
+   * Check if a tag is reserved so that it cannot be registered as a
+   * component. This is platform-dependent and may be overwritten.
+   */
+
+  isReservedTag: () => false,
+
+  /**
+   * Check if a tag is an unknown element.
+   * Platform-dependent.
+   */
+
+  isUnknownElement: () => false,
+
   /**
    * List of asset types that a component can own.
    *

+ 2 - 2
src/runtime/global-api/assets.js → src/core/global-api/assets.js

@@ -1,5 +1,5 @@
 import config from '../config'
-import { warn, isPlainObject, isReservedTag } from '../util/index'
+import { warn, isPlainObject } from '../util/index'
 
 export function initAssetRegisters (Vue) {
   /**
@@ -17,7 +17,7 @@ export function initAssetRegisters (Vue) {
       } else {
         /* istanbul ignore if */
         if (process.env.NODE_ENV !== 'production') {
-          if (type === 'component' && isReservedTag(id)) {
+          if (type === 'component' && config.isReservedTag(id)) {
             warn(
               'Do not use built-in or reserved HTML elements as component ' +
               'id: ' + id

+ 0 - 0
src/runtime/global-api/extend.js → src/core/global-api/extend.js


+ 1 - 2
src/runtime/global-api/index.js → src/core/global-api/index.js

@@ -6,7 +6,6 @@ import { initExtend } from './extend'
 import { initAssetRegisters } from './assets'
 import { nextTick } from '../util/index'
 import { set, del } from '../observer/index'
-import directives from '../directives/index'
 
 export function initGlobalAPI (Vue) {
   Vue.config = config
@@ -16,7 +15,7 @@ export function initGlobalAPI (Vue) {
   Vue.nextTick = nextTick
 
   Vue.options = {
-    directives,
+    directives: Object.create(null),
     filters: Object.create(null),
     components: Object.create(null),
     transitions: Object.create(null)

+ 0 - 0
src/runtime/global-api/mixin.js → src/core/global-api/mixin.js


+ 0 - 0
src/runtime/global-api/use.js → src/core/global-api/use.js


+ 0 - 0
src/runtime/index.js → src/core/index.js


+ 0 - 0
src/runtime/instance/events.js → src/core/instance/events.js


+ 0 - 0
src/runtime/instance/index.js → src/core/instance/index.js


+ 2 - 3
src/runtime/instance/lifecycle.js → src/core/instance/lifecycle.js

@@ -1,5 +1,5 @@
 import Watcher from '../observer/watcher'
-import { warn, validateProp, remove, query } from '../util/index'
+import { warn, validateProp, remove } from '../util/index'
 import { observerState } from '../observer/index'
 import { updateListeners } from '../vdom/helpers'
 
@@ -20,8 +20,7 @@ export function initLifecycle (vm) {
 }
 
 export function lifecycleMixin (Vue) {
-  Vue.prototype.$mount = function (el) {
-    this.$el = el && query(el)
+  Vue.prototype._mount = function () {
     if (!this.$options.render) {
       this.$options.render = () => this.$createElement('div')
       if (process.env.NODE_ENV !== 'production') {

+ 0 - 0
src/runtime/instance/proxy.js → src/core/instance/proxy.js


+ 0 - 0
src/runtime/instance/render.js → src/core/instance/render.js


+ 0 - 0
src/runtime/instance/state.js → src/core/instance/state.js


+ 0 - 0
src/runtime/observer/array.js → src/core/observer/array.js


+ 0 - 0
src/runtime/observer/batcher.js → src/core/observer/batcher.js


+ 0 - 0
src/runtime/observer/dep.js → src/core/observer/dep.js


+ 0 - 0
src/runtime/observer/index.js → src/core/observer/index.js


+ 0 - 0
src/runtime/observer/watcher.js → src/core/observer/watcher.js


+ 0 - 0
src/runtime/util/debug.js → src/core/util/debug.js


+ 2 - 4
src/runtime/util/env.js → src/core/util/env.js

@@ -13,10 +13,8 @@ export const devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__
 
 // UA sniffing for working around browser-specific quirks
 const UA = inBrowser && window.navigator.userAgent.toLowerCase()
-export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
-export const isAndroid = UA && UA.indexOf('android') > 0
-export const isIos = UA && /(iphone|ipad|ipod|ios)/i.test(UA)
-export const isWechat = UA && UA.indexOf('micromessenger') > 0
+const isIos = UA && /(iphone|ipad|ipod|ios)/i.test(UA)
+const isWechat = UA && UA.indexOf('micromessenger') > 0
 
 /**
  * Defer a task to execute it asynchronously. Ideally this

+ 0 - 1
src/runtime/util/index.js → src/core/util/index.js

@@ -1,7 +1,6 @@
 export * from '../../shared/util'
 export * from './lang'
 export * from './env'
-export * from './dom'
 export * from './options'
 export * from './debug'
 export * from './props'

+ 0 - 9
src/runtime/util/lang.js → src/core/util/lang.js

@@ -1,12 +1,3 @@
-export function remove (arr, item) {
-  if (arr.length) {
-    const index = arr.indexOf(item)
-    if (index > -1) {
-      return arr.splice(index, 1)
-    }
-  }
-}
-
 /**
  * Check if a string starts with $ or _
  *

+ 3 - 3
src/runtime/util/options.js → src/core/util/options.js

@@ -1,7 +1,6 @@
 import Vue from '../instance/index'
 import config from '../config'
 import { warn } from './debug'
-import { isReservedTag } from './dom'
 import { set } from '../observer/index'
 import {
   extend,
@@ -9,7 +8,8 @@ import {
   isArray,
   isPlainObject,
   hasOwn,
-  camelize
+  camelize,
+  isBuiltInTag
 } from '../../shared/util'
 
 /**
@@ -215,7 +215,7 @@ function guardComponents (options) {
     var components = options.components
     var def
     for (var key in components) {
-      if (isReservedTag(key)) {
+      if (isBuiltInTag(key) || config.isReservedTag(key)) {
         process.env.NODE_ENV !== 'production' && warn(
           'Do not use built-in or reserved HTML elements as component ' +
           'id: ' + key

+ 0 - 0
src/runtime/util/props.js → src/core/util/props.js


+ 0 - 0
src/runtime/vdom/create-component.js → src/core/vdom/create-component.js


+ 4 - 3
src/runtime/vdom/create-element.js → src/core/vdom/create-element.js

@@ -1,21 +1,22 @@
 import VNode from './vnode'
+import config from '../config'
 import { createComponent } from './create-component'
 import { flatten } from './helpers'
 import { renderState } from '../instance/render'
-import { warn, isReservedTag, isUnknownElement, resolveAsset } from '../util/index'
+import { warn, resolveAsset } from '../util/index'
 
 export default function createElement (tag, data, children, namespace) {
   const context = this
   const parent = renderState.activeInstance
   if (typeof tag === 'string') {
     let Ctor
-    if (isReservedTag(tag)) {
+    if (config.isReservedTag(tag)) {
       return VNode(tag, data, flatten(children), undefined, undefined, namespace)
     } else if ((Ctor = resolveAsset(context.$options, 'components', tag))) {
       return createComponent(Ctor, data, parent, children)
     } else {
       if (process.env.NODE_ENV !== 'production') {
-        if (!namespace && isUnknownElement(tag)) {
+        if (!namespace && config.isUnknownElement(tag)) {
           warn(
             'Unknown custom element: <' + tag + '> - did you ' +
             'register the component correctly? For recursive components, ' +

+ 0 - 0
src/runtime/vdom/helpers.js → src/core/vdom/helpers.js


+ 0 - 0
src/runtime/dom/modules/directives.js → src/core/vdom/modules/directives.js


+ 5 - 0
src/core/vdom/modules/index.js

@@ -0,0 +1,5 @@
+import directives from './directives'
+
+export default [
+  directives
+]

+ 1 - 1
src/runtime/vdom/patch.js → src/core/vdom/patch.js

@@ -32,7 +32,7 @@ function createKeyToOldIdx (children, beginIdx, endIdx) {
   return map
 }
 
-export default function createPatchFunction (backend) {
+export function createPatchFunction (backend) {
   let i, j
   const cbs = {}
 

+ 0 - 0
src/runtime/vdom/vnode.js → src/core/vdom/vnode.js


+ 18 - 0
src/entries/web-compiler.js

@@ -0,0 +1,18 @@
+import { extend } from '../shared/util'
+import { compile as baseCompile } from '../compiler/index'
+import * as directives from '../platforms/web/compiler/directives/index'
+import { isReservedTag, mustUseProp, getTagNamespace } from '../platforms/web/util'
+
+const baseOptions = {
+  directives,
+  isReservedTag,
+  mustUseProp,
+  getTagNamespace
+}
+
+export function compile (template, options) {
+  options = options
+    ? extend(extend({}, baseOptions), options)
+    : baseOptions
+  return baseCompile(template, options)
+}

+ 4 - 3
src/entries/web-runtime-with-compiler.js

@@ -1,7 +1,8 @@
-import config from '../runtime/config'
-import { compile } from '../compiler/index'
-import { query, warn, cached } from '../runtime/util/index'
+import config from '../core/config'
+import { warn, cached } from '../core/util/index'
+import { query } from '../platforms/web/util'
 import Vue from './web-runtime'
+import { compile } from './web-compiler'
 
 const idToTemplate = cached(id => query(id).innerHTML)
 

+ 23 - 3
src/entries/web-runtime.js

@@ -1,6 +1,26 @@
-import Vue from '../runtime/index'
-import { patch } from '../runtime/dom/index'
+import Vue from '../core/index'
+import { createPatchFunction } from '../core/vdom/patch'
+import * as nodeOps from '../platforms/web/runtime/node-ops'
+import platformDirectives from '../platforms/web/runtime/directives/index'
+import baseModules from '../core/vdom/modules/index'
+import platformModules from '../platforms/web/runtime/modules/index'
+import { query, isUnknownElement, isReservedTag } from '../platforms/web/util'
 
-Vue.prototype.__patch__ = patch
+// install platform specific utils
+Vue.config.isUnknownElement = isUnknownElement
+Vue.config.isReservedTag = isReservedTag
+
+// install platform runtime directives
+Vue.options.directives = platformDirectives
+
+// install platform patch function
+const modules = baseModules.concat(platformModules)
+Vue.prototype.__patch__ = createPatchFunction({ nodeOps, modules })
+
+// wrap mount
+Vue.prototype.$mount = function (el) {
+  this.$el = el && query(el)
+  this._mount()
+}
 
 export default Vue

+ 6 - 0
src/platforms/web/compiler/directives/html.js

@@ -0,0 +1,6 @@
+import { addProp } from '../../../../compiler/helpers'
+
+export default function html (el, dir) {
+  if (!dir.value) return
+  addProp(el, 'innerHTML', `(${dir.value})`)
+}

+ 9 - 0
src/platforms/web/compiler/directives/index.js

@@ -0,0 +1,9 @@
+import model from './model'
+import text from './text'
+import html from './html'
+
+export default {
+  model,
+  text,
+  html
+}

+ 2 - 2
src/compiler/codegen/directives/model.js → src/platforms/web/compiler/directives/model.js

@@ -1,6 +1,6 @@
-import { addHandler, addProp, getBindingAttr } from '../../helpers'
+import { addHandler, addProp, getBindingAttr } from '../../../../compiler/helpers'
 
-export function model (el, dir) {
+export default function model (el, dir) {
   const value = dir.value
   const modifiers = dir.modifiers
   if (el.tag === 'select') {

+ 6 - 0
src/platforms/web/compiler/directives/text.js

@@ -0,0 +1,6 @@
+import { addProp } from '../../../../compiler/helpers'
+
+export default function text (el, dir) {
+  if (!dir.value) return
+  addProp(el, 'textContent', `__toString__(${dir.value})`)
+}

+ 1 - 1
src/runtime/dom/class-util.js → src/platforms/web/runtime/class-util.js

@@ -1,4 +1,4 @@
-import { isIE9 } from '../util/index'
+import { isIE9 } from '../util'
 import { namespaceMap } from './node-ops'
 
 const svgNS = namespaceMap.svg

+ 0 - 0
src/runtime/directives/index.js → src/platforms/web/runtime/directives/index.js


+ 1 - 1
src/runtime/directives/model.js → src/platforms/web/runtime/directives/model.js

@@ -1,4 +1,4 @@
-import { isAndroid, isIE9 } from '../util/env'
+import { isAndroid, isIE9 } from '../../util'
 
 if (isIE9) {
   // http://www.matts411.com/post/internet-explorer-9-oninput/

+ 2 - 2
src/runtime/directives/show.js → src/platforms/web/runtime/directives/show.js

@@ -1,5 +1,5 @@
-import { isIE9 } from '../util/index'
-import { enter, leave } from '../dom/modules/transition'
+import { isIE9 } from '../../util'
+import { enter, leave } from '../modules/transition'
 
 export default {
   bind (el, value, _, vnode) {

+ 1 - 1
src/runtime/dom/modules/attrs.js → src/platforms/web/runtime/modules/attrs.js

@@ -1,4 +1,4 @@
-import { makeMap } from '../../../shared/util'
+import { makeMap } from '../../../../shared/util'
 
 const isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck')
 const isBooleanAttr = makeMap(

+ 1 - 1
src/runtime/dom/modules/class.js → src/platforms/web/runtime/modules/class.js

@@ -1,4 +1,4 @@
-import { extend, isArray, isObject } from '../../util/index'
+import { extend, isArray, isObject } from '../../../../shared/util'
 import { setClass } from '../class-util'
 
 function updateClass (oldVnode, vnode) {

+ 1 - 1
src/runtime/dom/modules/events.js → src/platforms/web/runtime/modules/events.js

@@ -1,4 +1,4 @@
-import { updateListeners } from '../../vdom/helpers'
+import { updateListeners } from '../../../../core/vdom/helpers'
 
 function updateDOMListeners (oldVnode, vnode) {
   if (!oldVnode.data.on && !vnode.data.on) {

+ 15 - 0
src/platforms/web/runtime/modules/index.js

@@ -0,0 +1,15 @@
+import attrs from './attrs'
+import klass from './class'
+import events from './events'
+import props from './props'
+import style from './style'
+import transition from './transition'
+
+export default [
+  attrs,
+  klass,
+  events,
+  props,
+  style,
+  transition
+]

+ 0 - 0
src/runtime/dom/modules/props.js → src/platforms/web/runtime/modules/props.js


+ 2 - 2
src/runtime/dom/modules/style.js → src/platforms/web/runtime/modules/style.js

@@ -1,5 +1,5 @@
-import { extend, isArray, cached, camelize } from '../../../shared/util'
-import { inBrowser } from '../../util/env'
+import { extend, isArray, cached, camelize } from '../../../../shared/util'
+import { inBrowser } from '../../../../core/util/env'
 
 const prefixes = ['Webkit', 'Moz', 'ms']
 const testEl = inBrowser && document.createElement('div')

+ 3 - 1
src/runtime/dom/modules/transition.js → src/platforms/web/runtime/modules/transition.js

@@ -1,5 +1,7 @@
 import { addClass, removeClass } from '../class-util'
-import { isIE9, inBrowser, cached, remove } from '../../util/index'
+import { inBrowser } from '../../../../core/util/index'
+import { cached, remove } from '../../../../shared/util'
+import { isIE9 } from '../../util'
 
 const TRANSITION = 'transition'
 const ANIMATION = 'animation'

+ 0 - 0
src/runtime/dom/node-ops.js → src/platforms/web/runtime/node-ops.js


+ 21 - 6
src/runtime/util/dom.js → src/platforms/web/util.js

@@ -1,13 +1,12 @@
-import { inBrowser } from './env'
-import { warn } from './debug'
+import { inBrowser } from '../../core/util/env'
+import { warn } from '../../core/util/debug'
 import { makeMap } from '../../shared/util'
 
-const builtInTags = 'slot,component,render'
-
-export const isBuiltInTag = makeMap(builtInTags)
+const UA = inBrowser && window.navigator.userAgent.toLowerCase()
+export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
+export const isAndroid = UA && UA.indexOf('android') > 0
 
 export const isReservedTag = makeMap(
-  builtInTags +
   'html,base,head,link,meta,style,title,' +
   'address,article,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
   'div,dd,dl,dt,figcaption,figure,hr,li,main,ol,p,pre,ul,' +
@@ -21,6 +20,22 @@ export const isReservedTag = makeMap(
   'content,element,shadow,template'
 )
 
+// attributes that should be using props for binding
+export const mustUseProp = makeMap('value,selected,checked,muted')
+
+// this map covers namespace elements that can appear as template root nodes
+const isSVG = makeMap(
+  'svg,g,defs,symbol,use,image,text,circle,ellipse,' +
+  'line,path,polygon,polyline,rect',
+  true
+)
+
+export function getTagNamespace (tag) {
+  if (isSVG(tag)) {
+    return 'svg'
+  }
+}
+
 const unknownElementCache = Object.create(null)
 export function isUnknownElement (tag) {
   if (!inBrowser) {

+ 0 - 22
src/runtime/dom/index.js

@@ -1,22 +0,0 @@
-import createPatchFunction from '../vdom/patch'
-import * as nodeOps from './node-ops'
-import classes from './modules/class'
-import style from './modules/style'
-import props from './modules/props'
-import attrs from './modules/attrs'
-import events from './modules/events'
-import directives from './modules/directives'
-import transition from './modules/transition'
-
-export const patch = createPatchFunction({
-  nodeOps,
-  modules: [
-    classes,
-    props,
-    attrs,
-    style,
-    events,
-    directives,
-    transition
-  ]
-})

+ 22 - 0
src/shared/util.js

@@ -17,6 +17,28 @@ export function makeMap (str, expectsLowerCase) {
     : val => map[val]
 }
 
+/**
+ * Check if a tag is a built-in tag.
+ */
+
+export const isBuiltInTag = makeMap('slot,component,render,transition', true)
+
+/**
+ * Remove an item from an array
+ *
+ * @param {Array} arr
+ * @param {*} item
+ */
+
+export function remove (arr, item) {
+  if (arr.length) {
+    const index = arr.indexOf(item)
+    if (index > -1) {
+      return arr.splice(index, 1)
+    }
+  }
+}
+
 /**
  * Check whether the object has the property.
  *