Skip to content

Commit bc254bf

Browse files
committed
fix #657: DOM structure change in bind() should not affect compilation
1 parent c0726dc commit bc254bf

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

src/compiler/compile.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ module.exports = function compile (el, options, partial, asParent) {
5252
return function link (vm, el) {
5353
var originalDirCount = vm._directives.length
5454
if (paramsLinkFn) paramsLinkFn(vm, el)
55+
// cache childNodes before linking parent, fix #657
56+
var childNodes = _.toArray(el.childNodes)
5557
if (nodeLinkFn) nodeLinkFn(vm, el)
56-
if (childLinkFn) childLinkFn(vm, el.childNodes)
58+
if (childLinkFn) childLinkFn(vm, childNodes)
5759

5860
/**
5961
* If this is a partial compile, the linker function
@@ -300,18 +302,18 @@ function compileNodeList (nodeList, options) {
300302

301303
function makeChildLinkFn (linkFns) {
302304
return function childLinkFn (vm, nodes) {
303-
// stablize nodes
304-
nodes = _.toArray(nodes)
305305
var node, nodeLinkFn, childrenLinkFn
306306
for (var i = 0, n = 0, l = linkFns.length; i < l; n++) {
307307
node = nodes[n]
308308
nodeLinkFn = linkFns[i++]
309309
childrenLinkFn = linkFns[i++]
310+
// cache childNodes before linking parent, fix #657
311+
var childNodes = _.toArray(node.childNodes)
310312
if (nodeLinkFn) {
311313
nodeLinkFn(vm, node)
312314
}
313315
if (childrenLinkFn) {
314-
childrenLinkFn(vm, node.childNodes)
316+
childrenLinkFn(vm, childNodes)
315317
}
316318
}
317319
}

test/unit/specs/misc_spec.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// test cases for edge cases & bug fixes
2+
var Vue = require('../../../src/vue')
3+
4+
describe('Misc', function () {
5+
6+
it('should handle directive.bind() altering its childNode structure', function () {
7+
var vm = new Vue({
8+
el: document.createElement('div'),
9+
template: '<div v-test>{{test}}</div>',
10+
data: {
11+
test: 'hi'
12+
},
13+
directives: {
14+
test: {
15+
bind: function () {
16+
this.el.insertBefore(document.createTextNode('yo '),
17+
this.el.firstChild)
18+
}
19+
}
20+
}
21+
})
22+
expect(vm.$el.textContent).toBe('yo hi')
23+
})
24+
25+
})

0 commit comments

Comments
 (0)