51d952ae9615eff3a46b6dcb862d94a577a921820754f291ec4b207c44c1bdd1d7b7ee519d1178e60e5a724572ab6ae34a114ca6f45428ba713808fb84efac 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /* @flow */
  2. import type VNode from 'core/vdom/vnode'
  3. /**
  4. * Runtime helper for resolving raw children VNodes into a slot object.
  5. */
  6. export function resolveSlots (
  7. children: ?Array<VNode>,
  8. context: ?Component
  9. ): { [key: string]: Array<VNode> } {
  10. if (!children || !children.length) {
  11. return {}
  12. }
  13. const slots = {}
  14. for (let i = 0, l = children.length; i < l; i++) {
  15. const child = children[i]
  16. const data = child.data
  17. // remove slot attribute if the node is resolved as a Vue slot node
  18. if (data && data.attrs && data.attrs.slot) {
  19. delete data.attrs.slot
  20. }
  21. // named slots should only be respected if the vnode was rendered in the
  22. // same context.
  23. if ((child.context === context || child.fnContext === context) &&
  24. data && data.slot != null
  25. ) {
  26. const name = data.slot
  27. const slot = (slots[name] || (slots[name] = []))
  28. if (child.tag === 'template') {
  29. slot.push.apply(slot, child.children || [])
  30. } else {
  31. slot.push(child)
  32. }
  33. } else {
  34. (slots.default || (slots.default = [])).push(child)
  35. }
  36. }
  37. // ignore slots that contains only whitespace
  38. for (const name in slots) {
  39. if (slots[name].every(isWhitespace)) {
  40. delete slots[name]
  41. }
  42. }
  43. return slots
  44. }
  45. function isWhitespace (node: VNode): boolean {
  46. return (node.isComment && !node.asyncFactory) || node.text === ' '
  47. }