Browse Source

Run data-evaluate-once scripts if they werent there before

Caleb Porzio 2 years ago
parent
commit
cd9d8d35d9
2 changed files with 23 additions and 5 deletions
  1. 20 5
      packages/navigate/src/page.js
  2. 3 0
      packages/navigate/src/persist.js

+ 20 - 5
packages/navigate/src/page.js

@@ -5,11 +5,11 @@ export function swapCurrentPageWithNewHtml(html, andThen) {
     let newBody = document.adoptNode(newDocument.body)
     let newHead = document.adoptNode(newDocument.head)
 
-    mergeNewHead(newHead)
+    let oldBodyScriptTagHashes = Array.from(document.body.querySelectorAll('script')).map(i => simpleHash(i.outerHTML))
 
-    // mergeNewHead(newHead)
+    mergeNewHead(newHead)
 
-    prepNewScriptTagsToRun(newBody)
+    prepNewBodyScriptTagsToRun(newBody, oldBodyScriptTagHashes)
 
     transitionOut(document.body)
 
@@ -43,9 +43,17 @@ function transitionIn(body) {
     })
 }
 
-function prepNewScriptTagsToRun(newBody) {
+function prepNewBodyScriptTagsToRun(newBody, oldBodyScriptTagHashes) {
     newBody.querySelectorAll('script').forEach(i => {
-        if (i.hasAttribute('data-navigate-once')) return
+        // We don't want to re-run script tags marked as "data-navigate-once"...
+        if (i.hasAttribute('data-navigate-once')) {
+            // However, if they didn't exist on the previous page, we do.
+            // Therefore, we'll check the "old body script hashes" to
+            // see if it was already there before skipping it...
+            let hash = simpleHash(i.outerHTML)
+
+            if (oldBodyScriptTagHashes.includes(hash)) return
+        }
 
         i.replaceWith(cloneScriptTag(i))
     })
@@ -117,3 +125,10 @@ function isScript(el)   {
     return el.tagName.toLowerCase() === 'script'
 }
 
+function simpleHash(str) {
+    return str.split('').reduce((a, b) => {
+        a = ((a << 5) - a) + b.charCodeAt(0)
+
+        return a & a
+    }, 0);
+}

+ 3 - 0
packages/navigate/src/persist.js

@@ -18,6 +18,9 @@ export function putPersistantElementsBack() {
     document.querySelectorAll('[x-persist]').forEach(i => {
         let old = els[i.getAttribute('x-persist')]
 
+        // There might be a brand new x-persist element...
+        if (! old) return
+
         old._x_wasPersisted = true
 
         Alpine.mutateDom(() => {