Skip to content

Commit c14410c

Browse files
committed
fix vuejs#655 directives on placeholders for block instances are not compiled
1 parent 8a02eb1 commit c14410c

File tree

6 files changed

+54
-20
lines changed

6 files changed

+54
-20
lines changed

src/compiler/compile.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,17 @@ var templateParser = require('../parsers/template')
2525
*/
2626

2727
module.exports = function compile (el, options, partial, asParent) {
28+
var isBlock = el.nodeType === 11
2829
var params = !partial && options.paramAttributes
30+
// if el is a fragment, this is a block instance
31+
// and paramAttributes will be stored on the first
32+
// element in the template. (excluding the _blockStart
33+
// comment node)
34+
var paramsEl = isBlock ? el.childNodes[1] : el
2935
var paramsLinkFn = params
30-
? compileParamAttributes(el, params, options)
36+
? compileParamAttributes(paramsEl, params, options)
3137
: null
32-
var nodeLinkFn = el instanceof DocumentFragment
38+
var nodeLinkFn = isBlock
3339
? null
3440
: compileNode(el, options, asParent)
3541
var childLinkFn =
@@ -51,7 +57,10 @@ module.exports = function compile (el, options, partial, asParent) {
5157

5258
return function link (vm, el) {
5359
var originalDirCount = vm._directives.length
54-
if (paramsLinkFn) paramsLinkFn(vm, el)
60+
if (paramsLinkFn) {
61+
var paramsEl = isBlock ? el.childNodes[1] : el
62+
paramsLinkFn(vm, paramsEl)
63+
}
5564
// cache childNodes before linking parent, fix #657
5665
var childNodes = _.toArray(el.childNodes)
5766
if (nodeLinkFn) nodeLinkFn(vm, el)

src/compiler/transclude.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ function transcludeTemplate (el, options) {
4848
if (options.replace) {
4949
if (frag.childNodes.length > 1) {
5050
transcludeContent(frag, rawContent)
51-
// TODO: store directives on placeholder node
52-
// and compile it somehow
53-
// probably only check for v-with, v-ref & paramAttributes
51+
_.copyAttributes(el, frag.firstChild)
5452
return frag
5553
} else {
5654
var replacer = frag.firstChild

src/instance/compile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ exports._compile = function (el) {
7575
exports._initElement = function (el) {
7676
if (el instanceof DocumentFragment) {
7777
this._isBlock = true
78-
this.$el = this._blockStart = el.firstChild
78+
this._blockStart = el.firstChild
79+
this.$el = el.childNodes[1]
7980
this._blockEnd = el.lastChild
8081
this._blockFragment = el
8182
} else {

test/unit/specs/api/dom_spec.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ if (_.inBrowser) {
4141
it('block instance', function () {
4242
vm2.$appendTo(parent, spy)
4343
expect(parent.childNodes.length).toBe(6)
44-
expect(parent.childNodes[2]).toBe(vm2.$el)
44+
expect(parent.childNodes[2]).toBe(vm2._blockStart)
45+
expect(parent.childNodes[3]).toBe(vm2.$el)
4546
expect(parent.childNodes[3].tagName).toBe('P')
4647
expect(parent.childNodes[4].tagName).toBe('SPAN')
4748
expect(parent.childNodes[5]).toBe(vm2._blockEnd)
@@ -66,15 +67,17 @@ if (_.inBrowser) {
6667
it('block instance', function () {
6768
vm2.$prependTo(parent, spy)
6869
expect(parent.childNodes.length).toBe(6)
69-
expect(parent.childNodes[0]).toBe(vm2.$el)
70+
expect(parent.childNodes[0]).toBe(vm2._blockStart)
71+
expect(parent.childNodes[1]).toBe(vm2.$el)
7072
expect(parent.childNodes[1].tagName).toBe('P')
7173
expect(parent.childNodes[2].tagName).toBe('SPAN')
7274
expect(parent.childNodes[3]).toBe(vm2._blockEnd)
7375
expect(spy.calls.count()).toBe(1)
7476
// empty
7577
vm2.$prependTo(empty, spy)
7678
expect(empty.childNodes.length).toBe(4)
77-
expect(empty.childNodes[0]).toBe(vm2.$el)
79+
expect(empty.childNodes[0]).toBe(vm2._blockStart)
80+
expect(empty.childNodes[1]).toBe(vm2.$el)
7881
expect(empty.childNodes[1].tagName).toBe('P')
7982
expect(empty.childNodes[2].tagName).toBe('SPAN')
8083
expect(empty.childNodes[3]).toBe(vm2._blockEnd)
@@ -95,7 +98,8 @@ if (_.inBrowser) {
9598
it('block instance', function () {
9699
vm2.$before(sibling, spy)
97100
expect(parent.childNodes.length).toBe(6)
98-
expect(parent.childNodes[1]).toBe(vm2.$el)
101+
expect(parent.childNodes[1]).toBe(vm2._blockStart)
102+
expect(parent.childNodes[2]).toBe(vm2.$el)
99103
expect(parent.childNodes[2].tagName).toBe('P')
100104
expect(parent.childNodes[3].tagName).toBe('SPAN')
101105
expect(parent.childNodes[4]).toBe(vm2._blockEnd)
@@ -123,7 +127,8 @@ if (_.inBrowser) {
123127
it('block instance', function () {
124128
vm2.$after(target, spy)
125129
expect(parent.childNodes.length).toBe(6)
126-
expect(parent.childNodes[1]).toBe(vm2.$el)
130+
expect(parent.childNodes[1]).toBe(vm2._blockStart)
131+
expect(parent.childNodes[2]).toBe(vm2.$el)
127132
expect(parent.childNodes[2].tagName).toBe('P')
128133
expect(parent.childNodes[3].tagName).toBe('SPAN')
129134
expect(parent.childNodes[4]).toBe(vm2._blockEnd)
@@ -133,7 +138,8 @@ if (_.inBrowser) {
133138
it('block instance no next sibling', function () {
134139
vm2.$after(sibling, spy)
135140
expect(parent.childNodes.length).toBe(6)
136-
expect(parent.childNodes[2]).toBe(vm2.$el)
141+
expect(parent.childNodes[2]).toBe(vm2._blockStart)
142+
expect(parent.childNodes[3]).toBe(vm2.$el)
137143
expect(parent.childNodes[3].tagName).toBe('P')
138144
expect(parent.childNodes[4].tagName).toBe('SPAN')
139145
expect(parent.childNodes[5]).toBe(vm2._blockEnd)
@@ -158,7 +164,8 @@ if (_.inBrowser) {
158164
it('block instance', function () {
159165
vm2.$before(sibling)
160166
expect(parent.childNodes.length).toBe(6)
161-
expect(parent.childNodes[1]).toBe(vm2.$el)
167+
expect(parent.childNodes[1]).toBe(vm2._blockStart)
168+
expect(parent.childNodes[2]).toBe(vm2.$el)
162169
expect(parent.childNodes[2].tagName).toBe('P')
163170
expect(parent.childNodes[3].tagName).toBe('SPAN')
164171
expect(parent.childNodes[4]).toBe(vm2._blockEnd)

test/unit/specs/api/lifecycle_spec.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,22 @@ if (_.inBrowser) {
9696
data: { test: 'frag' }
9797
})
9898
vm.$mount(frag)
99-
expect(vm.$el).toBe(vm._blockStart)
99+
expect(vm.$el).toBe(vm._blockStart.nextSibling)
100100
expect(vm._blockFragment).toBe(frag)
101-
expect(vm.$el.nextSibling.textContent).toBe('frag')
101+
expect(vm.$el.textContent).toBe('frag')
102102
})
103103

104104
it('replace fragment', function () {
105105
document.body.appendChild(el)
106106
var vm = new Vue({
107107
replace: true,
108108
data: { test: 'hi!' },
109-
template: '<div>{{test}}</div><div>{{test}}</div>'
109+
template: '<div>{{test}}</div><div>{{test + "!"}}</div>'
110110
})
111111
vm.$mount(el)
112-
expect(vm.$el.nextSibling).not.toBe(el)
113-
expect(vm.$el.nextSibling.textContent).toBe('hi!')
114-
expect(vm.$el.nextSibling.nextSibling.textContent).toBe('hi!')
112+
expect(vm.$el).not.toBe(el)
113+
expect(vm.$el.textContent).toBe('hi!')
114+
expect(vm.$el.nextSibling.textContent).toBe('hi!!')
115115
expect(document.body.contains(el)).toBe(false)
116116
expect(document.body.lastChild).toBe(vm._blockEnd)
117117
vm.$remove()

test/unit/specs/directives/with_spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,24 @@ if (_.inBrowser) {
133133
expect(_.warn).toHaveBeenCalled()
134134
})
135135

136+
it('block instance with replace:true', function () {
137+
var vm = new Vue({
138+
el: el,
139+
template: '<div v-component="test" v-with="b:a" c="{{d}}"></div>',
140+
data: {
141+
a: 'AAA',
142+
d: 'DDD'
143+
},
144+
components: {
145+
test: {
146+
paramAttributes: ['c'],
147+
template: '<p>{{b}}</p><p>{{c}}</p>',
148+
replace: true
149+
}
150+
}
151+
})
152+
expect(el.innerHTML).toBe('<!--v-start--><p>AAA</p><p>DDD</p><!--v-end--><!--v-component-->')
153+
})
154+
136155
})
137156
}

0 commit comments

Comments
 (0)