xref: /aosp_15_r20/external/executorch/docs/source/_static/js/progress-bar.js (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9document.addEventListener("DOMContentLoaded", function() {
10  const steps = Array.from(document.querySelectorAll('.progress-bar-item'));
11  const h2s = Array.from(document.querySelectorAll('h2'));
12
13  // Populate captions from h2s
14  h2s.forEach((h2, index) => {
15    const captionElem = document.getElementById(`caption-${index + 1}`);
16    if (captionElem) {
17      captionElem.innerText = h2.innerText;
18    }
19  });
20
21  // Throttle function to optimize performance
22  function throttle(func, delay) {
23    let lastCall = 0;
24    return function() {
25      const now = Date.now();
26      if (now - lastCall < delay) return;
27      lastCall = now;
28      func.apply(this, arguments);
29    }
30  }
31
32  document.addEventListener("scroll", throttle(function() {
33    let activeIndex = 0;
34    let closestDistance = Number.MAX_VALUE;
35    const totalHeight = document.documentElement.scrollHeight;
36    const viewportHeight = window.innerHeight;
37    const scrollBottom = window.scrollY + viewportHeight;
38    const isAtBottom = totalHeight === scrollBottom;
39
40    h2s.forEach((h2, index) => {
41      const rect = h2.getBoundingClientRect();
42      const distanceToTop = Math.abs(rect.top);
43      if (distanceToTop < closestDistance) {
44        closestDistance = distanceToTop;
45        activeIndex = index;
46      }
47    });
48
49    steps.forEach((step, index) => {
50      if (isAtBottom) {
51        step.classList.remove('active');
52        step.classList.add('completed');
53      } else {
54        if (index < activeIndex) {
55          step.classList.remove('active');
56          step.classList.add('completed');
57        } else if (index === activeIndex) {
58          step.classList.add('active');
59          step.classList.remove('completed');
60        } else {
61          step.classList.remove('active', 'completed');
62        }
63      }
64    });
65  }, 100));
66});
67