Skip to content

Commit 5f21eed

Browse files
author
Evan You
committed
Fix inline partial parentNode problem
Directives inside inline partials would get the fragment as the parentNode if they are compiled before the partial is appended to the correct parentNode. Therefore keep the reference of the fragment's childNodes, append it, then compile afterwards fixes the problem.
1 parent b63b551 commit 5f21eed

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

src/compiler.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -343,20 +343,24 @@ CompilerProto.compileNode = function (node) {
343343
* Compile a text node
344344
*/
345345
CompilerProto.compileTextNode = function (node) {
346+
346347
var tokens = TextParser.parse(node.nodeValue)
347348
if (!tokens) return
348-
var el, token, directive
349+
var el, token, directive, partial, partialId, partialNodes
350+
349351
for (var i = 0, l = tokens.length; i < l; i++) {
350352
token = tokens[i]
351353
if (token.key) { // a binding
352354
if (token.key.charAt(0) === '>') { // a partial
353-
var partialId = token.key.slice(1).trim(),
354-
partial = this.getOption('partials', partialId)
355+
partialId = token.key.slice(1).trim()
356+
partial = this.getOption('partials', partialId)
355357
if (partial) {
356358
el = partial.cloneNode(true)
357-
this.compileNode(el)
359+
// save an Array reference of the partial's nodes
360+
// so we can compile them AFTER appending the fragment
361+
partialNodes = slice.call(el.childNodes)
358362
}
359-
} else { // a binding
363+
} else { // a real binding
360364
el = document.createTextNode('')
361365
directive = Directive.parse('text', token.key, this, el)
362366
if (directive) {
@@ -366,7 +370,20 @@ CompilerProto.compileTextNode = function (node) {
366370
} else { // a plain string
367371
el = document.createTextNode(token)
368372
}
373+
374+
// insert node
369375
node.parentNode.insertBefore(el, node)
376+
377+
// compile partial after appending, because its children's parentNode
378+
// will change from the fragment to the correct parentNode.
379+
// This could affect directives that need access to its element's parentNode.
380+
if (partialNodes) {
381+
for (var j = 0, k = partialNodes.length; j < k; j++) {
382+
this.compile(partialNodes[j])
383+
}
384+
partialNodes = null
385+
}
386+
370387
}
371388
node.parentNode.removeChild(node)
372389
}

test/functional/fixtures/template.html

+18-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,20 @@
88
<body>
99

1010
<div id="usa" v-partial="global"></div>
11-
<div id="japan" v-partial="local"></div>
11+
<div id="japan">{{> local}}</div>
12+
<div id="repeat">{{> repeat}}</div>
1213

1314
<script type="text/v-template" id="test">
1415
<p>{{hi}}!</p>
1516
</script>
1617

18+
<script type="text/v-template" id="repeat-template">
19+
<p v-repeat="items">{{title}}</p>
20+
</script>
21+
1722
<script>
1823

19-
Vue.config({debug:true})
24+
// Vue.config({debug:true})
2025

2126
// direct usage
2227
var china = new Vue({
@@ -48,10 +53,20 @@
4853
var japan = new Vue({
4954
el: '#japan',
5055
partials: {
51-
local: document.querySelector('#test').innerHTML
56+
local: '#test'
5257
}
5358
})
5459
japan.hi = 'こんにちは'
60+
61+
var repeat = new Vue({
62+
el: '#repeat',
63+
partials: {
64+
repeat: '#repeat-template'
65+
},
66+
data: {
67+
items: [{ title: 'Repeat' }]
68+
}
69+
})
5570
</script>
5671
</body>
5772
</html>

test/functional/specs/template.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
casper.test.begin('Template', 4, function (test) {
1+
casper.test.begin('Templates and Partials', 5, function (test) {
22

33
casper
44
.start('./fixtures/template.html')
@@ -7,6 +7,7 @@ casper.test.begin('Template', 4, function (test) {
77
test.assertSelectorHasText('#japan', 'こんにちは', 'local partial')
88
test.assertSelectorHasText('#china', '你好', 'direct option')
99
test.assertSelectorHasText('#hawaii', 'Aloha', 'extend option')
10+
test.assertSelectorHasText('#repeat', 'Repeat', 'inline partial with repeat')
1011
})
1112
.run(function () {
1213
test.done()

0 commit comments

Comments
 (0)