From bc254bf942e1f21cc02dda281e5e701c78cb41e8 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 26 Jan 2015 12:52:29 -0500 Subject: [PATCH] fix #657: DOM structure change in bind() should not affect compilation --- src/compiler/compile.js | 10 ++++++---- test/unit/specs/misc_spec.js | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 test/unit/specs/misc_spec.js diff --git a/src/compiler/compile.js b/src/compiler/compile.js index b94e0edac..42004fcfd 100644 --- a/src/compiler/compile.js +++ b/src/compiler/compile.js @@ -52,8 +52,10 @@ module.exports = function compile (el, options, partial, asParent) { return function link (vm, el) { var originalDirCount = vm._directives.length if (paramsLinkFn) paramsLinkFn(vm, el) + // cache childNodes before linking parent, fix #657 + var childNodes = _.toArray(el.childNodes) if (nodeLinkFn) nodeLinkFn(vm, el) - if (childLinkFn) childLinkFn(vm, el.childNodes) + if (childLinkFn) childLinkFn(vm, childNodes) /** * If this is a partial compile, the linker function @@ -300,18 +302,18 @@ function compileNodeList (nodeList, options) { function makeChildLinkFn (linkFns) { return function childLinkFn (vm, nodes) { - // stablize nodes - nodes = _.toArray(nodes) var node, nodeLinkFn, childrenLinkFn for (var i = 0, n = 0, l = linkFns.length; i < l; n++) { node = nodes[n] nodeLinkFn = linkFns[i++] childrenLinkFn = linkFns[i++] + // cache childNodes before linking parent, fix #657 + var childNodes = _.toArray(node.childNodes) if (nodeLinkFn) { nodeLinkFn(vm, node) } if (childrenLinkFn) { - childrenLinkFn(vm, node.childNodes) + childrenLinkFn(vm, childNodes) } } } diff --git a/test/unit/specs/misc_spec.js b/test/unit/specs/misc_spec.js new file mode 100644 index 000000000..0cc65d2d6 --- /dev/null +++ b/test/unit/specs/misc_spec.js @@ -0,0 +1,25 @@ +// test cases for edge cases & bug fixes +var Vue = require('../../../src/vue') + +describe('Misc', function () { + + it('should handle directive.bind() altering its childNode structure', function () { + var vm = new Vue({ + el: document.createElement('div'), + template: '
{{test}}
', + data: { + test: 'hi' + }, + directives: { + test: { + bind: function () { + this.el.insertBefore(document.createTextNode('yo '), + this.el.firstChild) + } + } + } + }) + expect(vm.$el.textContent).toBe('yo hi') + }) + +}) \ No newline at end of file