Sfoglia il codice sorgente

working on compile

Evan You 12 anni fa
parent
commit
2c254d15e5
5 ha cambiato i file con 122 aggiunte e 10 eliminazioni
  1. 4 0
      changes.md
  2. 1 1
      src/config.js
  3. 2 1
      src/directive.js
  4. 114 7
      src/instance/compile.js
  5. 1 1
      src/util/dom.js

+ 4 - 0
changes.md

@@ -120,6 +120,10 @@ Instead of the old `Vue.config()` with a heavily overloaded API, the config obje
 Vue.config.debug = true
 ```
 
+## Prefix
+
+Config prefix now should include the hyphen: so the default is now `v-` and if you want to change it make sure to include the hyphen as well. e.g. `Vue.config.prefix = "data-"`.
+
 ## Interpolation Delimiters
 
 In the old version the interpolation delimiters are limited to the same base character (i.e. `['{','}']` translates into `{{}}` for text and `{{{}}}` for HTML). Now you can set them to whatever you like (*almost), and to indicate HTML interpolation, simply wrap the tag with one extra outer most character on each end. Example:

+ 1 - 1
src/config.js

@@ -6,7 +6,7 @@ module.exports = {
    * @type {String}
    */
 
-  prefix: 'v',
+  prefix: 'v-',
 
   /**
    * Whether to print debug messages.

+ 2 - 1
src/directive.js

@@ -31,6 +31,7 @@ function Directive (name, el, vm, descriptor) {
   this._bound = false
   // init definition
   this._initDef()
+  this._bind()
 }
 
 var p = Directive.prototype
@@ -71,7 +72,7 @@ p._bind = function () {
     )
     var value = this._watcher.value
     if (this.bind) {
-      this.bind(value)
+      this.bind()
     }
     if (this.update) {
       this.update(value)

+ 114 - 7
src/instance/compile.js

@@ -1,4 +1,7 @@
+var _ = require('../util')
 var config = require('../config')
+var Direcitve = require('../directive')
+var dirParser = require('../parse/directive')
 
 /**
  * The main entrance to the compilation process.
@@ -41,9 +44,9 @@ exports._compileNode = function (node) {
 }
 
 /**
- * Compile an HTMLElement
+ * Compile an Element
  *
- * @param {HTMLElement} node
+ * @param {Element} node
  */
 
 exports._compileElement = function (node) {
@@ -54,15 +57,71 @@ exports._compileElement = function (node) {
   if (tag === 'TEXTAREA' && node.value) {
       node.value = this.$interpolate(node.value)
   }
+  var hasAttributes = node.hasAttributes()
+  // check priority directives
+  if (hasAttributes) {
+    if (this._checkPriorityDirectives(node)) {
+      return
+    }
+  }
+  // check tag components
   if (
-    // skip non-component with no attributes
-    (!node.hasAttributes() && tag.indexOf('-') < 0) ||
-    // skip v-pre
-    _.attr(node, 'pre') !== null
+    tag.indexOf('-') > 0 &&
+    this.$options.components[tag]
   ) {
+    this._bindDirective('component', tag, node)
     return
   }
-  // TODO
+  // compile normal directives
+  if (hasAttributes) {
+    this._compileAttrs(node)
+  }
+  // recursively compile childNodes
+  if (node.hasChildNodes()) {
+    _.toArray(node.childNodes)
+      .forEach(this._compileNode, this)
+  }
+}
+
+/**
+ * Compile attribtues on an Element
+ *
+ * @param {Element} node
+ */
+
+exports._compileAttrs = function (node) {
+  var attrs = _.toArray(node.attributes)
+  var i = attrs.length
+  var registry = this.$options.directives
+  var dirs = []
+  var attr, attrName, dir, dirName
+  while (i--) {
+    attr = attrs[i]
+    attrName = attr.name
+    if (attrName.indexOf(config.prefix) === 0) {
+      dirName = attrName.slice(config.prefix.length)
+      if (registry[dirName]) {
+        node.removeAttribute(attrName)
+        dirs.push({
+          name: dirName,
+          value: attr.value
+        })
+      } else {
+        _.warn('Unknown directive: ' + dirName)
+      }
+    }
+  }
+  // sort the directives by priority, low to high
+  dirs.sort(function (a, b) {
+    a = registry[a.name].priority || 0
+    b = registry[b.name].priority || 0
+    return a > b ? 1 : -1
+  })
+  i = dirs.length
+  while (i--) {
+    dir = dirs[i]
+    this._bindDirective(dir.name, dir.value, node)
+  }
 }
 
 /**
@@ -83,4 +142,52 @@ exports._compileTextNode = function (node) {
 
 exports._compileComment = function (node) {
   
+}
+
+/**
+ * Check for priority directives that would potentially
+ * skip other directives:
+ *
+ * - v-pre
+ * - v-repeat
+ * - v-if
+ * - v-component
+ *
+ * @param {Element} node
+ * @return {Boolean}
+ */
+
+exports._checkPriorityDirectives = function (node) {
+  var value
+  /* jshint boss: true */
+  if (_.attr(node, 'pre') !== null) {
+    return true
+  } else if (value = _.attr(node, 'repeat')) {
+    this._bindDirective('repeat', value)
+    return true
+  } else if (value = _.attr(node, 'if')) {
+    this._bindDirective('if', value)
+    return true
+  } else if (value = _.attr(node, 'component')) {
+    this._bindDirective('component', value)
+    return true
+  }
+}
+
+/**
+ * Bind a directive.
+ *
+ * @param {String} name
+ * @param {String} value
+ * @param {Element} node
+ */
+
+exports._bindDirective = function (name, value, node) {
+  var descriptors = dirParser.parse(value)
+  var dirs = this._directives
+  for (var i = 0, l = descriptors.length; i < l; i++) {
+    dirs.push(
+      new Direcitve(name, node, this, descriptors[i])
+    )
+  }
 }

+ 1 - 1
src/util/dom.js

@@ -8,7 +8,7 @@ var config = require('../config')
  */
 
 exports.attr = function (node, attr) {
-  attr = config.prefix + '-' + attr
+  attr = config.prefix + attr
   var val = node.getAttribute(attr)
   node.removeAttribute(attr)
   return val