Skip to content

Commit 056a037

Browse files
committed
big rewrite for block-handling
1 parent 0bfd6e6 commit 056a037

File tree

18 files changed

+220
-258
lines changed

18 files changed

+220
-258
lines changed

examples/commits/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
var apiURL = 'https://api.github.com/repos/yyx990803/vue/commits?per_page=3&sha='
2-
var isPhantom = true//navigator.userAgent.indexOf('PhantomJS') > -1
2+
var isPhantom = navigator.userAgent.indexOf('PhantomJS') > -1
33

44
/**
55
* Test mocks

examples/todomvc/index.html

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,15 @@ <h1>todos</h1>
7979

8080
<!-- testing/benchmark only -->
8181
<script>
82-
if (navigator.userAgent.indexOf('PhantomJS') > -1) {
82+
var isPhantom = navigator.userAgent.indexOf('PhantomJS') > -1
83+
if (isPhantom) {
8384
localStorage.clear()
85+
} else {
86+
var now = window.performance && window.performance.now
87+
? function () { return window.performance.now() }
88+
: Date.now
89+
var metrics = { beforeLoad: now() }
8490
}
85-
var now = window.performance && window.performance.now
86-
? function () { return window.performance.now() }
87-
: Date.now
88-
var metrics = { beforeLoad: now() }
8991
</script>
9092
<!-- end testing/bench -->
9193

examples/todomvc/js/perf.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
setTimeout(function () {
2+
3+
if (window.isPhantom) return
24

35
// Initial load & render metrics
46

src/compile/compile.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,8 @@ function makeParamsLinkFn (params, options) {
381381

382382
var terminalDirectives = [
383383
'repeat',
384-
'component',
385-
'if'
384+
'if',
385+
'component'
386386
]
387387

388388
function skip () {}

src/compile/transclude.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ module.exports = function transclude (el, options) {
1919
if (el.tagName === 'TEMPLATE') {
2020
el = templateParser.parse(el)
2121
}
22-
if (options.template) {
23-
return transcludeTemplate(el, options)
24-
} else {
25-
return el
22+
if (options && options.template) {
23+
el = transcludeTemplate(el, options)
24+
}
25+
if (el instanceof DocumentFragment) {
26+
_.prepend(document.createComment('v-start'), el)
27+
el.appendChild(document.createComment('v-end'))
2628
}
29+
return el
2730
}
2831

2932
/**

src/directive.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ p._teardown = function () {
158158
if (watcher && watcher.active) {
159159
watcher.removeCb(this._update)
160160
if (!watcher.active) {
161-
this.vm._watchers[this.expression] = null
161+
this.vm._watchers[this.raw] = null
162162
}
163163
}
164164
this._bound = false

src/directives/component.js

Lines changed: 3 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,25 @@
11
var _ = require('../util')
2-
var Watcher = require('../watcher')
32
var templateParser = require('../parse/template')
43

54
module.exports = {
65

76
isLiteral: true,
87

98
/**
10-
* Setup. Need to check a few possible permutations:
9+
* Setup. Two possible usages:
1110
*
12-
* - literal:
11+
* - static:
1312
* v-component="comp"
1413
*
1514
* - dynamic:
1615
* v-component="{{currentView}}"
17-
*
18-
* - conditional:
19-
* v-component="comp" v-if="abc"
20-
*
21-
* - dynamic + conditional:
22-
* v-component="{{currentView}}" v-if="abc"
2316
*/
2417

2518
bind: function () {
2619
if (!this.el.__vue__) {
2720
// create a ref anchor
2821
this.ref = document.createComment('v-component')
2922
_.replace(this.el, this.ref)
30-
// check v-if conditionals
31-
this.checkIf()
3223
// check keep-alive options
3324
this.checkKeepAlive()
3425
// if static, build right now.
@@ -44,46 +35,6 @@ module.exports = {
4435
}
4536
},
4637

47-
/**
48-
* Check if v-component is being used together with v-if.
49-
* If yes, we created a watcher for the v-if value and
50-
* react to its value change in `this.ifCallback`.
51-
*/
52-
53-
checkIf: function () {
54-
var condition = _.attr(this.el, 'if')
55-
if (condition !== null) {
56-
var self = this
57-
this.ifWatcher = new Watcher(
58-
this.vm,
59-
condition,
60-
function (value) {
61-
self.toggleIf(value)
62-
}
63-
)
64-
this.active = this.ifWatcher.value
65-
} else {
66-
this.active = true
67-
}
68-
},
69-
70-
/**
71-
* Callback when v-if value changes.
72-
* Marks the active flag.
73-
*
74-
* @param {*} value
75-
*/
76-
77-
toggleIf: function (value) {
78-
if (value) {
79-
this.active = true
80-
this.build()
81-
} else {
82-
this.active = false
83-
this.unbuild(true)
84-
}
85-
},
86-
8738
/**
8839
* Check if the "keep-alive" flag is present.
8940
* If yes, instead of destroying the active vm when
@@ -119,9 +70,6 @@ module.exports = {
11970
*/
12071

12172
build: function () {
122-
if (!this.active) {
123-
return
124-
}
12573
if (this.keepAlive) {
12674
var vm = this.cache[this.ctorId]
12775
if (vm) {
@@ -178,16 +126,12 @@ module.exports = {
178126
/**
179127
* Unbind.
180128
* Make sure keepAlive is set to false so that the
181-
* instance is always destroyed. Teardown v-if watcher
182-
* if present.
129+
* instance is always destroyed.
183130
*/
184131

185132
unbind: function () {
186133
this.keepAlive = false
187134
this.unbuild()
188-
if (this.ifWatcher) {
189-
this.ifWatcher.teardown()
190-
}
191135
}
192136

193137
}

src/directives/if.js

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@ module.exports = {
88
bind: function () {
99
var el = this.el
1010
if (!el.__vue__) {
11-
this.ref = document.createComment('v-if')
12-
_.replace(el, this.ref)
13-
this.isBlock = el.tagName === 'TEMPLATE'
14-
this.template = this.isBlock
15-
? templateParser.parse(el, true)
16-
: el
11+
this.start = document.createComment('v-if-start')
12+
this.end = document.createComment('v-if-end')
13+
_.replace(el, this.end)
14+
_.before(this.start, this.end)
15+
if (el.tagName === 'TEMPLATE') {
16+
this.template = templateParser.parse(el, true)
17+
} else {
18+
this.template = document.createDocumentFragment()
19+
this.template.appendChild(el)
20+
}
1721
// compile the nested partial
1822
this.linker = compile(
1923
this.template,
@@ -40,28 +44,13 @@ module.exports = {
4044

4145
insert: function () {
4246
var vm = this.vm
43-
var el = templateParser.clone(this.template)
44-
var ref = this.ref
45-
var decompile = this.linker(vm, el)
46-
if (this.isBlock) {
47-
var blockStart = el.firstChild
48-
this.decompile = function () {
49-
decompile()
50-
var node = blockStart
51-
var next
52-
while (node !== ref) {
53-
next = node.nextSibling
54-
transition.remove(node, vm)
55-
node = next
56-
}
57-
}
58-
} else {
59-
this.decompile = function () {
60-
decompile()
61-
transition.remove(el, vm)
62-
}
47+
var frag = templateParser.clone(this.template)
48+
var decompile = this.linker(vm, frag)
49+
this.decompile = function () {
50+
decompile()
51+
transition.blockRemove(this.start, this.end, vm)
6352
}
64-
transition.before(el, ref, vm)
53+
transition.blockAppend(frag, this.end, vm)
6554
},
6655

6756
teardown: function () {

src/directives/partial.js

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
var _ = require('../util')
22
var templateParser = require('../parse/template')
3+
var transition = require('../transition')
34

45
module.exports = {
56

67
isLiteral: true,
78

89
bind: function () {
910
var el = this.el
11+
this.start = document.createComment('v-partial-start')
12+
this.end = document.createComment('v-partial-end')
1013
if (el.nodeType !== 8) {
1114
el.innerHTML = ''
1215
}
13-
if (el.tagName === 'TEMPLATE') {
14-
this.el = document.createComment('v-partial')
15-
_.replace(el, this.el)
16+
if (el.tagName === 'TEMPLATE' || el.nodeType === 8) {
17+
_.replace(el, this.end)
18+
} else {
19+
el.appendChild(this.end)
1620
}
21+
_.before(this.start, this.end)
1722
if (!this._isDynamicLiteral) {
1823
this.compile(this.expression)
19-
}
24+
}
2025
},
2126

2227
update: function (id) {
@@ -30,32 +35,14 @@ module.exports = {
3035
if (!partial) {
3136
return
3237
}
33-
partial = templateParser.parse(partial, true)
34-
var el = this.el
3538
var vm = this.vm
36-
var decompile = vm.$compile(partial)
37-
if (el.nodeType === 8) {
38-
// comment ref node means inline partial
39-
var blockStart = partial.firstChild
40-
this.decompile = function () {
41-
decompile()
42-
var node = blockStart
43-
var next
44-
while (node !== el) {
45-
next = node.nextSibling
46-
_.remove(node)
47-
node = next
48-
}
49-
}
50-
_.before(partial, el)
51-
} else {
52-
// just append to container
53-
this.decompile = function () {
54-
decompile()
55-
el.innerHTML = ''
56-
}
57-
el.appendChild(partial)
39+
var frag = templateParser.parse(partial, true)
40+
var decompile = vm.$compile(frag)
41+
this.decompile = function () {
42+
decompile()
43+
transition.blockRemove(this.start, this.end, vm)
5844
}
45+
transition.blockAppend(frag, this.end, vm)
5946
},
6047

6148
teardown: function () {

src/directives/repeat.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,18 @@ module.exports = {
9595

9696
checkComponent: function () {
9797
var id = _.attr(this.el, 'component')
98+
var options = this.vm.$options
9899
if (!id) {
99100
this.Ctor = _.Vue // default constructor
100101
this.inherit = true // inline repeats should inherit
101-
this._linker = compile(this.template, this.vm.$options)
102+
// important: transclude with no options, just
103+
// to ensure block start and block end
104+
this.template = transclude(this.template)
105+
this._linker = compile(this.template, options)
102106
} else {
103107
var tokens = textParser.parse(id)
104108
if (!tokens) { // static component
105-
var Ctor = this.Ctor = this.vm.$options.components[id]
109+
var Ctor = this.Ctor = options.components[id]
106110
_.assertAsset(Ctor, 'component', id)
107111
if (Ctor) {
108112
// merge an empty object with owner vm as parent

0 commit comments

Comments
 (0)