Skip to content

Commit aba5228

Browse files
committed
wip - current tests pass
1 parent 792c139 commit aba5228

File tree

9 files changed

+55
-30
lines changed

9 files changed

+55
-30
lines changed

src/api/child.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,5 @@ exports.$addChild = function (opts, BaseCtor) {
4242
opts._parent = parent
4343
opts._root = parent.$root
4444
var child = new ChildVue(opts)
45-
this._children.push(child)
4645
return child
4746
}

src/compiler/compile.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,13 @@ function compile (el, options, partial, transcluded) {
6060
}
6161
// cache childNodes before linking parent, fix #657
6262
var childNodes = _.toArray(el.childNodes)
63-
// if transcluded, link in parent scope
64-
if (transcluded) vm = vm.$parent
65-
if (nodeLinkFn) nodeLinkFn(vm, el)
66-
if (childLinkFn) childLinkFn(vm, childNodes)
63+
// if this is a transcluded compile, linkers need to be
64+
// called in source scope, and the host needs to be
65+
// passed down.
66+
var source = transcluded ? vm.$parent : vm
67+
var host = transcluded ? vm : undefined
68+
if (nodeLinkFn) nodeLinkFn(source, el, host)
69+
if (childLinkFn) childLinkFn(source, childNodes, host)
6770

6871
/**
6972
* If this is a partial compile, the linker function
@@ -150,7 +153,7 @@ function compileElement (el, options) {
150153
if (!linkFn) {
151154
var dirs = collectDirectives(el, options)
152155
linkFn = dirs.length
153-
? makeDirectivesLinkFn(dirs)
156+
? makeNodeLinkFn(dirs)
154157
: null
155158
}
156159
}
@@ -168,14 +171,14 @@ function compileElement (el, options) {
168171
}
169172

170173
/**
171-
* Build a multi-directive link function.
174+
* Build a link function for all directives on a single node.
172175
*
173176
* @param {Array} directives
174177
* @return {Function} directivesLinkFn
175178
*/
176179

177-
function makeDirectivesLinkFn (directives) {
178-
return function directivesLinkFn (vm, el) {
180+
function makeNodeLinkFn (directives) {
181+
return function nodeLinkFn (vm, el, host) {
179182
// reverse apply because it's sorted low to high
180183
var i = directives.length
181184
var dir, j, k, target
@@ -193,7 +196,7 @@ function makeDirectivesLinkFn (directives) {
193196
k = dir.descriptors.length
194197
for (j = 0; j < k; j++) {
195198
target._bindDir(dir.name, el,
196-
dir.descriptors[j], dir.def)
199+
dir.descriptors[j], dir.def, host)
197200
}
198201
}
199202
}
@@ -465,13 +468,16 @@ function checkTerminalDirectives (el, options) {
465468
for (var i = 0; i < 3; i++) {
466469
dirName = terminalDirectives[i]
467470
if (value = _.attr(el, dirName)) {
468-
return makeTeriminalLinkFn(el, dirName, value, options)
471+
return makeTerminalNodeLinkFn(el, dirName, value, options)
469472
}
470473
}
471474
}
472475

473476
/**
474-
* Build a link function for a terminal directive.
477+
* Build a node link function for a terminal directive.
478+
* A terminal link function terminates the current
479+
* compilation recursion and handles compilation of the
480+
* subtree in the directive.
475481
*
476482
* @param {Element} el
477483
* @param {String} dirName
@@ -480,14 +486,14 @@ function checkTerminalDirectives (el, options) {
480486
* @return {Function} terminalLinkFn
481487
*/
482488

483-
function makeTeriminalLinkFn (el, dirName, value, options) {
489+
function makeTerminalNodeLinkFn (el, dirName, value, options) {
484490
var descriptor = dirParser.parse(value)[0]
485491
var def = options.directives[dirName]
486-
var terminalLinkFn = function (vm, el) {
487-
vm._bindDir(dirName, el, descriptor, def)
492+
var fn = function terminalNodeLinkFn (vm, el, host) {
493+
vm._bindDir(dirName, el, descriptor, def, host)
488494
}
489-
terminalLinkFn.terminal = true
490-
return terminalLinkFn
495+
fn.terminal = true
496+
return fn
491497
}
492498

493499
/**

src/directive.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ var expParser = require('./parsers/expression')
1818
* - {String} [arg]
1919
* - {Array<Object>} [filters]
2020
* @param {Object} def - directive definition object
21+
* @param {Vue|undefined} host - transclusion host target
2122
* @constructor
2223
*/
2324

24-
function Directive (name, el, vm, descriptor, def) {
25+
function Directive (name, el, vm, descriptor, def, host) {
2526
// public
2627
this.name = name
2728
this.el = el
@@ -32,6 +33,7 @@ function Directive (name, el, vm, descriptor, def) {
3233
this.arg = descriptor.arg
3334
this.filters = _.resolveFilters(vm, descriptor.filters)
3435
// private
36+
this._host = host
3537
this._locked = false
3638
this._bound = false
3739
// init

src/directives/component.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ module.exports = {
8787
var child = vm.$addChild({
8888
el: el,
8989
template: this.template,
90-
_asComponent: true
90+
_asComponent: true,
91+
_host: this._host
9192
}, this.Ctor)
9293
if (this.keepAlive) {
9394
this.cache[this.ctorId] = child

src/directives/repeat.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ module.exports = {
297297
var vm = this.vm.$addChild({
298298
el: templateParser.clone(this.template),
299299
_asComponent: this.asComponent,
300+
_host: this._host,
300301
_linkFn: this._linkFn,
301302
_meta: meta,
302303
data: data,

src/instance/compile.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,12 @@ exports._initElement = function (el) {
8989
* @param {Node} node - target node
9090
* @param {Object} desc - parsed directive descriptor
9191
* @param {Object} def - directive definition object
92+
* @param {Vue|undefined} host - transclusion host component
9293
*/
9394

94-
exports._bindDir = function (name, node, desc, def) {
95+
exports._bindDir = function (name, node, desc, def, host) {
9596
this._directives.push(
96-
new Directive(name, node, this, desc, def)
97+
new Directive(name, node, this, desc, def, host)
9798
)
9899
}
99100

@@ -120,6 +121,12 @@ exports._destroy = function (remove, deferCleanup) {
120121
i = parent._children.indexOf(this)
121122
parent._children.splice(i, 1)
122123
}
124+
// same for transclusion host.
125+
var host = this._host
126+
if (host && !host._isBeingDestroyed) {
127+
i = host._transCpnts.indexOf(this)
128+
host._transCpnts.splice(i, 1)
129+
}
123130
// destroy all children.
124131
i = this._children.length
125132
while (i--) {

src/instance/events.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ exports._initDOMHooks = function () {
8080
function onAttached () {
8181
this._isAttached = true
8282
this._children.forEach(callAttach)
83-
if (this._transCpnts) {
83+
if (this._transCpnts.length) {
8484
this._transCpnts.forEach(callAttach)
8585
}
8686
}
@@ -104,7 +104,7 @@ function callAttach (child) {
104104
function onDetached () {
105105
this._isAttached = false
106106
this._children.forEach(callDetach)
107-
if (this._transCpnts) {
107+
if (this._transCpnts.length) {
108108
this._transCpnts.forEach(callDetach)
109109
}
110110
}

src/instance/init.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,16 @@ exports._init = function (options) {
5656
// transcluded components that belong to the parent.
5757
// need to keep track of them so that we can call
5858
// attached/detached hooks on them.
59-
this._transCpnts = null
59+
this._transCpnts = []
60+
this._host = options._host
61+
62+
// push self into parent / transclusion host
63+
if (this.$parent) {
64+
this.$parent._children.push(this)
65+
}
66+
if (this._host) {
67+
this._host._transCpnts.push(this)
68+
}
6069

6170
// props used in v-repeat diffing
6271
this._new = true

test/unit/specs/compiler/compile_spec.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ if (_.inBrowser) {
5353
expect(typeof linker).toBe('function')
5454
linker(vm, el)
5555
expect(vm._bindDir.calls.count()).toBe(4)
56-
expect(vm._bindDir).toHaveBeenCalledWith('a', el, descriptorB, defA)
57-
expect(vm._bindDir).toHaveBeenCalledWith('a', el.firstChild, descriptorA, defA)
58-
expect(vm._bindDir).toHaveBeenCalledWith('b', el.firstChild, descriptorB, defB)
59-
expect(vm._bindDir).toHaveBeenCalledWith('b', el.lastChild, descriptorB, defB)
56+
expect(vm._bindDir).toHaveBeenCalledWith('a', el, descriptorB, defA, undefined)
57+
expect(vm._bindDir).toHaveBeenCalledWith('a', el.firstChild, descriptorA, defA, undefined)
58+
expect(vm._bindDir).toHaveBeenCalledWith('b', el.firstChild, descriptorB, defB, undefined)
59+
expect(vm._bindDir).toHaveBeenCalledWith('b', el.lastChild, descriptorB, defB, undefined)
6060
// check the priority sorting
6161
// the "b" on the firstNode should be called first!
6262
expect(vm._bindDir.calls.argsFor(1)[0]).toBe('b')
@@ -116,7 +116,7 @@ if (_.inBrowser) {
116116
// expect 1 call because terminal should return early and let
117117
// the directive handle the rest.
118118
expect(vm._bindDir.calls.count()).toBe(1)
119-
expect(vm._bindDir).toHaveBeenCalledWith('repeat', el.firstChild, descriptor, def)
119+
expect(vm._bindDir).toHaveBeenCalledWith('repeat', el.firstChild, descriptor, def, undefined)
120120
})
121121

122122
it('custom element components', function () {
@@ -131,7 +131,7 @@ if (_.inBrowser) {
131131
var linker = compile(el, options)
132132
linker(vm, el)
133133
expect(vm._bindDir.calls.count()).toBe(1)
134-
expect(vm._bindDir).toHaveBeenCalledWith('component', el.firstChild, descriptor, def)
134+
expect(vm._bindDir).toHaveBeenCalledWith('component', el.firstChild, descriptor, def, undefined)
135135
expect(_.warn).not.toHaveBeenCalled()
136136
})
137137

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy