File size: 2,995 Bytes
8f8f7dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
const queryArg = "section";

function syncHFSpacesURLHash(){
    // Check for section parameter in URL
    const urlParams = new URLSearchParams(window.location.search);
    const sectionId = urlParams.get(queryArg);
    
    if (sectionId) {
      // Find the element with the specified ID
      const targetElement = document.getElementById(sectionId);
      
      // scroll if the element exists
      if (targetElement) {
        targetElement.scrollIntoView();
        history.replaceState(null, null, `#${sectionId}`);
      }
    }

    updateHashBasedOnHashChange();
    
    // Variables to manage throttling
    let isScrolling = false;
    let lastKnownScrollPosition = 0;
    
    // Add the scroll event listener here
    window.addEventListener('scroll', function() {
      lastKnownScrollPosition = window.scrollY;
      
      if (!isScrolling) {
        window.requestAnimationFrame(function() {
          updateHashBasedOnScroll(lastKnownScrollPosition);
          isScrolling = false;
        });
      }
      
      isScrolling = true;
    });
    
    // Initial hash update on page load
    updateHashBasedOnScroll(window.scrollY);
}

// Function to update the URL hash based on scroll position
function updateHashBasedOnScroll(scrollPosition) {
    // Get only heading elements with IDs that we want to track
    const elementsWithIds = Array.from(document.querySelectorAll('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]'));

    // Skip updating if there are no elements with IDs
    if (elementsWithIds.length === 0) return;
  
    // Find the element closest to the top of the viewport
    let closestElement = null;
    let closestDistance = Infinity;
    const viewportMiddle = scrollPosition + window.innerHeight / 2;
    
    // Iterate through all elements with IDs to find the closest one
    elementsWithIds.forEach(element => {
      const elementTop = element.getBoundingClientRect().top + scrollPosition;
      const distance = Math.abs(elementTop - viewportMiddle);
      
      if (distance < closestDistance) {
        closestDistance = distance;
        closestElement = element;
      }
    });
    
    // Update the URL hash if we found a closest element
    if (closestElement && closestElement.id) {
      // Only update if the hash is different to avoid unnecessary history entries
      if (window.location.hash !== `#${closestElement.id}`) {
        // Update the URL without adding a new history entry
        history.replaceState(null, null, `#${closestElement.id}`);
        postMessageToHFSpaces(closestElement.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 };