@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.53 kB
JavaScript
;(()=>{var l,s,g,r,p,b=e=>{history.state?.vtbagId??history.replaceState({vtbagId:history.length},""),s=parseInt(sessionStorage.getItem("vtbag-id")??"NaN",10),r=history.state.vtbagId,l=sessionStorage.getItem("vtbag-navigation-type"),sessionStorage.setItem("vtbag-id",""+r),g=sessionStorage.getItem("vtbag-from"),p=sessionStorage.getItem("vtbag-to")};addEventListener("pagereveal",b);var y=e=>{e.activation&&(l=e.activation.navigationType,g=e.activation.from?.url??"",p=e.activation.entry.url??"",s=history.state?.vtbagId,r=l==="push"?s+(g===p?0:1):l==="replace"?s:e.activation.entry.index!==-1?s+(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",y);var c=document.currentScript;function w(e,a){let t,n,i=["backward","same","forward"],o=c.dataset.directionAttribute;return o&&(i=o.trim().split(/\s*,\s*/),i.length!==4?console.error(`[turn-signal] syntax error: data-direction-attribute value "${o}" does not match "attributeName, backwardValue, sameValue, forwardValue"`):(n=i.shift(),t=e<a?i[0]:e===a?i[1]:i[2])),{attributeName:n,value:t}}function h(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 m(e){if(!e.viewTransition)return;let a=r,t=s,n=S();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:i,value:o}=w(a,t);i&&o&&(document.documentElement.setAttribute(i,o),e.viewTransition.finished.then(()=>document.documentElement.removeAttribute(i)),sessionStorage.setItem("vtbag-signal-attribute",`${i} ${o}`)),o=h(a,t),o&&(e.viewTransition.types?.add(o),sessionStorage.setItem("vtbag-signal-type",o))}e.viewTransition.types?.add(e.type==="pageswap"?"old":"new")}function S(){let e=c.dataset.selector;return e?[...document.querySelectorAll(e)].map(t=>new URL(t.href??".",location.href).pathname):[]}"onpageswap"in window&&addEventListener("pageswap",m);"onpagereveal"in window&&addEventListener("pagereveal",m);var v=null,T=()=>{document.addEventListener("click",e=>{let a=e.composedPath()[0];v=a instanceof Element?a.closest("a, area"):null})};addEventListener("DOMContentLoaded",T);function u(){return v}var E="data-vtbag-link-types",d="vtbag-all-link-types",I=e=>{let a=u();if(!e.viewTransition)return;let t=JSON.parse(sessionStorage.getItem(d)??"[]"),n="";if(!isNaN(r))if(r<s)n=(t[r]??"").split(/\s*\/\s*/)[0]??"";else{l==="traverse"?n=t[s]??"":(a&&(n=a.getAttribute(E)??""),t[s]=n,sessionStorage.setItem(d,JSON.stringify(t)));let i=n.split(/\s*\/\s*/);s===r?n=i[~~((i.length-1)/2)]??"":n=i[i.length-1]??""}f(n+" old",e)};addEventListener("pageswap",I);var L=e=>{if(!e.viewTransition)return;let a=JSON.parse(sessionStorage.getItem(d)??"[]"),t=a[r]??"";if(r<s)t=t.split(/\s*\/\s*/)[0]??"";else{let n=(a[s]??"").split(/\s*\/\s*/);s===r?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))}})();