8000 deprecate {{>yield}} and use <content> syntax · hwclass/vue@1f3175b · GitHub
[go: up one dir, main page]

Skip to content

Commit 1f3175b

Browse files
committed
deprecate {{>yield}} and use <content> syntax
1 parent a3d3017 commit 1f3175b

File tree

8 files changed

+157
-37
lines changed

8 files changed

+157
-37
lines changed

src/compiler.js

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,6 @@ function Compiler (vm, options) {
177177
}
178178

179179
// done!
180-
compiler.rawContent = null
181180
compiler.init = false
182181

183182
// post compile / ready hook
@@ -197,14 +196,16 @@ CompilerProto.setupElement = function (options) {
197196
: options.el || document.createElement(options.tagName || 'div')
198197

199198
var template = options.template,
200-
child, frag, replacer, i, attr, attrs
199+
child, replacer, i, attr, attrs
201200

202201
if (template) {
203202
// collect anything already in there
204-
/* jshint boss: true */
205-
frag = this.rawContent = document.createDocumentFragment()
206-
while (child = el.firstChild) {
207-
frag.appendChild(child)
203+
if (el.hasChildNodes()) {
204+
this.rawContent = document.createElement('div')
205+
/* jshint boss: true */
206+
while (child = el.firstChild) {
207+
this.rawContent.appendChild(child)
208+
}
208209
}
209210
// replace option: use the first node in
210211
// the template directly
@@ -227,6 +228,8 @@ CompilerProto.setupElement = function (options) {
227228
} else {
228229
el.appendChild(template.cloneNode(true))
229230
}
231+
232+
this.setupContent(el)
230233
}
231234

232235
// apply element options
@@ -242,6 +245,59 @@ CompilerProto.setupElement = function (options) {
242245
return el
243246
}
244247

248+
/**
249+
* Deal with <content> insertion points
250+
* per the Web Components spec
251+
*/
252+
CompilerProto.setupContent = function (el) {
253+
254+
var outlets = slice.call(el.getElementsByTagName('content')),
255+
raw = this.rawContent,
256+
outlet, select, i, j, main
257+
258+
i = outlets.length
259+
if (i) {
260+
// first pass, collect corresponding content
261+
// for each outlet.
262+
while (i--) {
263+
outlet = outlets[i]
264+
if (raw) {
265+
select = outlet.getAttribute('select')
266+
if (select) { // select content
267+
outlet.content =
268+
slice.call(raw.querySelectorAll(select))
269+
} else { // default content
270+
main = outlet
271+
}
272+
} else { // fallback content
273+
outlet.content =
274+
slice.call(outlet.childNodes)
275+
}
276+
}
277+
// second pass, actually insert the contents
278+
for (i = 0, j = outlets.length; i < j; i++) {
279+
outlet = outlets[i]
280+
if (outlet === main) continue
281+
insert(outlet, outlet.content)
282+
}
283+
// finally insert the main content
284+
if (raw) {
285+
insert(main, slice.call(raw.childNodes))
286+
}
287+
}
288+
289+
function insert (outlet, contents) {
290+
var parent = outlet.parentNode,
291+
i = 0, j = contents.length
292+
for (; i < j; i++) {
293+
parent.insertBefore(contents[i], outlet)
294+
}
295+
parent.removeChild(outlet)
296+
}
297+
298+
this.rawContent = null
299+
}
300+
245301
/**
246302
* Setup observer.
247303
* The observer listens for get/set/mutate events on all VM

src/directives/partial.js

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,32 @@ module.exports = {
99

1010
bind: function () {
1111

12-
var compiler = this.compiler,
13-
id = this.expression
12+
var id = this.expression
1413
if (!id) return
1514

16-
var partial = id === 'yield'
17-
? this.compiler.rawContent
18-
: this.compiler.getOption('partials', id)
15+
var el = this.el,
16+
compiler = this.compiler,
17+
partial = compiler.getOption('partials', id)
1918

2019
if (!partial) {
21-
utils.warn('Unknown partial: ' + id)
20+
if (id === 'yield') {
21+
utils.warn('{{>yield}} syntax has been deprecated. Use <content> tag instead.')
22+
} else {
23+
utils.warn('Unknown partial: ' + id)
24+
}
2225
return
2326
}
2427

2528
partial = partial.cloneNode(true)
2629

2730
// comment ref node means inline partial
28-
if (this.el.nodeType === 8) {
31+
if (el.nodeType === 8) {
2932

3033
// keep a ref for the partial's content nodes
3134
var nodes = [].slice.call(partial.childNodes),
32-
ref = this.el,
33-
parent = ref.parentNode
34-
parent.insertBefore(partial, ref)
35-
parent.removeChild(ref)
35+
parent = el.parentNode
36+
parent.insertBefore(partial, el)
37+
parent.removeChild(el)
3638
// compile partial after appending, because its children's parentNode
3739
// will change from the fragment to the correct parentNode.
3840
// This could affect directives that need access to its element's parentNode.
@@ -41,8 +43,8 @@ module.exports = {
4143
} else {
4244

4345
// just set innerHTML...
44-
this.el.innerHTML = ''
45-
this.el.appendChild(partial.cloneNode(true))
46+
el.innerHTML = ''
47+
el.appendChild(partial.cloneNode(true))
4648

4749
}
4850
}

src/directives/view.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module.exports = {
1616
// cache original content
1717
/* jshint boss: true */
1818
var node,
19-
frag = this.inner = document.createDocumentFragment()
19+
frag = this.inner = document.createElement('div')
2020
while (node = el.firstChild) {
2121
frag.appendChild(node)
2222
}
@@ -30,13 +30,11 @@ module.exports = {
3030
var Ctor = this.compiler.getOption('components', value)
3131
if (!Ctor) return
3232

33-
var inner = this.inner.cloneNode(true)
34-
3533
this.childVM = new Ctor({
3634
el: this.raw.cloneNode(true),
3735
parent: this.vm,
38-
created: function () {
39-
this.$compiler.rawContent = inner
36+
compilerOptions: {
37+
rawContent: this.inner.cloneNode(true)
4038
}
4139
})
4240

src/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ function enableDebug () {
313313
if (!config.silent && console) {
314314
console.warn(msg)
315315
if (config.debug && console.trace) {
316-
console.trace(msg)
316+
console.trace()
317317
}
318318
}
319319
}

test/functional/fixtures/routing.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,21 @@
5353
Vue.config('debug', true)
5454

5555
Vue.component('home', {
56-
template: '<h1>Home</h1><div class="content">{{>yield}}</div>',
56+
template: '<h1>Home</h1><div class="content"><content/></div>',
5757
created: function () {
5858
this.msg = "Home sweet home!"
5959
}
6060
})
6161

6262
Vue.component('page1', {
63-
template: '<h1>Page1</h1><div class="content">{{>yield}}</div>',
63+
template: '<h1>Page1</h1><div class="content"><content/></div>',
6464
created: function () {
6565
this.msg = "Welcome to page 1!"
6666
}
6767
})
6868

6969
Vue.component('page2', {
70-
template: '<h1>Page2</h1><div class="content">{{>yield}}</div>',
70+
template: '<h1>Page2</h1><div class="content"><content/></div>',
7171
created: function () {
7272
this.msg = "Welcome to page 2!"
7373
}

test/functional/fixtures/template.html

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
<div id="conditional" v-partial="{{ok ? 'global' : 'nope'}}"></div>
55
<div id="japan">{{> local}}</div>
66
<div id="repeat">{{> repeat}}</div>
7-
<div id="yielder"><x-yielder><p>{{a}}</p><p>{{b}}</p></x-yielder></div>
87

98
<script type="text/v-template" id="test">
109
<p>{{hi}}!</p>
@@ -14,10 +13,27 @@
1413
<p v-repeat="items">{{title}}</p>
1514
</script>
1615

17-
<script type="text/v-template" id="yield-template">
18-
<h1>before</h1>{{>yield}}<h2>after</h2>
16+
<!-- content insertion point tests -->
17+
<div id="content">
18+
<my-compponent>
19+
<p class="b">{{b}}</p>
20+
<p class="rest1">rest</p>
21+
<p class="rest2">rest</p>
22+
<p class="a">{{a}}</p>
23+
</my-compponent>
24+
</div>
25+
26+
<script type="text/v-template" id="content-template">
27+
<h1>before</h1>
28+
<content select=".a"></content>
29+
<content select=".b"></content>
30+
<content></content>
31+
<h2>after</h2>
1932
</script>
2033

34+
<!-- content fallback test -->
35+
<div id="fallback"></div>
36+
2137
<script src="../../../dist/vue.js"></script>
2238
<script>
2339

@@ -76,12 +92,17 @@ <h1>before</h1>{{>yield}}<h2>after</h2>
7692
}
7793
})
7894

79-
Vue.component('x-yielder', {
80-
template: '#yield-template',
95+
Vue.component('my-compponent', {
96+
template: '#content-template',
8197
data: {
8298
a: 'A', b: 'B'
8399
}
84100
})
85101

86-
new Vue({el:'#yielder'})
102+
new Vue({el:'#content'})
103+
104+
new Vue({
105+
el: '#fallback',
106+
template: '<content>This is fallback</content>'
107+
})
87108
</script>

test/functional/specs/template.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
casper.test.begin('Templates and Partials', 6, function (test) {
1+
casper.test.begin('Templates and Partials', 7, function (test) {
22

33
casper
44
.start('./fixtures/template.html')
@@ -9,8 +9,11 @@ casper.test.begin('Templates and Partials', 6, function (test) {
99
test.assertSelectorHasText('#hawaii', 'Aloha', 'extend option')
1010
test.assertSelectorHasText('#repeat', 'Repeat', 'inline partial with repeat')
1111
test.assertEvalEquals(function () {
12-
return document.querySelector('#yielder').innerHTML
13-
}, '<x-yielder><h1>before</h1><p>A</p><p>B</p><h2>after</h2></x-yielder>')
12+
return document.querySelector('#content').textContent
13+
.replace(/\n/g, ' ')
14+
.replace(/\s+/g, ' ')
15+
}, ' before A B rest rest after ')
16+
test.assertSelectorHasText('#fallback', 'This is fallback')
1417
})
1518
.run(function () {
1619
test.done()

test/unit/specs/misc.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,44 @@ describe('Misc Features', function () {
207207

208208
})
209209

210+
describe('content insertion points', function () {
211+
212+
it('should insert original content', function () {
213+
var div = document.createElement('div')
214+
div.innerHTML = '<h1>hello!</h1>'
215+
var t = new Vue({
216+
el: div,
217+
template: '<h1>before</h1><content></content><p>after</p>'
218+
})
219+
assert.strictEqual(t.$el.innerHTML, '<h1>before</h1><h1>hello!</h1><p>after</p>')
220+
})
221+
222+
it('should respect "select" attributes', function () {
223+
var div = document.createElement('div')
224+
div.innerHTML = '<h1>hi</h1><h1>ha</h1><p>hehe</p>'
225+
var t = new Vue({
226+
el: div,
227+
template: '<h1>before</h1>' +
228+
'<content></content>' +
229+
'<content select="h1:nth-of-type(2)"></content>' +
230+
'<content select="h1:nth-of-type(1)"></content>' +
231+
'<p>after</p>'
232+
})
233+
assert.strictEqual(t.$el.innerHTML,
234+
'<h1>before</h1>' +
235+
'<p>hehe</p>' +
236+
'<h1>ha</h1><h1>hi</h1>' +
237+
'<p>after</p>'
238+
)
239+
})
240+
241+
it('should use fallback content if no rawContent is available', function () {
242+
var t = new Vue({
243+
template: '<content>Hello!</content>'
244+
})
245+
assert.strictEqual(t.$el.innerHTML, 'Hello!')
246+
})
247+
248+
})
249+
210250
})

0 commit comments

Comments
 (0)
0