You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.4 KiB
51 lines
1.4 KiB
|
3 years ago
|
/* @flow */
|
||
|
|
|
||
|
|
import type VNode from 'core/vdom/vnode'
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Runtime helper for resolving raw children VNodes into a slot object.
|
||
|
|
*/
|
||
|
|
export function resolveSlots (
|
||
|
|
children: ?Array<VNode>,
|
||
|
|
context: ?Component
|
||
|
|
): { [key: string]: Array<VNode> } {
|
||
|
|
if (!children || !children.length) {
|
||
|
|
return {}
|
||
|
|
}
|
||
|
|
const slots = {}
|
||
|
|
for (let i = 0, l = children.length; i < l; i++) {
|
||
|
|
const child = children[i]
|
||
|
|
const data = child.data
|
||
|
|
// remove slot attribute if the node is resolved as a Vue slot node
|
||
|
|
if (data && data.attrs && data.attrs.slot) {
|
||
|
|
delete data.attrs.slot
|
||
|
|
}
|
||
|
|
// named slots should only be respected if the vnode was rendered in the
|
||
|
|
// same context.
|
||
|
|
if ((child.context === context || child.fnContext === context) &&
|
||
|
|
data && data.slot != null
|
||
|
|
) {
|
||
|
|
const name = data.slot
|
||
|
|
const slot = (slots[name] || (slots[name] = []))
|
||
|
|
if (child.tag === 'template') {
|
||
|
|
slot.push.apply(slot, child.children || [])
|
||
|
|
} else {
|
||
|
|
slot.push(child)
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
(slots.default || (slots.default = [])).push(child)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// ignore slots that contains only whitespace
|
||
|
|
for (const name in slots) {
|
||
|
|
if (slots[name].every(isWhitespace)) {
|
||
|
|
delete slots[name]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return slots
|
||
|
|
}
|
||
|
|
|
||
|
|
function isWhitespace (node: VNode): boolean {
|
||
|
|
return (node.isComment && !node.asyncFactory) || node.text === ' '
|
||
|
|
}
|