@vtbag/turn-signal
Version:
Turn-Signal is a lightweight script that enhances cross-document navigation by detecting the direction of browser navigation. It enables developers to create smooth, responsive transitions that adjust based on forward or backward navigation, delivering a
2 lines (1 loc) • 3.9 kB
JavaScript
;(()=>{var l,i,g,o,p,y=e=>{history.state?.vtbagId??history.replaceState({vtbagId:history.length},""),i=parseInt(sessionStorage.getItem("vtbag-id")??"NaN",10),o=history.state.vtbagId,l=sessionStorage.getItem("vtbag-navigation-type"),sessionStorage.setItem("vtbag-id",""+o),g=sessionStorage.getItem("vtbag-from"),p=sessionStorage.getItem("vtbag-to")};addEventListener("pagereveal",y);var w=e=>{e.activation&&(l=e.activation.navigationType,g=e.activation.from?.url??"",p=e.activation.entry.url??"",i=history.state?.vtbagId,o=l==="push"?i+(g===p?0:1):l==="replace"?i:e.activation.entry.index!==-1?i+(e.activation.entry.index-(e.activation.from?.index??-1)):NaN,sessionStorage.setItem("vtbag-navigation-type",l),sessionStorage.setItem("vtbag-from",g),sessionStorage.setItem("vtbag-to",p))};addEventListener("pageswap",w);var c=document.currentScript;function b(e,a){let t,n,s=["backward","same","forward"],r=c.dataset.directionAttribute;return r&&(s=r.trim().split(/\s*,\s*/),s.length!==4?console.error(`[turn-signal] syntax error: data-direction-attribute value "${r}" does not match "attributeName, backwardValue, sameValue, forwardValue"`):(n=s.shift(),t=e<a?s[0]:e===a?s[1]:s[2])),{attributeName:n,value:t}}function T(e,a){let t=["backward","same","forward"],n=c.dataset.directionTypes;if(n&&(t=n.trim().split(/\s*,\s*/),t.length!==3)){console.error(`[turn-signal] syntax error: data-direction-types value "${n}" does not match "backwardValue, sameValue, forwardValue"`);return}return e<a?t[0]:e===a?t[1]:t[2]}function d(e){if(!e.viewTransition)return;let a=o,t=i,n=h();if(n.length&&(t=n.indexOf(new URL(g??".",location.href).pathname),a=n.indexOf(new URL(p??".",location.href).pathname)),sessionStorage.removeItem("vtbag-signal-attribute"),sessionStorage.removeItem("vtbag-signal-type"),!isNaN(a)){let{attributeName:s,value:r}=b(a,t);s&&r&&(document.documentElement.setAttribute(s,r),e.viewTransition.finished.then(()=>document.documentElement.removeAttribute(s)),sessionStorage.setItem("vtbag-signal-attribute",`${s} ${r}`)),r=T(a,t),r&&(e.viewTransition.types?.add(r),sessionStorage.setItem("vtbag-signal-type",r))}e.viewTransition.types?.add(e.type==="pageswap"?"old":"new")}function h(){let e=c.dataset.selector;return e?[...document.querySelectorAll(e)].map(t=>new URL(t.href??".",location.href).pathname):[]}"onpageswap"in window&&addEventListener("pageswap",d);"onpagereveal"in window&&addEventListener("pagereveal",d);var m=null,S=()=>{document.addEventListener("click",e=>{let a=e.composedPath()[0];m=a instanceof Element?a.closest("a, area"):null})};addEventListener("DOMContentLoaded",S);function u(){return m}var E="data-vtbag-link-types",v="vtbag-all-link-types",I=e=>{let a=u();if(!e.viewTransition)return;let t=JSON.parse(sessionStorage.getItem(v)??"[]"),n="";if(!isNaN(o))if(o<i)n=(t[o]??"").split(/\s*\/\s*/)[0]??"";else{l==="traverse"?n=t[i]??"":(a&&(n=a.getAttribute(E)??""),t[i]=n,sessionStorage.setItem(v,JSON.stringify(t)));let s=n.split(/\s*\/\s*/);i===o?n=s[~~((s.length-1)/2)]??"":n=s[s.length-1]??""}f(n+" old",e)};addEventListener("pageswap",I);var L=e=>{if(!e.viewTransition)return;let a=JSON.parse(sessionStorage.getItem(v)??"[]"),t=a[o]??"";if(o<i)t=t.split(/\s*\/\s*/)[0]??"";else{let n=(a[i]??"").split(/\s*\/\s*/);i===o?t=n[~~((n.length-1)/2)]??"":t=n[n.length-1]??""}f(t+" new",e)};addEventListener("pagereveal",L);function f(e,a){let t=e.trim().split(/\s+/);t.length>1&&t[0]==="none"&&t.shift()&&a.viewTransition?.types?.clear(),t.forEach(n=>a.viewTransition?.types?.add(n))}addEventListener("pagereveal",e=>{console.log("pagereveal",l?.slice(0,4),i,g),console.log(" ","-> ",o,p),e.viewTransition&&console.log("types: ",...e.viewTransition?.types??[])});addEventListener("pageswap",e=>{console.log("pageswap ",l?.slice(0,4),i,g),console.log(" ","-> ",o,p),e.viewTransition&&console.log("types:",...e.viewTransition.types??[])});})();