working on compile

This commit is contained in:
Evan You 2014-08-12 20:09:37 -04:00
parent ea067d4275
commit 2c254d15e5
5 changed files with 122 additions and 10 deletions

View File

@ -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:

View File

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

View File

@ -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)

View File

@ -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])
)
}
}

View File

@ -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