clone.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { effect, release, overrideEffect } from "./reactivity"
  2. import { initTree, isRoot } from "./lifecycle"
  3. import { walk } from "./utils/walk"
  4. let isCloning = false
  5. export function skipDuringClone(callback, fallback = () => {}) {
  6. return (...args) => isCloning ? fallback(...args) : callback(...args)
  7. }
  8. export function onlyDuringClone(callback) {
  9. return (...args) => isCloning && callback(...args)
  10. }
  11. export function interuptCrawl(callback) {
  12. return (...args) => isCloning || callback(...args)
  13. }
  14. export function clone(oldEl, newEl) {
  15. if (! newEl._x_dataStack) newEl._x_dataStack = oldEl._x_dataStack
  16. isCloning = true
  17. dontRegisterReactiveSideEffects(() => {
  18. cloneTree(newEl)
  19. })
  20. isCloning = false
  21. }
  22. export function cloneTree(el) {
  23. let hasRunThroughFirstEl = false
  24. let shallowWalker = (el, callback) => {
  25. walk(el, (el, skip) => {
  26. if (hasRunThroughFirstEl && isRoot(el)) return skip()
  27. hasRunThroughFirstEl = true
  28. callback(el, skip)
  29. })
  30. }
  31. initTree(el, shallowWalker)
  32. }
  33. function dontRegisterReactiveSideEffects(callback) {
  34. let cache = effect
  35. overrideEffect((callback, el) => {
  36. let storedEffect = cache(callback)
  37. release(storedEffect)
  38. return () => {}
  39. })
  40. callback()
  41. overrideEffect(cache)
  42. }