|
1 | 1 | import { SLOT } from '../priorities' |
2 | | - |
3 | | -import { |
4 | | - parseTemplate, |
5 | | - cloneNode |
6 | | -} from '../../parsers/template' |
7 | | - |
8 | 2 | import { |
9 | | - extend, |
10 | 3 | extractContent, |
11 | 4 | replace, |
12 | | - remove, |
13 | | - isTemplate |
| 5 | + remove |
14 | 6 | } from '../../util/index' |
15 | 7 |
|
16 | | -// This is the elementDirective that handles <content> |
17 | | -// transclusions. It relies on the raw content of an |
18 | | -// instance being stored as `$options._content` during |
19 | | -// the transclude phase. |
20 | | - |
21 | | -// We are exporting two versions, one for named and one |
22 | | -// for unnamed, because the unnamed slots must be compiled |
23 | | -// AFTER all named slots have selected their content. So |
24 | | -// we need to give them different priorities in the compilation |
25 | | -// process. (See #1965) |
26 | | - |
27 | | -export const slot = { |
| 8 | +export default { |
28 | 9 |
|
29 | 10 | priority: SLOT, |
| 11 | + params: ['name'], |
30 | 12 |
|
31 | 13 | bind () { |
32 | | - var host = this.vm |
33 | | - var raw = host.$options._content |
34 | | - if (!raw) { |
| 14 | + // this was resolved during component transclusion |
| 15 | + var name = this.params.name || 'default' |
| 16 | + var content = this.vm._slotContents && this.vm._slotContents[name] |
| 17 | + if (!content || !content.hasChildNodes()) { |
35 | 18 | this.fallback() |
36 | | - return |
37 | | - } |
38 | | - var context = host._context |
39 | | - var slotName = this.params && this.params.name |
40 | | - if (!slotName) { |
41 | | - // Default slot |
42 | | - this.tryCompile(extractFragment(raw.childNodes, raw, true), context, host) |
43 | 19 | } else { |
44 | | - // Named slot |
45 | | - var selector = '[slot="' + slotName + '"]' |
46 | | - var nodes = raw.querySelectorAll(selector) |
47 | | - if (nodes.length) { |
48 | | - this.tryCompile(extractFragment(nodes, raw), context, host) |
49 | | - } else { |
50 | | - this.fallback() |
51 | | - } |
52 | | - } |
53 | | - }, |
54 | | - |
55 | | - tryCompile (content, context, host) { |
56 | | - if (content.hasChildNodes()) { |
57 | | - this.compile(content, context, host) |
58 | | - } else { |
59 | | - this.fallback() |
| 20 | + this.compile(content.cloneNode(true), this.vm._context, this.vm) |
60 | 21 | } |
61 | 22 | }, |
62 | 23 |
|
@@ -101,47 +62,3 @@ export const slot = { |
101 | 62 | } |
102 | 63 | } |
103 | 64 | } |
104 | | - |
105 | | -export const namedSlot = extend(extend({}, slot), { |
106 | | - priority: slot.priority + 1, |
107 | | - params: ['name'] |
108 | | -}) |
109 | | - |
110 | | -/** |
111 | | - * Extract qualified content nodes from a node list. |
112 | | - * |
113 | | - * @param {NodeList} nodes |
114 | | - * @param {Element} parent |
115 | | - * @param {Boolean} main |
116 | | - * @return {DocumentFragment} |
117 | | - */ |
118 | | - |
119 | | -function extractFragment (nodes, parent, main) { |
120 | | - var frag = document.createDocumentFragment() |
121 | | - for (var i = 0, l = nodes.length; i < l; i++) { |
122 | | - var node = nodes[i] |
123 | | - // if this is the main outlet, we want to skip all |
124 | | - // previously selected nodes; |
125 | | - // otherwise, we want to mark the node as selected. |
126 | | - // clone the node so the original raw content remains |
127 | | - // intact. this ensures proper re-compilation in cases |
128 | | - // where the outlet is inside a conditional block |
129 | | - if (main && !node.__v_selected) { |
130 | | - append(node) |
131 | | - } else if (!main && node.parentNode === parent) { |
132 | | - node.__v_selected = true |
133 | | - append(node) |
134 | | - } |
135 | | - } |
136 | | - return frag |
137 | | - |
138 | | - function append (node) { |
139 | | - if (isTemplate(node) && |
140 | | - !node.hasAttribute('v-if') && |
141 | | - !node.hasAttribute('v-for')) { |
142 | | - node = parseTemplate(node) |
143 | | - } |
144 | | - node = cloneNode(node) |
145 | | - frag.appendChild(node) |
146 | | - } |
147 | | -} |
0 commit comments