File size: 3,911 Bytes
8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a 8f8f7dd f9b076a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
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 };
|