x-if.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import { evaluateLater } from '../evaluator'
  2. import { addScopeToNode } from '../scope'
  3. import { directive } from '../directives'
  4. import { initTree, destroyTree } from '../lifecycle'
  5. import { mutateDom } from '../mutation'
  6. import { warn } from "../utils/warn"
  7. import { skipDuringClone } from '../clone'
  8. directive('if', (el, { expression }, { effect, cleanup }) => {
  9. if (el.tagName.toLowerCase() !== 'template') warn('x-if can only be used on a <template> tag', el)
  10. let evaluate = evaluateLater(el, expression)
  11. let show = () => {
  12. if (el._x_currentIfEl) return el._x_currentIfEl
  13. let clone = el.content.cloneNode(true).firstElementChild
  14. addScopeToNode(clone, {}, el)
  15. mutateDom(() => {
  16. el.after(clone)
  17. // These nodes will be "inited" as morph walks the tree...
  18. skipDuringClone(() => initTree(clone))()
  19. })
  20. el._x_currentIfEl = clone
  21. el._x_undoIf = () => {
  22. mutateDom(() => {
  23. destroyTree(clone)
  24. clone.remove()
  25. })
  26. delete el._x_currentIfEl
  27. }
  28. return clone
  29. }
  30. let hide = () => {
  31. if (! el._x_undoIf) return
  32. el._x_undoIf()
  33. delete el._x_undoIf
  34. }
  35. effect(() => evaluate(value => {
  36. value ? show() : hide()
  37. }))
  38. cleanup(() => el._x_undoIf && el._x_undoIf())
  39. })