resolve-slots.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { parseTemplate } from '../parsers/template'
  2. import {
  3. isTemplate,
  4. toArray,
  5. getBindAttr,
  6. warn
  7. } from '../util/index'
  8. /**
  9. * Scan and determine slot content distribution.
  10. * We do this during transclusion instead at compile time so that
  11. * the distribution is decoupled from the compilation order of
  12. * the slots.
  13. *
  14. * @param {Element|DocumentFragment} template
  15. * @param {Element} content
  16. * @param {Vue} vm
  17. */
  18. export function resolveSlots (vm, content) {
  19. if (!content) {
  20. return
  21. }
  22. var contents = vm._slotContents = Object.create(null)
  23. var el, name
  24. for (var i = 0, l = content.children.length; i < l; i++) {
  25. el = content.children[i]
  26. /* eslint-disable no-cond-assign */
  27. if (name = el.getAttribute('slot')) {
  28. (contents[name] || (contents[name] = [])).push(el)
  29. }
  30. /* eslint-enable no-cond-assign */
  31. if (process.env.NODE_ENV !== 'production' && getBindAttr(el, 'slot')) {
  32. warn('The "slot" attribute must be static.', vm.$parent)
  33. }
  34. }
  35. for (name in contents) {
  36. contents[name] = extractFragment(contents[name], content)
  37. }
  38. if (content.hasChildNodes()) {
  39. const nodes = content.childNodes
  40. if (
  41. nodes.length === 1 &&
  42. nodes[0].nodeType === 3 &&
  43. !nodes[0].data.trim()
  44. ) {
  45. return
  46. }
  47. contents['default'] = extractFragment(content.childNodes, content)
  48. }
  49. }
  50. /**
  51. * Extract qualified content nodes from a node list.
  52. *
  53. * @param {NodeList} nodes
  54. * @return {DocumentFragment}
  55. */
  56. function extractFragment (nodes, parent) {
  57. var frag = document.createDocumentFragment()
  58. nodes = toArray(nodes)
  59. for (var i = 0, l = nodes.length; i < l; i++) {
  60. var node = nodes[i]
  61. if (
  62. isTemplate(node) &&
  63. !node.hasAttribute('v-if') &&
  64. !node.hasAttribute('v-for')
  65. ) {
  66. parent.removeChild(node)
  67. node = parseTemplate(node, true)
  68. }
  69. frag.appendChild(node)
  70. }
  71. return frag
  72. }