Prechádzať zdrojové kódy

remove directive dependency from compile/compile

Evan You 11 rokov pred
rodič
commit
9bcb9b9dbc
5 zmenil súbory, kde vykonal 79 pridanie a 60 odobranie
  1. 1 0
      component.json
  2. 1 35
      src/api/lifecycle.js
  3. 12 25
      src/compile/compile.js
  4. 64 0
      src/instance/compile.js
  5. 1 0
      src/vue.js

+ 1 - 0
component.json

@@ -47,6 +47,7 @@
     "src/directives/with.js",
     "src/directives/with.js",
     "src/filters/array-filters.js",
     "src/filters/array-filters.js",
     "src/filters/index.js",
     "src/filters/index.js",
+    "src/instance/compile.js",
     "src/instance/events.js",
     "src/instance/events.js",
     "src/instance/init.js",
     "src/instance/init.js",
     "src/instance/scope.js",
     "src/instance/scope.js",

+ 1 - 35
src/api/lifecycle.js

@@ -1,6 +1,4 @@
 var _ = require('../util')
 var _ = require('../util')
-var compile = require('../compile/compile')
-var transclude = require('../compile/transclude')
 
 
 /**
 /**
  * Set instance target element and kick off the compilation
  * Set instance target element and kick off the compilation
@@ -17,20 +15,7 @@ exports.$mount = function (el) {
     _.warn('$mount() should be called only once.')
     _.warn('$mount() should be called only once.')
     return
     return
   }
   }
-  var options = this.$options
-  if (options._linker) {
-    // pre-compiled linker. this means the element has
-    // been transcluded and compiled. just link it.
-    this._initElement(el)
-    this._callHook('beforeCompile')
-    options._linker(this, el)
-  } else {
-    el = transclude(el, options)
-    this._initElement(el)
-    this._callHook('beforeCompile')
-    var linker = compile(el, options)
-    linker(this, el)
-  }
+  this._compile(el)
   this._isCompiled = true
   this._isCompiled = true
   this._callHook('compiled')
   this._callHook('compiled')
   if (_.inDoc(this.$el)) {
   if (_.inDoc(this.$el)) {
@@ -43,25 +28,6 @@ exports.$mount = function (el) {
   }
   }
 }
 }
 
 
-/**
- * Initialize instance element. Called in the public
- * $mount() method.
- *
- * @param {Element} el
- */
-
-exports._initElement = function (el) {
-  if (el instanceof DocumentFragment) {
-    this._isBlock = true
-    this.$el = this._blockStart = el.firstChild
-    this._blockEnd = el.lastChild
-    this._blockFragment = el
-  } else {
-    this.$el = el
-  }
-  this.$el.__vue__ = this
-}
-
 /**
 /**
  * Mark an instance as ready.
  * Mark an instance as ready.
  */
  */

+ 12 - 25
src/compile/compile.js

@@ -1,6 +1,5 @@
 var _ = require('../util')
 var _ = require('../util')
 var config = require('../config')
 var config = require('../config')
-var Direcitve = require('../directive')
 var textParser = require('../parse/text')
 var textParser = require('../parse/text')
 var dirParser = require('../parse/directive')
 var dirParser = require('../parse/directive')
 var templateParser = require('../parse/template')
 var templateParser = require('../parse/template')
@@ -112,7 +111,6 @@ function makeDirectivesLinkFn (directives) {
   return function directivesLinkFn (vm, el) {
   return function directivesLinkFn (vm, el) {
     // reverse apply because it's sorted low to high
     // reverse apply because it's sorted low to high
     var i = directives.length
     var i = directives.length
-    var vmDirs = vm._directives
     var dir, j
     var dir, j
     while (i--) {
     while (i--) {
       dir = directives[i]
       dir = directives[i]
@@ -122,10 +120,8 @@ function makeDirectivesLinkFn (directives) {
       } else {
       } else {
         j = dir.descriptors.length
         j = dir.descriptors.length
         while (j--) {
         while (j--) {
-          vmDirs.push(
-            new Direcitve(dir.name, el, vm,
-                          dir.descriptors[j], dir.def)
-          )
+          vm._bindDir(dir.name, el,
+                      dir.descriptors[j], dir.def)
         }
         }
       }
       }
     }
     }
@@ -194,7 +190,6 @@ function makeTextNodeLinkFn (tokens, frag) {
   return function textNodeLinkFn (vm, el) {
   return function textNodeLinkFn (vm, el) {
     var fragClone = frag.cloneNode(true)
     var fragClone = frag.cloneNode(true)
     var childNodes = _.toArray(fragClone.childNodes)
     var childNodes = _.toArray(fragClone.childNodes)
-    var dirs = vm._directives
     var token, value, node
     var token, value, node
     for (var i = 0, l = tokens.length; i < l; i++) {
     for (var i = 0, l = tokens.length; i < l; i++) {
       token = tokens[i]
       token = tokens[i]
@@ -209,10 +204,8 @@ function makeTextNodeLinkFn (tokens, frag) {
             node.nodeValue = value
             node.nodeValue = value
           }
           }
         } else {
         } else {
-          dirs.push(
-            new Direcitve(token.type, node, vm,
-                          token.descriptor, token.def)
-          )
+          vm._bindDir(token.type, node,
+                      token.descriptor, token.def)
         }
         }
       }
       }
     }
     }
@@ -335,12 +328,10 @@ function makeParamsLinkFn (params, options) {
         // we can directly fake the descriptor here beacuse
         // we can directly fake the descriptor here beacuse
         // param attributes cannot use expressions or
         // param attributes cannot use expressions or
         // filters.
         // filters.
-        vm._directives.push(
-          new Direcitve('with', el, vm, {
-            arg: param.name,
-            expression: param.value
-          }, def)
-        )
+        vm._bindDir('with', el, {
+          arg: param.name,
+          expression: param.value
+        }, def)
       } else {
       } else {
         // just set once
         // just set once
         vm.$set(param.name, param.value)
         vm.$set(param.name, param.value)
@@ -358,7 +349,7 @@ function makeParamsLinkFn (params, options) {
  * @return {Function} terminalLinkFn
  * @return {Function} terminalLinkFn
  */
  */
 
 
-var terminalDirecitves = [
+var terminalDirectives = [
   'repeat',
   'repeat',
   'component',
   'component',
   'if'
   'if'
@@ -371,7 +362,7 @@ function checkTerminalDirectives (el, options) {
   var value, dirName
   var value, dirName
   /* jshint boss: true */
   /* jshint boss: true */
   for (var i = 0; i < 3; i++) {
   for (var i = 0; i < 3; i++) {
-    dirName = terminalDirecitves[i]
+    dirName = terminalDirectives[i]
     if (value = _.attr(el, dirName)) {
     if (value = _.attr(el, dirName)) {
       return makeTeriminalLinkFn(el, dirName, value, options)
       return makeTeriminalLinkFn(el, dirName, value, options)
     }
     }
@@ -399,9 +390,7 @@ function makeTeriminalLinkFn (el, dirName, value, options) {
     var linker = compile(el, options)
     var linker = compile(el, options)
   }
   }
   return function terminalLinkFn (vm, el) {
   return function terminalLinkFn (vm, el) {
-    vm._directives.push(
-      new Direcitve(dirName, el, vm, descriptor, def, linker)
-    )
+    vm._bindDir(dirName, el, descriptor, def, linker)
   }
   }
 }
 }
 
 
@@ -480,9 +469,7 @@ function collectAttrDirective (el, name, value, options) {
         : function (vm, el) {
         : function (vm, el) {
             var value = textParser.tokensToExp(tokens, vm)
             var value = textParser.tokensToExp(tokens, vm)
             var desc = dirParser.parse(name + ':' + value)[0]
             var desc = dirParser.parse(name + ':' + value)[0]
-            vm._directives.push(
-              new Direcitve('attr', el, vm, desc, def)
-            )
+            vm._bindDir('attr', el, desc, def)
           }
           }
     }
     }
   }
   }

+ 64 - 0
src/instance/compile.js

@@ -0,0 +1,64 @@
+var Directive = require('../directive')
+var compile = require('../compile/compile')
+var transclude = require('../compile/transclude')
+
+/**
+ * Transclude, compile and link element.
+ *
+ * If a pre-compiled linker is available, that means the
+ * passed in element will be pre-transcluded and compiled
+ * as well - all we need to do is to call the linker.
+ *
+ * Otherwise we need to call transclude/compile/link here.
+ *
+ * @param {Element} el
+ */
+
+exports._compile = function (el) {
+  var options = this.$options
+  if (options._linker) {
+    this._initElement(el)
+    options._linker(this, el)
+  } else {
+    el = transclude(el, options)
+    this._initElement(el)
+    var linker = compile(el, options)
+    linker(this, el)
+  }
+}
+
+/**
+ * Initialize instance element. Called in the public
+ * $mount() method.
+ *
+ * @param {Element} el
+ */
+
+exports._initElement = function (el) {
+  if (el instanceof DocumentFragment) {
+    this._isBlock = true
+    this.$el = this._blockStart = el.firstChild
+    this._blockEnd = el.lastChild
+    this._blockFragment = el
+  } else {
+    this.$el = el
+  }
+  this.$el.__vue__ = this
+  this._callHook('beforeCompile')
+}
+
+/**
+ * Create and bind a directive to an element.
+ *
+ * @param {String} name - directive name
+ * @param {Node} node   - target node
+ * @param {Object} desc - parsed directive descriptor
+ * @param {Object} def  - directive definition object
+ * @param {Function} [linker] - pre-compiled linker fn
+ */
+
+exports._bindDir = function (name, node, desc, def, linker) {
+  this._directives.push(
+    new Directive(name, node, this, desc, def, linker)
+  )
+}

+ 1 - 0
src/vue.js

@@ -69,6 +69,7 @@ Object.defineProperty(p, '$data', {
 extend(p, require('./instance/init'))
 extend(p, require('./instance/init'))
 extend(p, require('./instance/events'))
 extend(p, require('./instance/events'))
 extend(p, require('./instance/scope'))
 extend(p, require('./instance/scope'))
+extend(p, require('./instance/compile'))
 
 
 /**
 /**
  * Mixin public API methods
  * Mixin public API methods