@localnerve/jump-scroll 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jump-scroll.js +2 -2
- package/package.json +1 -1
package/dist/jump-scroll.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! jump-scroll@0.9.
|
|
2
|
-
class t extends HTMLElement{#t=null;#e=null;#s=null;#r=!0;#i=!1;#o=0;#n="";#a=null;#l=null;#c=null;#h=null;#u=null;static#d=15;#p=null;#b=null;#g=null;#v=null;#m=null;#y=null;#f=null;#T=!1;#w=!1;#k=0;static#I=800;static#C=["target"];static#S={target:"section",display:"best",colormap:"",enablekeyboard:!0,scrollcontainer:""};static get observedAttributes(){return[...t.#C,"display","colormap","enablekeyboard","scrollcontainer"]}static getNumber(t){return parseFloat(t.replace(/[^.+\-\d]+/,""))}constructor(){super(),this.attachShadow({mode:"open",delegatesFocus:!0}),this.targetIntersection=this.targetIntersection.bind(this),this.controlIntersection=this.controlIntersection.bind(this),this.resizeHandler=this.resizeHandler.bind(this),this.clickTop=this.clickTop.bind(this),this.clickBottom=this.clickBottom.bind(this),this.clickNext=this.clickNext.bind(this),this.clickPrev=this.clickPrev.bind(this),this.controlBlur=this.controlBlur.bind(this),this.keydownHandler=this.keydownHandler.bind(this)}#A(e){if(this.hasAttribute(e)){const t=this.getAttribute(e);return/^\s*(?:true|false)\s*$/i.test(t)?"false"!==t:t}return t.#S[e]}get currentTarget(){return this.#h}set currentTarget(t){this.#u.has(t)&&(this.#h=t,this.#j())}jumpScroll(t){const e=this.#u.get(t);e&&(this.currentTarget=e.prev,this.#x("next",(t=>t<window.innerHeight)))}get target(){return this.#A("target")}set target(t){const e="target";t?this.setAttribute(e,t):this.removeAttribute(e),this.#E(e)}get display(){return this.#A("display")}set display(t){const e="display",s=["both","best"];this.#b&&this.#b.classList.remove(...s.concat("up","down")),s.includes(t)?(this.setAttribute(e,t),this.#B(),this.#O(),this.#b&&this.#b.classList.add(t)):this.removeAttribute(e)}get colormap(){return this.#A("colormap")}set colormap(t){if(null===this.#b)return;this.#p&&this.#p.clear(),this.#p=null;const e="colormap",s=t&&t.split(";");if(s&&s.length>0&&s[0].includes("@")){this.setAttribute(e,t),this.#p=new Map;for(const t of s){let[e,s]=t.replace(/\s/,"").split("@"),[r,i]=s.replace(/\s/,"").split("/");r.startsWith("--")&&(r=`var(${r})`),i?.startsWith("--")&&(i=`var(${i})`),document.querySelectorAll(e).forEach((t=>{this.#p.set(t,{bgColor:r,bgColorFocus:i})}))}}else this.removeAttribute(e)}keydownHandler(t){const e={PageDown:{true:this.clickBottom,false:this.clickNext},Space:{true:this.clickPrev,false:this.clickNext},PageUp:{true:this.clickTop,false:this.clickPrev}},s=e[t.code]?.[Boolean(t.shiftKey).toString()];s&&s(t)}get enableKeyboard(){return this.#A("enablekeyboard")}set enableKeyboard(t){if(!this.#f)return;const e=t?"addEventListener":"removeEventListener";this.#f[e]("keydown",this.keydownHandler),this.setAttribute("enablekeyboard",t)}#L(){if(!this.#a||!this.#u)return;let t,e,s=1e6;const r=[],i=this.#u.keys();for(const o of i){for(e=o,t=0;e.parentElement;e=e.parentElement)t++;t<=s&&(s=t,r.unshift(o))}let o=r[0].parentElement??r[0];if(r.length>1){const t=new Range;t.setStart(r[0],0),t.setEnd(r[1],0),t.collapsed&&(t.setStart(r[1],0),t.setEnd(r[0],0)),o=t.commonAncestorContainer??o}return o}get scrollContainer(){return this.#A("scrollcontainer")}set scrollContainer(t){if(!this.#a||!this.#u)return;let e;if(this.#f?.id&&this.#f.id.startsWith("js-")&&(this.#f.id=""),t&&(e=document.querySelector(t)),this.#f=e??this.#L(),this.#f){let t;if(this.#f.id)t=this.#f.id;else{const e=new Uint8Array(10);t=`js-${btoa(crypto.getRandomValues(e))}`,this.#f.id=t}if(this.setAttribute("aria-controls",t),this.setAttribute("aria-valuemin","0"),this.#u){const t=this.#u.size-1;this.setAttribute("aria-valuemax",t>0?t:1)}}}#j(){this.#u&&this.setAttribute("aria-valuenow",this.#u.get(this.#h).index)}#z(t,e){const s=t=>{const e=this.#y;return Array.from(this.#b.querySelectorAll(`.${t} button`)).forEach((t=>{t.blur(),t.setAttribute("disabled","true"),t.setAttribute("aria-hidden","true")})),this.#g.get(e)},r=(t,e)=>{Array.from(this.#b.querySelectorAll(`.${t} button`)).forEach((t=>{t.removeAttribute("disabled"),t.setAttribute("aria-hidden","false"),t===e&&t.focus()}))};"mid"===t?"both"===this.display?["top","bot"].forEach((t=>r(t))):"down"===e?r("bot",s("top")):r("top",s("bot")):"start"===t?r("bot",s("top")):r("top",s("bot"))}#R(t){const e=[t],s=["mid","start","end","rest","up","down"];null!==this.#a&&s.push("none"),"best"===this.display&&"mid"===t&&(this.#r?e.push("down"):e.push("up")),this.#z(t,e[e.length-1]),this.#b.classList.remove(...s),this.#b.classList.add(...e),setTimeout((()=>{this.#b.classList.add("rest")}),500)}#x(e,s){const r=this.#u.get(this.#h);if(r[e]){const i=r[e],o=this.#u.get(i),n=Math.round(o.lastTop);this.currentTarget=i,this.#h.scrollIntoView({block:"nearest",inline:"start",behavior:"smooth"}),setTimeout((()=>{n===Math.round(o.lastTop)&&(s(n)?this.#x(e,s):window.scrollBy({top:n,behavior:"smooth"}))}),16.67*t.#d)}else this.#h.scrollIntoView({block:"nearest",inline:"start",behavior:"smooth"})}#F(t="start"){this.currentTarget="start"===t?this.#a:this.#l,this.#h.scrollIntoView({block:"nearest",inline:"start",behavior:"smooth"}),this.#R(t)}clickTop(t){t&&t.preventDefault(),this.#F("start")}clickBottom(t){t&&t.preventDefault(),this.#F("end")}clickNext(t){t&&t.preventDefault(),this.#x("next",(t=>t<window.innerHeight))}clickPrev(t){t&&t.preventDefault(),this.#x("prev",(t=>t>0))}saveFocus(t){this.#y=t}controlBlur(){this.#y=null}#E(e,s){if(!t.#C.includes(e)||!this.#T)return;let r,i;this.#a=null,this.#l=null,this.#c=null,this.#h=null,this.#u?this.#u.clear():this.#u=new Map;const o=[];if(document.querySelectorAll(this[e]).forEach((t=>{for(r=t.getBoundingClientRect(),i=0;i<o.length&&!(r.top<o[i].top);i++);(0===i||i>0&&o[i-1].top!==r.top)&&o.splice(i,0,{top:r.top,bot:r.bottom,el:t}),"function"==typeof s&&s(t)})),o.length>0){this.#a=o[0].el,this.#l=o[o.length-1].el,this.#c=new WeakMap([[this.#a,{pos:"start",down:!0}],[this.#l,{pos:"end",down:!1}]]);let t=0,e=0;const s=window.innerHeight;for(i=0;i<o.length;i++)0>o[i].top&&(e=o[i].bot<s?1:0,t=i+e<o.length?i+e:i),this.#u.set(o[i].el,{index:i,prev:i>0?o[i-1].el:null,next:i<o.length-1?o[i+1].el:null});this.currentTarget=o[t].el,0===t?this.#R("start"):t===o.length-1?this.#R("end"):this.#R("mid")}}targetIntersection(t){const e=t=>{const e=this.#u.get(t.target);t.isIntersecting&&t.intersectionRatio>=.95?e.lastTop?e.lastTop<t.boundingClientRect.top&&(e.lastTop=t.boundingClientRect.top):e.lastTop=t.boundingClientRect.top:t.isIntersecting||(e.lastTop=void 0)};let s,r;const i=(t,e,s,r)=>{let i=t;const o=s.target===e&&s||r.target===e&&r;return o&&(i?o.intersectionRatio<i.intersectionRatio&&(i=o):i=o),i},o=t.sort(((t,o)=>{const n=t.isIntersecting&&o.isIntersecting;let a=t.isIntersecting?-1:o.isIntersecting?1:0;return s=i(s,this.#a,t,o),r=i(r,this.#l,t,o),e(t),e(o),n&&(a=o.intersectionRatio-t.intersectionRatio),a}))[0],n=o.rootBounds?.height??1e6,a=o.boundingClientRect.height,l=a<=n?.49:n/2/a;if(o.isIntersecting){const t=this.#u.get(this.#h),e=this.#c.has(o.target),i=this.#u.get(o.target),n=o.boundingClientRect.top,a=o.intersectionRatio,c=o.target,h=e?0:l,{pos:u,down:d}=this.#c.get(c)??{pos:"mid",down:void 0===i.lastTop?this.#r:n<i.lastTop};if(i.lastTop=n,"mid"!==u)this.#i=a>l&&u;else if(this.#i){const t="start"===this.#i?s:r;t&&t.intersectionRatio<=l&&(this.#i=!1)}if(!this.#i||"mid"!==u){(this.#r?i.index>t.index:i.index<t.index)&&a>h&&(this.currentTarget=c),this.#R(u),this.#r=d}this.#i&&o.intersectionRatio>=.98&&(this.currentTarget=c)}else o.intersectionRatio<=l&&(this.#u.get(o.target).lastTop=void 0)}controlIntersection(t,e){if(this.#p&&!this.#w){const s=e.filter((t=>t.isIntersecting));if(s.length>0){const e=s[0],{bgColor:r,bgColorFocus:i}=this.#p.get(e.target);this.#o++,this.#n=t,r?this.#b.style.setProperty("--js-bg-color",r):(this.#b.style.removeProperty("--js-bg-color"),this.#o=0),i?this.#b.style.setProperty("--js-bg-color-focus",i):this.#b.style.removeProperty("--js-bg-color-focus")}else{this.#o--;const e=t!==this.#n,s=this.#o<=0&&t===this.#n;(e||s)&&(this.#b.style.removeProperty("--js-bg-color"),this.#b.style.removeProperty("--js-bg-color-focus"),this.#o=0)}}}#O(){if(!this.#u)return;const e=window.innerHeight,s=this.offsetHeight,r=e-s,i=Math.abs(s-2),o=t.getNumber(window.getComputedStyle(this).bottom),n=e-o-2;this.#t=new IntersectionObserver(this.targetIntersection,{threshold:[.1,.2,.3,.4,.5,.6,.7,.8,.9,1]}),this.#e=new IntersectionObserver(this.controlIntersection.bind(null,"top"),{threshold:0,rootMargin:`-${r}px 0px -${i}px 0px`}),this.#s=new IntersectionObserver(this.controlIntersection.bind(null,"bot"),{threshold:0,rootMargin:`-${n}px 0px -${o}px 0px`});const a=this.#u.keys();for(const t of a)this.#t.observe(t);const l=this.#p.keys();for(const t of l)this.#e.observe(t),this.#s.observe(t)}#B(){this.#t&&this.#t.disconnect(),this.#e&&this.#e.disconnect(),this.#s&&this.#s.disconnect(),this.#t=null,this.#e=null,this.#s=null}resizeHandler(){this.#w||(this.#w=!0,setTimeout((()=>{let t=!1;const e=window.innerWidth;e!==this.#k&&(e>this.#k&&(t=!0),this.#k=e),this.#H(!1,t),this.#w=!1}),t.#I))}#M(){this.#w=!1,window.addEventListener("resize",this.resizeHandler)}#q(){window.removeEventListener("resize",this.resizeHandler),this.#w=!1}#H(e=!0,s=!0){let r=!1;this.#T?this.#P(e,s):r=!0,this.#T=!0,s&&t.#C.forEach((t=>{this.#E(t)})),r&&(this.#k=window.innerWidth,this.setAttribute("aria-label","Alternate scroller, jump directly to author's sections"),this.scrollContainer=this.scrollContainer,this.enableKeyboard=this.enableKeyboard),this.#O(),e&&this.#M()}#P(t=!0,e=!0){t&&this.#q(),this.#B(),e&&(this.#a=null,this.#l=null,this.#c=null,this.#h=null,this.#u&&this.#u.clear(),this.#u=null,this.#f=null,this.enableKeyboard=!1,this.#T=!1)}connectedCallback(){"complete"!==document.readyState?window.addEventListener("load",(()=>{this.#H()}),{once:!0}):this.#H();const{shadowRoot:t}=this;t.innerHTML='<style>:host{--js-width:3rem;--js-aspect-ratio:0.2;--js-height:calc(var(--js-width) * (1 / var(--js-aspect-ratio)));--js-bg-color:black;--js-bg-color-focus:darkorange;--js-bg-spread-focus:8px;--js-color:white;--js-opacity-full:0.8;--js-opacity-rest:0.5;--js-attach-right:1rem;--js-attach-bottom:1rem;position:fixed;bottom:var(--js-attach-bottom);right:var(--js-attach-right);color:var(--js-color)}.container{display:block;transition:opacity 1s;opacity:var(--js-opacity-full);width:var(--js-width);height:auto;aspect-ratio:var(--js-aspect-ratio)}.container button{padding:0;margin:0;border:none;color:transparent}.container.best{aspect-ratio:calc(var(--js-aspect-ratio) * 2)}.container.none{display:none}.container.rest{opacity:var(--js-opacity-rest)}.container.mid{transform:none}.container.best.mid.down .top,.container.start .top{pointer-events:none;opacity:0}.container.best.mid.up .bot,.container.end .bot{pointer-events:none;opacity:0;transform:translateY(102%)}.container.best.end .top,.container.best.mid.down .top,.container.best.mid.up .top{transform:translateY(5%)}.container.end .top{transform:translateY(102%)}button:hover{cursor:pointer}.bot,.top{position:absolute;width:var(--js-width);height:auto;aspect-ratio:calc(var(--js-aspect-ratio) * 2);transition:opacity 1s,transform 1s;pointer-events:auto}.top{top:0}.bot{bottom:0}.bc:focus-within{filter:drop-shadow(0px 0px var(--js-bg-spread-focus) var(--js-bg-color-focus))}.bc{position:absolute;width:var(--js-width)}.bc-end,.bc-start{height:calc(var(--js-height)/ 6)}.bc-next,.bc-prev{height:calc(var(--js-height)/ 4)}.bc-start{top:0}.bc-end{bottom:0}.bc-prev{top:calc((var(--js-height)/ 6) + 10%)}.bc-next{bottom:calc((var(--js-height)/ 6) + 10%)}.bot .end,.bot .next,.top .prev,.top .start{position:absolute;left:50%;width:100%;background:var(--js-bg-color);-webkit-user-select:none;user-select:none}.bot .end,.top .start{height:calc(var(--js-height)/ 6);clip-path:polygon(10% 0%,90% 0%,90% 30%,65% 30%,100% 100%,0% 100%,35% 30%,10% 30%)}.bot .next,.top .prev{height:calc(var(--js-height)/ 4);clip-path:polygon(50% 0%,100% 60%,65% 60%,100% 100%,0% 100%,35% 60%,0% 60%)}.top .prev,.top .start{transform:translateX(-50%)}.bot .end,.bot .next{transform:translateX(-50%) rotateX(180deg)}</style><div class="container none"><div class="top"><div class="bc bc-start"><button type="button" class="start">Scroll to start</button></div><div class="bc bc-prev"><button type="button" class="prev">Scroll to previous</button></div></div><div class="bot"><div class="bc bc-next"><button type="button" class="next">Scroll to next</button></div><div class="bc bc-end"><button type="button" class="end">Scroll to end</button><div></div></div>',this.#b=t.querySelector(".container"),this.display=this.display,this.colormap=this.colormap,this.addEventListener("blur",this.controlBlur),this.#v=[this.#b.querySelector('button[class*="next"]'),this.#b.querySelector('button[class*="prev"]'),this.#b.querySelector('button[class*="start"]'),this.#b.querySelector('button[class*="end"]')],this.#m=this.#v.map((t=>this.saveFocus.bind(this,t))),this.#v.forEach(((t,e)=>{t.addEventListener("focus",this.#m[e])})),this.#g=new WeakMap([[this.#v[0],this.#v[1]],[this.#v[1],this.#v[0]],[this.#v[2],this.#v[3]],[this.#v[3],this.#v[2]]]),t.querySelector(".bc-start").addEventListener("click",this.clickTop),t.querySelector(".bc-end").addEventListener("click",this.clickBottom),t.querySelector(".bc-prev").addEventListener("click",this.clickPrev),t.querySelector(".bc-next").addEventListener("click",this.clickNext)}disconnectedCallback(){this.#b=null,this.#y=null,this.#g=null,this.removeEventListener("blur",this.controlBlur),this.#v.forEach(((t,e)=>{t.removeEventListener("focus",this.#m[e])})),this.#v=null,this.#m=null,this.shadowRoot.querySelector(".bc-start").removeEventListener("click",this.clickTop),this.shadowRoot.querySelector(".bc-end").removeEventListener("click",this.clickBottom),this.shadowRoot.querySelector(".bc-prev").removeEventListener("click",this.clickPrev),this.shadowRoot.querySelector(".bc-next").removeEventListener("click",this.clickNext),this.#P()}attributeChangedCallback(t,e,s){s!==e&&(this[t]=this.getAttribute(t))}}customElements.define("jump-scroll",t);
|
|
1
|
+
/*! jump-scroll@0.9.2, Copyright (c) 2023 Alex Grant (alex@localnerve.com), LocalNerve LLC, BSD-3-Clause */
|
|
2
|
+
class t extends HTMLElement{#t=null;#e=null;#s=null;#r=!0;#i=!1;#o=0;#n="";#a=null;#l=null;#c=null;#h=null;#u=null;static#d=15;#p=null;#b=null;#g=null;#v=null;#m=null;#y=null;#f=null;#T=!1;#w=!1;#k=0;static#I=800;static#C=["target"];static#S={target:"section",display:"best",colormap:"",enablekeyboard:!0,scrollcontainer:""};static get observedAttributes(){return[...t.#C,"display","colormap","enablekeyboard","scrollcontainer"]}static getNumber(t){return parseFloat(t.replace(/[^.+\-\d]+/,""))}constructor(){super(),this.attachShadow({mode:"open",delegatesFocus:!0}),this.targetIntersection=this.targetIntersection.bind(this),this.controlIntersection=this.controlIntersection.bind(this),this.resizeHandler=this.resizeHandler.bind(this),this.clickTop=this.clickTop.bind(this),this.clickBottom=this.clickBottom.bind(this),this.clickNext=this.clickNext.bind(this),this.clickPrev=this.clickPrev.bind(this),this.controlBlur=this.controlBlur.bind(this),this.keydownHandler=this.keydownHandler.bind(this)}#A(e){if(this.hasAttribute(e)){const t=this.getAttribute(e);return/^\s*(?:true|false)\s*$/i.test(t)?"false"!==t:t}return t.#S[e]}get currentTarget(){return this.#h}set currentTarget(t){this.#u.has(t)&&(this.#h=t,this.#j())}jumpScroll(t){if(t!==this.#h){const e=this.#u.get(t);e&&(this.currentTarget=e.prev,this.#x("next",(t=>t<window.innerHeight)))}}get target(){return this.#A("target")}set target(t){const e="target";t?this.setAttribute(e,t):this.removeAttribute(e),this.#E(e)}get display(){return this.#A("display")}set display(t){const e="display",s=["both","best"];this.#b&&this.#b.classList.remove(...s.concat("up","down")),s.includes(t)?(this.setAttribute(e,t),this.#B(),this.#O(),this.#b&&this.#b.classList.add(t)):this.removeAttribute(e)}get colormap(){return this.#A("colormap")}set colormap(t){if(null===this.#b)return;this.#p&&this.#p.clear(),this.#p=null;const e="colormap",s=t&&t.split(";");if(s&&s.length>0&&s[0].includes("@")){this.setAttribute(e,t),this.#p=new Map;for(const t of s){let[e,s]=t.replace(/\s/,"").split("@"),[r,i]=s.replace(/\s/,"").split("/");r.startsWith("--")&&(r=`var(${r})`),i?.startsWith("--")&&(i=`var(${i})`),document.querySelectorAll(e).forEach((t=>{this.#p.set(t,{bgColor:r,bgColorFocus:i})}))}}else this.removeAttribute(e)}keydownHandler(t){const e={PageDown:{true:this.clickBottom,false:this.clickNext},Space:{true:this.clickPrev,false:this.clickNext},PageUp:{true:this.clickTop,false:this.clickPrev}},s=e[t.code]?.[Boolean(t.shiftKey).toString()];s&&s(t)}get enableKeyboard(){return this.#A("enablekeyboard")}set enableKeyboard(t){if(!this.#f)return;const e=t?"addEventListener":"removeEventListener";this.#f[e]("keydown",this.keydownHandler),this.setAttribute("enablekeyboard",t)}#L(){if(!this.#a||!this.#u)return;let t,e,s=1e6;const r=[],i=this.#u.keys();for(const o of i){for(e=o,t=0;e.parentElement;e=e.parentElement)t++;t<=s&&(s=t,r.unshift(o))}let o=r[0].parentElement??r[0];if(r.length>1){const t=new Range;t.setStart(r[0],0),t.setEnd(r[1],0),t.collapsed&&(t.setStart(r[1],0),t.setEnd(r[0],0)),o=t.commonAncestorContainer??o}return o}get scrollContainer(){return this.#A("scrollcontainer")}set scrollContainer(t){if(!this.#a||!this.#u)return;let e;if(this.#f?.id&&this.#f.id.startsWith("js-")&&(this.#f.id=""),t&&(e=document.querySelector(t)),this.#f=e??this.#L(),this.#f){let t;if(this.#f.id)t=this.#f.id;else{const e=new Uint8Array(10);t=`js-${btoa(crypto.getRandomValues(e))}`,this.#f.id=t}if(this.setAttribute("aria-controls",t),this.setAttribute("aria-valuemin","0"),this.#u){const t=this.#u.size-1;this.setAttribute("aria-valuemax",t>0?t:1)}}}#j(){this.#u&&this.setAttribute("aria-valuenow",this.#u.get(this.#h).index)}#z(t,e){const s=t=>{const e=this.#y;return Array.from(this.#b.querySelectorAll(`.${t} button`)).forEach((t=>{t.blur(),t.setAttribute("disabled","true"),t.setAttribute("aria-hidden","true")})),this.#g.get(e)},r=(t,e)=>{Array.from(this.#b.querySelectorAll(`.${t} button`)).forEach((t=>{t.removeAttribute("disabled"),t.setAttribute("aria-hidden","false"),t===e&&t.focus()}))};"mid"===t?"both"===this.display?["top","bot"].forEach((t=>r(t))):"down"===e?r("bot",s("top")):r("top",s("bot")):"start"===t?r("bot",s("top")):r("top",s("bot"))}#R(t){const e=[t],s=["mid","start","end","rest","up","down"];null!==this.#a&&s.push("none"),"best"===this.display&&"mid"===t&&(this.#r?e.push("down"):e.push("up")),this.#z(t,e[e.length-1]),this.#b.classList.remove(...s),this.#b.classList.add(...e),setTimeout((()=>{this.#b.classList.add("rest")}),500)}#x(e,s){const r=this.#u.get(this.#h);if(r[e]){const i=r[e],o=this.#u.get(i),n=Math.round(o.lastTop);this.currentTarget=i,this.#h.scrollIntoView({block:"nearest",inline:"start",behavior:"smooth"}),setTimeout((()=>{n===Math.round(o.lastTop)&&(s(n)?this.#x(e,s):window.scrollBy({top:n,behavior:"smooth"}))}),16.67*t.#d)}else this.#h.scrollIntoView({block:"nearest",inline:"start",behavior:"smooth"})}#F(t="start"){this.currentTarget="start"===t?this.#a:this.#l,this.#h.scrollIntoView({block:"nearest",inline:"start",behavior:"smooth"}),this.#R(t)}clickTop(t){t&&t.preventDefault(),this.#F("start")}clickBottom(t){t&&t.preventDefault(),this.#F("end")}clickNext(t){t&&t.preventDefault(),this.#x("next",(t=>t<window.innerHeight))}clickPrev(t){t&&t.preventDefault(),this.#x("prev",(t=>t>0))}saveFocus(t){this.#y=t}controlBlur(){this.#y=null}#E(e,s){if(!t.#C.includes(e)||!this.#T)return;let r,i;this.#a=null,this.#l=null,this.#c=null,this.#h=null,this.#u?this.#u.clear():this.#u=new Map;const o=[];if(document.querySelectorAll(this[e]).forEach((t=>{for(r=t.getBoundingClientRect(),i=0;i<o.length&&!(r.top<o[i].top);i++);(0===i||i>0&&o[i-1].top!==r.top)&&o.splice(i,0,{top:r.top,bot:r.bottom,el:t}),"function"==typeof s&&s(t)})),o.length>0){this.#a=o[0].el,this.#l=o[o.length-1].el,this.#c=new WeakMap([[this.#a,{pos:"start",down:!0}],[this.#l,{pos:"end",down:!1}]]);let t=0,e=0;const s=window.innerHeight;for(i=0;i<o.length;i++)0>o[i].top&&(e=o[i].bot<s?1:0,t=i+e<o.length?i+e:i),this.#u.set(o[i].el,{index:i,prev:i>0?o[i-1].el:null,next:i<o.length-1?o[i+1].el:null});this.currentTarget=o[t].el,0===t?this.#R("start"):t===o.length-1?this.#R("end"):this.#R("mid")}}targetIntersection(t){const e=t=>{const e=this.#u.get(t.target);t.isIntersecting&&t.intersectionRatio>=.95?e.lastTop?e.lastTop<t.boundingClientRect.top&&(e.lastTop=t.boundingClientRect.top):e.lastTop=t.boundingClientRect.top:t.isIntersecting||(e.lastTop=void 0)};let s,r;const i=(t,e,s,r)=>{let i=t;const o=s.target===e&&s||r.target===e&&r;return o&&(i?o.intersectionRatio<i.intersectionRatio&&(i=o):i=o),i},o=t.sort(((t,o)=>{const n=t.isIntersecting&&o.isIntersecting;let a=t.isIntersecting?-1:o.isIntersecting?1:0;return s=i(s,this.#a,t,o),r=i(r,this.#l,t,o),e(t),e(o),n&&(a=o.intersectionRatio-t.intersectionRatio),a}))[0],n=o.rootBounds?.height??1e6,a=o.boundingClientRect.height,l=a<=n?.49:n/2/a;if(o.isIntersecting){const t=this.#u.get(this.#h),e=this.#c.has(o.target),i=this.#u.get(o.target),n=o.boundingClientRect.top,a=o.intersectionRatio,c=o.target,h=e?0:l,{pos:u,down:d}=this.#c.get(c)??{pos:"mid",down:void 0===i.lastTop?this.#r:n<i.lastTop};if(i.lastTop=n,"mid"!==u)this.#i=a>l&&u;else if(this.#i){const t="start"===this.#i?s:r;t&&t.intersectionRatio<=l&&(this.#i=!1)}if(!this.#i||"mid"!==u){(this.#r?i.index>t.index:i.index<t.index)&&a>h&&(this.currentTarget=c),this.#R(u),this.#r=d}this.#i&&o.intersectionRatio>=.98&&(this.currentTarget=c)}else o.intersectionRatio<=l&&(this.#u.get(o.target).lastTop=void 0)}controlIntersection(t,e){if(this.#p&&!this.#w){const s=e.filter((t=>t.isIntersecting));if(s.length>0){const e=s[0],{bgColor:r,bgColorFocus:i}=this.#p.get(e.target);this.#o++,this.#n=t,r?this.#b.style.setProperty("--js-bg-color",r):(this.#b.style.removeProperty("--js-bg-color"),this.#o=0),i?this.#b.style.setProperty("--js-bg-color-focus",i):this.#b.style.removeProperty("--js-bg-color-focus")}else{this.#o--;const e=t!==this.#n,s=this.#o<=0&&t===this.#n;(e||s)&&(this.#b.style.removeProperty("--js-bg-color"),this.#b.style.removeProperty("--js-bg-color-focus"),this.#o=0)}}}#O(){if(!this.#u)return;const e=window.innerHeight,s=this.offsetHeight,r=e-s,i=Math.abs(s-2),o=t.getNumber(window.getComputedStyle(this).bottom),n=e-o-2;this.#t=new IntersectionObserver(this.targetIntersection,{threshold:[.1,.2,.3,.4,.5,.6,.7,.8,.9,1]}),this.#e=new IntersectionObserver(this.controlIntersection.bind(null,"top"),{threshold:0,rootMargin:`-${r}px 0px -${i}px 0px`}),this.#s=new IntersectionObserver(this.controlIntersection.bind(null,"bot"),{threshold:0,rootMargin:`-${n}px 0px -${o}px 0px`});const a=this.#u.keys();for(const t of a)this.#t.observe(t);const l=this.#p.keys();for(const t of l)this.#e.observe(t),this.#s.observe(t)}#B(){this.#t&&this.#t.disconnect(),this.#e&&this.#e.disconnect(),this.#s&&this.#s.disconnect(),this.#t=null,this.#e=null,this.#s=null}resizeHandler(){this.#w||(this.#w=!0,setTimeout((()=>{let t=!1;const e=window.innerWidth;e!==this.#k&&(e>this.#k&&(t=!0),this.#k=e),this.#H(!1,t),this.#w=!1}),t.#I))}#M(){this.#w=!1,window.addEventListener("resize",this.resizeHandler)}#q(){window.removeEventListener("resize",this.resizeHandler),this.#w=!1}#H(e=!0,s=!0){let r=!1;this.#T?this.#P(e,s):r=!0,this.#T=!0,s&&t.#C.forEach((t=>{this.#E(t)})),r&&(this.#k=window.innerWidth,this.setAttribute("aria-label","Alternate scroller, jump directly to author's sections"),this.scrollContainer=this.scrollContainer,this.enableKeyboard=this.enableKeyboard),this.#O(),e&&this.#M()}#P(t=!0,e=!0){t&&this.#q(),this.#B(),e&&(this.#a=null,this.#l=null,this.#c=null,this.#h=null,this.#u&&this.#u.clear(),this.#u=null,this.#f=null,this.enableKeyboard=!1,this.#T=!1)}connectedCallback(){"complete"!==document.readyState?window.addEventListener("load",(()=>{this.#H()}),{once:!0}):this.#H();const{shadowRoot:t}=this;t.innerHTML='<style>:host{--js-width:3rem;--js-aspect-ratio:0.2;--js-height:calc(var(--js-width) * (1 / var(--js-aspect-ratio)));--js-bg-color:black;--js-bg-color-focus:darkorange;--js-bg-spread-focus:8px;--js-color:white;--js-opacity-full:0.8;--js-opacity-rest:0.5;--js-attach-right:1rem;--js-attach-bottom:1rem;position:fixed;bottom:var(--js-attach-bottom);right:var(--js-attach-right);color:var(--js-color)}.container{display:block;transition:opacity 1s;opacity:var(--js-opacity-full);width:var(--js-width);height:auto;aspect-ratio:var(--js-aspect-ratio)}.container button{padding:0;margin:0;border:none;color:transparent}.container.best{aspect-ratio:calc(var(--js-aspect-ratio) * 2)}.container.none{display:none}.container.rest{opacity:var(--js-opacity-rest)}.container.mid{transform:none}.container.best.mid.down .top,.container.start .top{pointer-events:none;opacity:0}.container.best.mid.up .bot,.container.end .bot{pointer-events:none;opacity:0;transform:translateY(102%)}.container.best.end .top,.container.best.mid.down .top,.container.best.mid.up .top{transform:translateY(5%)}.container.end .top{transform:translateY(102%)}button:hover{cursor:pointer}.bot,.top{position:absolute;width:var(--js-width);height:auto;aspect-ratio:calc(var(--js-aspect-ratio) * 2);transition:opacity 1s,transform 1s;pointer-events:auto}.top{top:0}.bot{bottom:0}.bc:focus-within{filter:drop-shadow(0px 0px var(--js-bg-spread-focus) var(--js-bg-color-focus))}.bc{position:absolute;width:var(--js-width)}.bc-end,.bc-start{height:calc(var(--js-height)/ 6)}.bc-next,.bc-prev{height:calc(var(--js-height)/ 4)}.bc-start{top:0}.bc-end{bottom:0}.bc-prev{top:calc((var(--js-height)/ 6) + 10%)}.bc-next{bottom:calc((var(--js-height)/ 6) + 10%)}.bot .end,.bot .next,.top .prev,.top .start{position:absolute;left:50%;width:100%;background:var(--js-bg-color);-webkit-user-select:none;user-select:none}.bot .end,.top .start{height:calc(var(--js-height)/ 6);clip-path:polygon(10% 0%,90% 0%,90% 30%,65% 30%,100% 100%,0% 100%,35% 30%,10% 30%)}.bot .next,.top .prev{height:calc(var(--js-height)/ 4);clip-path:polygon(50% 0%,100% 60%,65% 60%,100% 100%,0% 100%,35% 60%,0% 60%)}.top .prev,.top .start{transform:translateX(-50%)}.bot .end,.bot .next{transform:translateX(-50%) rotateX(180deg)}</style><div class="container none"><div class="top"><div class="bc bc-start"><button type="button" class="start">Scroll to start</button></div><div class="bc bc-prev"><button type="button" class="prev">Scroll to previous</button></div></div><div class="bot"><div class="bc bc-next"><button type="button" class="next">Scroll to next</button></div><div class="bc bc-end"><button type="button" class="end">Scroll to end</button><div></div></div>',this.#b=t.querySelector(".container"),this.display=this.display,this.colormap=this.colormap,this.addEventListener("blur",this.controlBlur),this.#v=[this.#b.querySelector('button[class*="next"]'),this.#b.querySelector('button[class*="prev"]'),this.#b.querySelector('button[class*="start"]'),this.#b.querySelector('button[class*="end"]')],this.#m=this.#v.map((t=>this.saveFocus.bind(this,t))),this.#v.forEach(((t,e)=>{t.addEventListener("focus",this.#m[e])})),this.#g=new WeakMap([[this.#v[0],this.#v[1]],[this.#v[1],this.#v[0]],[this.#v[2],this.#v[3]],[this.#v[3],this.#v[2]]]),t.querySelector(".bc-start").addEventListener("click",this.clickTop),t.querySelector(".bc-end").addEventListener("click",this.clickBottom),t.querySelector(".bc-prev").addEventListener("click",this.clickPrev),t.querySelector(".bc-next").addEventListener("click",this.clickNext)}disconnectedCallback(){this.#b=null,this.#y=null,this.#g=null,this.removeEventListener("blur",this.controlBlur),this.#v.forEach(((t,e)=>{t.removeEventListener("focus",this.#m[e])})),this.#v=null,this.#m=null,this.shadowRoot.querySelector(".bc-start").removeEventListener("click",this.clickTop),this.shadowRoot.querySelector(".bc-end").removeEventListener("click",this.clickBottom),this.shadowRoot.querySelector(".bc-prev").removeEventListener("click",this.clickPrev),this.shadowRoot.querySelector(".bc-next").removeEventListener("click",this.clickNext),this.#P()}attributeChangedCallback(t,e,s){s!==e&&(this[t]=this.getAttribute(t))}}customElements.define("jump-scroll",t);
|