浏览代码

Offer more hooks inside x-teleport for Livewire

Caleb Porzio 1 年之前
父节点
当前提交
beb1d8763c
共有 2 个文件被更改,包括 31 次插入28 次删除
  1. 31 11
      packages/alpinejs/src/directives/x-teleport.js
  2. 0 17
      packages/alpinejs/src/utils/walk.js

+ 31 - 11
packages/alpinejs/src/directives/x-teleport.js

@@ -5,18 +5,10 @@ import { mutateDom } from "../mutation"
 import { addScopeToNode } from "../scope"
 import { warn } from "../utils/warn"
 
-let teleportContainerDuringClone = document.createElement('div')
-
 directive('teleport', (el, { modifiers, expression }, { cleanup }) => {
     if (el.tagName.toLowerCase() !== 'template') warn('x-teleport can only be used on a <template> tag', el)
 
-    let target = skipDuringClone(() => {
-        return document.querySelector(expression)
-    }, () => {
-        return teleportContainerDuringClone
-    })()
-
-    if (! target) warn(`Cannot find x-teleport element for selector: "${expression}"`)
+    let target = getTarget(expression)
 
     let clone = el.content.cloneNode(true).firstElementChild
 
@@ -24,6 +16,10 @@ directive('teleport', (el, { modifiers, expression }, { cleanup }) => {
     el._x_teleport = clone
     clone._x_teleportBack = el
 
+    // Add the key to the DOM so they can be more easily searched for and linked up...
+    el.setAttribute('data-teleport-template', true)
+    clone.setAttribute('data-teleport-target', true)
+
     // Forward event listeners:
     if (el._x_forwardEvents) {
         el._x_forwardEvents.forEach(eventName => {
@@ -37,7 +33,7 @@ directive('teleport', (el, { modifiers, expression }, { cleanup }) => {
 
     addScopeToNode(clone, {}, el)
 
-    mutateDom(() => {
+    let placeInDom = (clone, target, modifiers) => {
         if (modifiers.includes('prepend')) {
             // insert element before the target
             target.parentNode.insertBefore(clone, target)
@@ -48,11 +44,35 @@ directive('teleport', (el, { modifiers, expression }, { cleanup }) => {
             // origin
             target.appendChild(clone)
         }
+    }
+
+    mutateDom(() => {
+        placeInDom(clone, target, modifiers)
 
         initTree(clone)
 
         clone._x_ignore = true
     })
 
-    cleanup(() => clone.remove())
+    el._x_teleportPutBack = () => {
+        let target = getTarget(expression)
+
+        mutateDom(() => {
+            placeInDom(el._x_teleport, target, modifiers)
+        })
+    }
 })
+
+let teleportContainerDuringClone = document.createElement('div')
+
+function getTarget(expression) {
+    let target = skipDuringClone(() => {
+        return document.querySelector(expression)
+    }, () => {
+        return teleportContainerDuringClone
+    })()
+
+    if (! target) warn(`Cannot find x-teleport element for selector: "${expression}"`)
+
+    return target
+}

+ 0 - 17
packages/alpinejs/src/utils/walk.js

@@ -19,20 +19,3 @@ export function walk(el, callback) {
         node = node.nextElementSibling
     }
 }
-// export function walk(el, callback) {
-//     if (el instanceof ShadowRoot || el instanceof DocumentFragment) {
-//         Array.from(el.children).forEach(el => walk(el, callback))
-
-//         return
-//     }
-
-//     callback(el, () => {
-//         let node = el.firstElementChild
-
-//         while (node) {
-//             walk(node, callback)
-
-//             node = node.nextElementSibling
-//         }
-//     })
-// }