浏览代码

Tweak x-navigate

Caleb Porzio 2 年之前
父节点
当前提交
96b477a769
共有 3 个文件被更改,包括 44 次插入77 次删除
  1. 2 0
      packages/alpinejs/src/alpine.js
  2. 33 35
      packages/navigate/src/index.js
  3. 9 42
      packages/navigate/src/links.js

+ 2 - 0
packages/alpinejs/src/alpine.js

@@ -11,6 +11,7 @@ import { getBinding as bound } from './utils/bind'
 import { debounce } from './utils/debounce'
 import { throttle } from './utils/throttle'
 import { setStyles } from './utils/styles'
+import { entangle } from './entangle'
 import { nextTick } from './nextTick'
 import { walk } from './utils/walk'
 import { plugin } from './plugin'
@@ -52,6 +53,7 @@ let Alpine = {
     setStyles, // INTERNAL
     mutateDom,
     directive,
+    entangle,
     throttle,
     debounce,
     evaluate,

+ 33 - 35
packages/navigate/src/index.js

@@ -1,69 +1,67 @@
-import { transition } from "alpinejs/src/directives/x-transition"
-import { finishAndHideProgressBar, showAndStartProgressBar } from "./bar"
-import { fetchHtml } from "./fetch"
 import { updateCurrentPageHtmlInHistoryStateForLaterBackButtonClicks, updateUrlAndStoreLatestHtmlForFutureBackButtons, whenTheBackOrForwardButtonIsClicked } from "./history"
-import { extractDestinationFromLink, hijackNewLinksOnThePage, whenALinkIsClicked, whenALinkIsHovered } from "./links"
-import { swapCurrentPageWithNewHtml } from "./page"
-import { putPersistantElementsBack, storePersistantElementsForLater } from "./persist"
 import { getPretchedHtmlOr, prefetchHtml, storeThePrefetchedHtmlForWhenALinkIsClicked } from "./prefetch"
+import { extractDestinationFromLink, whenThisLinkIsClicked, whenThisLinkIsHovered } from "./links"
 import { restoreScrollPosition, storeScrollInformationInHtmlBeforeNavigatingAway } from "./scroll"
+import { putPersistantElementsBack, storePersistantElementsForLater } from "./persist"
+import { finishAndHideProgressBar, showAndStartProgressBar } from "./bar"
+import { transition } from "alpinejs/src/directives/x-transition"
+import { swapCurrentPageWithNewHtml } from "./page"
+import { fetchHtml } from "./fetch"
 
-let enablePrefetch = true
 let enablePersist = true
 let showProgressBar = true
 let restoreScroll = true
 let autofocus = false
 
 export default function (Alpine) {
-    updateCurrentPageHtmlInHistoryStateForLaterBackButtonClicks()
+    Alpine.directive('navigate', (el, { value, expression, modifiers }, { evaluateLater, cleanup }) => {
+        let shouldPrefetch = modifiers.includes('prefetch')
 
-    enablePrefetch && whenALinkIsHovered((el) => {
-        let forDestination = extractDestinationFromLink(el)
+        shouldPrefetch && whenThisLinkIsHovered(el, () => {
+            let forDestination = extractDestinationFromLink(el)
 
-        prefetchHtml(forDestination, html => {
-            storeThePrefetchedHtmlForWhenALinkIsClicked(html, forDestination)
+            prefetchHtml(forDestination, html => {
+                storeThePrefetchedHtmlForWhenALinkIsClicked(html, forDestination)
+            })
         })
-    })
 
-    whenALinkIsClicked((el) => {
-        showProgressBar && showAndStartProgressBar()
+        whenThisLinkIsClicked(el, () => {
+            showProgressBar && showAndStartProgressBar()
 
-        let fromDestination = extractDestinationFromLink(el)
+            let fromDestination = extractDestinationFromLink(el)
 
-        fetchHtmlOrUsePrefetchedHtml(fromDestination, html => {
-            restoreScroll && storeScrollInformationInHtmlBeforeNavigatingAway()
+            fetchHtmlOrUsePrefetchedHtml(fromDestination, html => {
+                restoreScroll && storeScrollInformationInHtmlBeforeNavigatingAway()
 
-            showProgressBar && finishAndHideProgressBar()
+                showProgressBar && finishAndHideProgressBar()
 
-            updateCurrentPageHtmlInHistoryStateForLaterBackButtonClicks()
+                updateCurrentPageHtmlInHistoryStateForLaterBackButtonClicks()
 
-            preventAlpineFromPickingUpDomChanges(Alpine, andAfterAllThis => {
-                enablePersist && storePersistantElementsForLater()
+                preventAlpineFromPickingUpDomChanges(Alpine, andAfterAllThis => {
+                    enablePersist && storePersistantElementsForLater()
 
-                swapCurrentPageWithNewHtml(html, () => {
-                    enablePersist && putPersistantElementsBack()
+                    swapCurrentPageWithNewHtml(html, () => {
+                        enablePersist && putPersistantElementsBack()
 
-                    // Added setTimeout here to detect a currently hovered prefetch link...
-                    // (hack for laracon)
-                    setTimeout(() => hijackNewLinksOnThePage())
+                        restoreScroll && restoreScrollPosition()
 
-                    restoreScroll && restoreScrollPosition()
+                        fireEventForOtherLibariesToHookInto()
 
-                    fireEventForOtherLibariesToHookInto()
+                        updateUrlAndStoreLatestHtmlForFutureBackButtons(html, fromDestination)
 
-                    updateUrlAndStoreLatestHtmlForFutureBackButtons(html, fromDestination)
+                        andAfterAllThis(() => {
+                            autofocus && autofocusElementsWithTheAutofocusAttribute()
 
-                    andAfterAllThis(() => {
-                        autofocus && autofocusElementsWithTheAutofocusAttribute()
-
-                        nowInitializeAlpineOnTheNewPage(Alpine)
+                            nowInitializeAlpineOnTheNewPage(Alpine)
+                        })
                     })
                 })
-
             })
         })
     })
 
+    updateCurrentPageHtmlInHistoryStateForLaterBackButtonClicks()
+
     whenTheBackOrForwardButtonIsClicked((html) => {
         // @todo: see if there's a way to update the current HTML BEFORE
         // the back button is hit, and not AFTER:

+ 9 - 42
packages/navigate/src/links.js

@@ -1,51 +1,18 @@
 
-let handleLinkClick = () => {}
-let handleLinkHover = () => {}
+export function whenThisLinkIsClicked(el, callback) {
+    el.addEventListener('click', e => {
+        e.preventDefault()
 
-export function whenALinkIsClicked(callback) {
-    handleLinkClick = callback
-
-    initializeLinksForClicking()
+        callback(el)
+    })
 }
 
-export function whenALinkIsHovered(callback) {
-    handleLinkHover = callback
-
-    initializeLinksForHovering()
+export function whenThisLinkIsHovered(el, callback) {
+    el.addEventListener('mouseenter', e => {
+        callback(e)
+    })
 }
 
 export function extractDestinationFromLink(linkEl) {
     return new URL(linkEl.getAttribute('href'), document.baseURI)
 }
-
-export function hijackNewLinksOnThePage() {
-    initializeLinksForClicking()
-    initializeLinksForHovering()
-}
-
-function initializeLinksForClicking() {
-    getLinks().forEach(el => {
-        el.addEventListener('click', e => {
-            e.preventDefault()
-
-            handleLinkClick(el)
-        })
-    })
-}
-
-function initializeLinksForHovering() {
-    getLinks()
-        .filter(i => i.hasAttribute('wire:navigate.prefetch'))
-        .forEach(el => {
-            el.addEventListener('mouseenter', e => {
-                handleLinkHover(el)
-            })
-        })
-}
-
-function getLinks() {
-    return Array.from(document.links)
-        .filter(i => i.hasAttribute('wire:navigate')
-        || i.hasAttribute('wire:navigate.prefetch'))
-}
-