PageSourceSearch

https://ranktoday.com/wp-content/plugins/breakdance/subplugins/bre…/toc@1/breakdance-toc.js?bd_ver=2.7.2

js ranktoday.com collected 2026-10-01 12:40:54 UTC 5,604 bytes, 191 lines download raw bytes

1(function () {
2  const { mergeObjects } = BreakdanceFrontend.utils;
3
4  function slugify(text) {
5    return text
6      .toString()
7      .normalize("NFD")
8      .replace(/[\u0300-\u036f]/g, "")
9      .toLowerCase()
10      .trim()
11      .replace(/\s+/g, "-")
12      .replace(/[^\w-]+/g, "")
13      .replace(/--+/g, "-");
14  }
15
16  class BreakdanceTOC {
17    options = {
18      content: {
19        table: {
20          advanced: {
21            container_selector: "body.breakdance",
22          },
23        },
24      },
25      design: {
26        collapse: false,
27        style: "none",
28        scroll_offset: {
29          number: 10,
30        },
31        heading_offset: {
32          number: 10,
33        },
34      },
35      tocSelector: ".js-breakdance-toc",
36    };
37
38    constructor(selector, options) {
39      this.selector = selector;
40      this.element = document.querySelector(`${this.selector}`);
41      if (!this.element) return;
42      this.tocSelector = this.element.querySelector(
43        `${this.options.tocSelector}`
44      );
45      this.options = mergeObjects(this.options, options || {});
46      this.headingSelectors = this.generateSelectors();
47
48      this.init();
49    }
50
51    generateSelectors() {
52      const selectors = this.options.content.table.included_headings;
53      if (selectors) {
54        const keys = Object.keys(selectors)
55          .filter((k) => selectors[k] === true)
56          .toString();
57        return keys;
58      } else {
59        return "h2,h3,h4";
60      }
61    }
62
63    getHeadings() {
64      const containerSelector =
65        this.options.content.table.advanced.container_selector;
66      if (containerSelector.length <= 1) return [];
67      const container = document.querySelector(containerSelector);
68
69      if (!container) return [];
70
71      return [].slice.call(container.querySelectorAll(this.headingSelectors));
72    }
73
74    setHeadingIds() {
75      const headings = this.getHeadings();
76
77      headings.forEach((heading, index) => {
78        const slug = slugify(heading.textContent);
79        let ref = `${slug}-${index}`;
80
81        if (!heading.id) {
82          heading.setAttribute("id", ref);
83        }
84      });
85    }
86
87    maybeInitAccordion() {
88      this.accordion = this.element.querySelector(".js-toc-accordion");
89      if (!this.accordion) return;
90      this.accordionClickHandler = this.accordionClick.bind(this);
91      this.accordion.classList.remove("is-on");
92      this.accordion.addEventListener("click", this.accordionClickHandler);
93    }
94
95    accordionClick(event) {
96      event.preventDefault();
97      this.accordion.classList.toggle("is-on");
98    }
99
100    destroyAccordionClick() {
101      this.accordion.removeEventListener("click", this.accordionClickHandler);
102    }
103
104    generateJsonLd() {
105      const links = [].slice
106        .call(this.element.querySelectorAll(".toc-link"))
107        .map((link) => {
108          return {
109            "@context": "https://schema.org",
110            "@type": "SiteNavigationElement",
111            "@id": "#bde-toc",
112            name: link.textContent,
113            url: `${link.href}`,
114          };
115        });
116
117      const script = document.createElement("script");
118      script.id = "bde-toc-json-ld";
119
120      script.type = "application/ld+json";
121      script.innerHTML = JSON.stringify({
122        "@context": "https://schema.org",
123        "@graph": [links],
124      });
125
126      document.head.appendChild(script);
127    }
128
129    initTocbot() {
130      this.tocbotInstance = tocbot;
131      const collapseDepth = this.options.design.collapse == true ? 0 : 6;
132
133      this.tocbotInstance.init({
134        // Where to render the table of contents.
135        tocSelector: this.options.tocSelector,
136        // Where to grab the headings to build the table of contents.
137        contentSelector: this.options.content.table.advanced.container_selector,
138        // Which headings to grab inside of the contentSelector element.
139        headingSelector: this.headingSelectors,
140        // Headings that match the ignoreSelector will be skipped.
141        ignoreSelector:
142          this.options.content.table.advanced.ignore_selectors || ".toc-ignore",
143        // How many heading levels should not be collapsed.
144        // For example, number 6 will show everything since
145        // there are only 6 heading levels and number 0 will collapse them all.
146        // The sections that are hidden will open
147        // and close as you scroll to headings within them.
148        collapseDepth: collapseDepth,
149        // Smooth scroll offset.
150        scrollSmoothOffset: this.options.design.scroll_offset.number * -1,
151        headingsOffset: this.options.design.heading_offset.number,
152        hasInnerContainers: true,
153        headingObjectCallback: this.headingObjectCallback.bind(this),
154      });
155      this.tocbotInstance.refresh();
156    }
157
158    headingObjectCallback(obj, node) {
159      const isHeadingWithinPopup = node.closest(".bde-popup");
160      const isTocWithinPopup = this.element.closest(".bde-popup");
161
162      // If the heading is within a popup and the TOC is not, don't show the popup heading in the TOC
163      if (isHeadingWithinPopup && !isTocWithinPopup) {
164        return null;
165      }
166      return obj;
167    }
168
169    init() {
170      this.setHeadingIds();
171      this.maybeInitAccordion();
172      this.initTocbot();
173      this.generateJsonLd();
174    }
175
176    update() {
177      if (!this.tocbotInstance) return;
178      this.tocbotInstance.refresh();
179    }
180
181    destroy() {
182      if (!this.tocbotInstance) return;
183      this.tocbotInstance.destroy();
184      this.tocbotInstance = null;
185
186      document.querySelector("#bde-toc-json-ld")?.remove();
187    }
188  }
189
190  window.BreakdanceTOC = BreakdanceTOC;
191})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.