function getPos(element) { /* Element.getBoundingClientRect() * Return box of the element relatively to viewport. */ const rect = element.getBoundingClientRect(); /* The properties window.scrollX and window.scrollY * return the viewport position relatively to the document */ return { x: rect.left + window.scrollX, y: rect.top + window.scrollY, }; } // Use this if needed : // const getTop = element => element.offsetTop + (element.offsetParent && getTop(element.offsetParent)); let articles; const resize = () => { for (const [article, sidenote] of articles) { if (sidenote.offsetWidth < 200 || window.screen.width < 1400) { sidenote.innerHTML = ""; return; } const notes = Array.from(article.querySelectorAll("li")).filter((element) => element.id.startsWith("user-content-fn"), ); const newSidenotes = notes.map((sidenoteLi) => { const div = document.createElement("div"); const refName = sidenoteLi.querySelector(".data-footnote-backref") .attributes.href.value; const refSideNode = article.querySelector( `#${CSS.escape(refName.slice(1))}`, ); const sup = document.createElement("sup"); sup.textContent = refSideNode.textContent + " "; for (const element of sidenoteLi.children) { const child = element.cloneNode(true); div.append(child); } div.children[0].prepend(sup); div.style.top = `${getPos(refSideNode).y}px`; div.classList.add("sidenote"); return div; }); sidenote.replaceChildren(...newSidenotes); if (sidenote.offsetWidth < 100 || window.screen.width < 1400) { sidenote.innerHTML = ""; return; } } }; window.addEventListener("DOMContentLoaded", () => { articles = Array.from(document.querySelectorAll("article")); if (articles.length > 0) { articles = articles.map((x) => [ x, x.parentElement.querySelector(".sidenotes"), ]); new ResizeObserver(resize).observe(articles[0][1]); } if (document.querySelectorAll(".math-display").length > 0) { document.head.innerHTML += ''; } });