Download src/syncHFSpacesURLHash.js from hesamation/primer-llm-embedding: direct link, hf CLI and curl.
- Browser
- Download file 3.91 kB
-
https://huggingface.co/spaces/hesamation/primer-llm-embedding/resolve/main/src/syncHFSpacesURLHash.js
- Command line
-
hf download hf://spaces/hesamation/primer-llm-embedding/src/syncHFSpacesURLHash.js
-
curl -L -o syncHFSpacesURLHash.js https://huggingface.co/spaces/hesamation/primer-llm-embedding/resolve/main/src/syncHFSpacesURLHash.js
3.91 kB
| const queryArg = "section"; | |
| function syncHFSpacesURLHash() { | |
| // Handle explicit section requests (don't update hash automatically on load) | |
| const hasExplicitRequest = handleExplicitSectionRequest(); | |
| // Set up hash change monitoring | |
| updateHashBasedOnHashChange(); | |
| // Always set up scroll monitoring to update hash during scrolling | |
| setupScrollMonitoring(); | |
| // If no explicit request, we don't update the hash on initial load | |
| // The hash will only start updating when the user scrolls | |
| } | |
| function handleExplicitSectionRequest() { | |
| // Check for section parameter in URL | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const sectionId = urlParams.get(queryArg); | |
| // If we have an explicit section request | |
| if (sectionId) { | |
| const targetElement = document.getElementById(sectionId); | |
| if (targetElement) { | |
| // Slight delay to ensure the browser doesn't try to do its own scrolling first | |
| setTimeout(() => { | |
| targetElement.scrollIntoView(); | |
| history.replaceState(null, null, `#${sectionId}`); | |
| }, 100); | |
| } | |
| return true; | |
| } | |
| // No explicit section parameter found | |
| return false; | |
| } | |
| function setupScrollMonitoring() { | |
| // Variables to manage throttling | |
| let isScrolling = false; | |
| let lastKnownScrollPosition = 0; | |
| let initialScroll = true; | |
| // Add the scroll event listener | |
| window.addEventListener('scroll', function() { | |
| lastKnownScrollPosition = window.scrollY; | |
| if (!isScrolling) { | |
| window.requestAnimationFrame(function() { | |
| // Skip the first scroll event which might be browser's automatic scroll | |
| // to a hash on page load | |
| if (initialScroll) { | |
| initialScroll = false; | |
| } else { | |
| updateHashBasedOnScroll(lastKnownScrollPosition); | |
| } | |
| isScrolling = false; | |
| }); | |
| } | |
| isScrolling = true; | |
| }); | |
| } | |
| // Function to update the URL hash based on scroll position | |
| function updateHashBasedOnScroll(scrollPosition) { | |
| const closestHeading = findClosestHeading(scrollPosition); | |
| // Update the URL hash if we found a closest element | |
| if (closestHeading && closestHeading.id) { | |
| // Only update if the hash is different to avoid unnecessary operations | |
| if (window.location.hash !== `#${closestHeading.id}`) { | |
| silentlyUpdateHash(closestHeading.id); | |
| postMessageToHFSpaces(closestHeading.id); | |
| } | |
| } | |
| } | |
| // Find the closest heading to the current scroll position | |
| function findClosestHeading(scrollPosition) { | |
| // Get only heading elements with IDs that we want to track | |
| const headingsWithIds = Array.from(document.querySelectorAll('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]')); | |
| // Skip if there are no headings with IDs | |
| if (headingsWithIds.length === 0) return null; | |
| // Find the element closest to the middle of the viewport | |
| let closestHeading = null; | |
| let closestDistance = Infinity; | |
| const viewportMiddle = scrollPosition + window.innerHeight / 2; | |
| // Iterate through all headings to find the closest one | |
| headingsWithIds.forEach(heading => { | |
| const headingTop = heading.getBoundingClientRect().top + scrollPosition; | |
| const distance = Math.abs(headingTop - viewportMiddle); | |
| if (distance < closestDistance) { | |
| closestDistance = distance; | |
| closestHeading = heading; | |
| } | |
| }); | |
| return closestHeading; | |
| } | |
| // Update hash without triggering scroll or other side effects | |
| function silentlyUpdateHash(id) { | |
| history.replaceState(null, null, `#${id}`); | |
| } | |
| function updateHashBasedOnHashChange() { | |
| window.addEventListener('hashchange', () => { | |
| const elementId = window.location.hash.slice(1); | |
| postMessageToHFSpaces(elementId); | |
| }); | |
| } | |
| function postMessageToHFSpaces(elementId) { | |
| const parentOrigin = "https://huggingface.co"; | |
| window.parent.postMessage({ queryString: `${queryArg}=${elementId}` }, parentOrigin); | |
| } | |
| export { syncHFSpacesURLHash }; | |