Skip to content

Commit 5872bf3

Browse files
author
Evan You
committed
fix #176 + node compiling perf improvements
1 parent 984304c commit 5872bf3

File tree

5 files changed

+81
-76
lines changed

5 files changed

+81
-76
lines changed

src/compiler.js

Lines changed: 69 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -332,33 +332,11 @@ CompilerProto.observeData = function (data) {
332332
* Compile a DOM node (recursive)
333333
*/
334334
CompilerProto.compile = function (node, root) {
335-
336-
var compiler = this,
337-
nodeType = node.nodeType
338-
335+
var nodeType = node.nodeType
339336
if (nodeType === 1 && node.tagName !== 'SCRIPT') { // a normal node
340-
341-
// skip anything with v-pre
342-
if (utils.attr(node, 'pre') !== null) {
343-
return
344-
}
345-
346-
// check priority directives.
347-
// if any of them are present, it will take over the node with a childVM
348-
// so we can skip the rest
349-
for (var i = 0, l = priorityDirectives.length; i < l; i++) {
350-
if (compiler.checkPriorityDir(priorityDirectives[i], node, root)) {
351-
return
352-
}
353-
}
354-
355-
// if none of the priority directives applies,
356-
// compile the normal directives.
357-
compiler.compileNode(node)
358-
337+
this.compileElement(node, root)
359338
} else if (nodeType === 3 && config.interpolate) {
360-
// text node
361-
compiler.compileTextNode(node)
339+
this.compileTextNode(node)
362340
}
363341
}
364342

@@ -368,7 +346,7 @@ CompilerProto.compile = function (node, root) {
368346
*/
369347
CompilerProto.checkPriorityDir = function (dirname, node, root) {
370348
var expression, directive, Ctor
371-
if (dirname === 'component' && (Ctor = this.resolveComponent(node, undefined, true))) {
349+
if (dirname === 'component' && root !== true && (Ctor = this.resolveComponent(node, undefined, true))) {
372350
directive = Directive.parse(dirname, '', this, node)
373351
directive.Ctor = Ctor
374352
} else {
@@ -388,64 +366,83 @@ CompilerProto.checkPriorityDir = function (dirname, node, root) {
388366
/**
389367
* Compile normal directives on a node
390368
*/
391-
CompilerProto.compileNode = function (node) {
369+
CompilerProto.compileElement = function (node, root) {
392370

393-
// check transition & animation properties
394-
node.vue_trans = utils.attr(node, 'transition')
395-
node.vue_anim = utils.attr(node, 'animation')
396-
node.vue_effect = this.eval(utils.attr(node, 'effect'))
371+
if (node.hasAttributes() || node.tagName.indexOf('-') > -1) {
397372

398-
var prefix = config.prefix + '-',
399-
attrs = slice.call(node.attributes),
400-
params = this.options.paramAttributes,
401-
i = attrs.length, j, attr, isDirective, exps, exp, directive, dirname
373+
// skip anything with v-pre
374+
if (utils.attr(node, 'pre') !== null) {
375+
return
376+
}
402377

403-
while (i--) {
378+
// check priority directives.
379+
// if any of them are present, it will take over the node with a childVM
380+
// so we can skip the rest
381+
for (var i = 0, l = priorityDirectives.length; i < l; i++) {
382+
if (this.checkPriorityDir(priorityDirectives[i], node, root)) {
383+
return
384+
}
385+
}
404386

405-
attr = attrs[i]
406-
isDirective = false
407-
408-
if (attr.name.indexOf(prefix) === 0) {
409-
// a directive - split, parse and bind it.
410-
isDirective = true
411-
exps = Directive.split(attr.value)
412-
// loop through clauses (separated by ",")
413-
// inside each attribute
414-
j = exps.length
415-
while (j--) {
416-
exp = exps[j]
417-
dirname = attr.name.slice(prefix.length)
418-
directive = Directive.parse(dirname, exp, this, node)
419-
420-
if (dirname === 'with') {
421-
this.bindDirective(directive, this.parent)
422-
} else {
423-
this.bindDirective(directive)
387+
// check transition & animation properties
388+
node.vue_trans = utils.attr(node, 'transition')
389+
node.vue_anim = utils.attr(node, 'animation')
390+
node.vue_effect = this.eval(utils.attr(node, 'effect'))
391+
392+
var prefix = config.prefix + '-',
393+
attrs = slice.call(node.attributes),
394+
params = this.options.paramAttributes,
395+
attr, isDirective, exps, exp, directive, dirname
396+
397+
i = attrs.length
398+
while (i--) {
399+
400+
attr = attrs[i]
401+
isDirective = false
402+
403+
if (attr.name.indexOf(prefix) === 0) {
404+
// a directive - split, parse and bind it.
405+
isDirective = true
406+
exps = Directive.split(attr.value)
407+
// loop through clauses (separated by ",")
408+
// inside each attribute
409+
l = exps.length
410+
while (l--) {
411+
exp = exps[l]
412+
dirname = attr.name.slice(prefix.length)
413+
directive = Directive.parse(dirname, exp, this, node)
414+
415+
if (dirname === 'with') {
416+
this.bindDirective(directive, this.parent)
417+
} else {
418+
this.bindDirective(directive)
419+
}
420+
424421
}
425-
426-
}
427-
} else if (config.interpolate) {
428-
// non directive attribute, check interpolation tags
429-
exp = TextParser.parseAttr(attr.value)
430-
if (exp) {
431-
directive = Directive.parse('attr', attr.name + ':' + exp, this, node)
432-
if (params && params.indexOf(attr.name) > -1) {
433-
// a param attribute... we should use the parent binding
434-
// to avoid circular updates like size={{size}}
435-
this.bindDirective(directive, this.parent)
436-
} else {
437-
this.bindDirective(directive)
422+
} else if (config.interpolate) {
423+
// non directive attribute, check interpolation tags
424+
exp = TextParser.parseAttr(attr.value)
425+
if (exp) {
426+
directive = Directive.parse('attr', attr.name + ':' + exp, this, node)
427+
if (params && params.indexOf(attr.name) > -1) {
428+
// a param attribute... we should use the parent binding
429+
// to avoid circular updates like size={{size}}
430+
this.bindDirective(directive, this.parent)
431+
} else {
432+
this.bindDirective(directive)
433+
}
438434
}
439435
}
440-
}
441436

442-
if (isDirective && dirname !== 'cloak') {
443-
node.removeAttribute(attr.name)
437+
if (isDirective && dirname !== 'cloak') {
438+
node.removeAttribute(attr.name)
439+
}
444440
}
441+
445442
}
446443

447444
// recursively compile childNodes
448-
if (node.childNodes.length) {
445+
if (node.hasChildNodes() && node.tagName !== 'TEXTAREA') {
449446
slice.call(node.childNodes).forEach(this.compile, this)
450447
}
451448
}

src/directives/model.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ module.exports = {
2727
self.lock = false
2828
self.ownerVM = self.binding.compiler.vm
2929

30+
// textarea
31+
if (tag === 'TEXTAREA' && el.value) {
32+
el.value = self.compiler.eval(el.value)
33+
}
34+
3035
// determine what event to listen to
3136
self.event =
3237
(self.compiler.options.lazy ||

src/exp-parser.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var utils = require('./utils'),
22
STR_SAVE_RE = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,
33
STR_RESTORE_RE = /"(\d+)"/g,
4+
NEWLINE_RE = /\n/g,
45
CTOR_RE = new RegExp('constructor'.split('').join('[\'"+, ]*')),
56
UNICODE_RE = /\\u\d\d\d\d/,
67
QUOTE_RE = /"/g
@@ -172,7 +173,9 @@ exports.parse = function (exp, compiler, data, filters) {
172173

173174
function saveStrings (str) {
174175
var i = strings.length
175-
strings[i] = str
176+
// escape newlines in strings so the expression
177+
// can be correctly evaluated
178+
strings[i] = str.replace(NEWLINE_RE, '\\n')
176179
return '"' + i + '"'
177180
}
178181

test/functional/fixtures/forms.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<option>d</option>
2020
</select>
2121

22-
<textarea name="textarea" v-model="textarea"></textarea>
22+
<textarea name="textarea" v-model="textarea">more {{text}}</textarea>
2323

2424
</form>
2525

@@ -43,7 +43,7 @@
4343
radio: 'b',
4444
select: 'b',
4545
multipleSelect: ['a','c'],
46-
textarea: 'more text'
46+
textarea: undefined
4747
}
4848
})
4949
</script>

test/functional/specs/forms.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ casper.test.begin('Forms', 13, function (test) {
2020
return o.value || o.text
2121
})
2222
}, ['a', 'c'])
23-
test.assertField('textarea', 'more text')
23+
test.assertField('textarea', 'more some text')
2424
})
2525
.then(function () {
2626
this.fill('#forms', {

0 commit comments

Comments
 (0)