PageSourceSearch

https://opentsdb.net/docs/build/html/_static/sphinx_highlight.js

js opentsdb.net collected 2026-09-24 08:28:24 UTC 4,712 bytes, 144 lines download raw bytes

1/* Highlighting utilities for Sphinx HTML documentation. */
2"use strict";
3
4const SPHINX_HIGHLIGHT_ENABLED = true
5
6/**
7 * highlight a given string on a node by wrapping it in
8 * span elements with the given class name.
9 */
10const _highlight = (node, addItems, text, className) => {
11  if (node.nodeType === Node.TEXT_NODE) {
12    const val = node.nodeValue;
13    const parent = node.parentNode;
14    const pos = val.toLowerCase().indexOf(text);
15    if (
16      pos >= 0 &&
17      !parent.classList.contains(className) &&
18      !parent.classList.contains("nohighlight")
19    ) {
20      let span;
21
22      const closestNode = parent.closest("body, svg, foreignObject");
23      const isInSVG = closestNode && closestNode.matches("svg");
24      if (isInSVG) {
25        span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
26      } else {
27        span = document.createElement("span");
28        span.classList.add(className);
29      }
30
31      span.appendChild(document.createTextNode(val.substr(pos, text.length)));
32      parent.insertBefore(
33        span,
34        parent.insertBefore(
35          document.createTextNode(val.substr(pos + text.length)),
36          node.nextSibling
37        )
38      );
39      node.nodeValue = val.substr(0, pos);
40
41      if (isInSVG) {
42        const rect = document.createElementNS(
43          "http://www.w3.org/2000/svg",
44          "rect"
45        );
46        const bbox = parent.getBBox();
47        rect.x.baseVal.value = bbox.x;
48        rect.y.baseVal.value = bbox.y;
49        rect.width.baseVal.value = bbox.width;
50        rect.height.baseVal.value = bbox.height;
51        rect.setAttribute("class", className);
52        addItems.push({ parent: parent, target: rect });
53      }
54    }
55  } else if (node.matches && !node.matches("button, select, textarea")) {
56    node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
57  }
58};
59const _highlightText = (thisNode, text, className) => {
60  let addItems = [];
61  _highlight(thisNode, addItems, text, className);
62  addItems.forEach((obj) =>
63    obj.parent.insertAdjacentElement("beforebegin", obj.target)
64  );
65};
66
67/**
68 * Small JavaScript module for the documentation.
69 */
70const SphinxHighlight = {
71
72  /**
73   * highlight the search words provided in localstorage in the text
74   */
75  highlightSearchWords: () => {
76    if (!SPHINX_HIGHLIGHT_ENABLED) return;  // bail if no highlight
77
78    // get and clear terms from localstorage
79    const url = new URL(window.location);
80    const highlight =
81        localStorage.getItem("sphinx_highlight_terms")
82        || url.searchParams.get("highlight")
83        || "";
84    localStorage.removeItem("sphinx_highlight_terms")
85    url.searchParams.delete("highlight");
86    window.history.replaceState({}, "", url);
87
88    // get individual terms from highlight string
89    const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
90    if (terms.length === 0) return; // nothing to do
91
92    // There should never be more than one element matching "div.body"
93    const divBody = document.querySelectorAll("div.body");
94    const body = divBody.length ? divBody[0] : document.querySelector("body");
95    window.setTimeout(() => {
96      terms.forEach((term) => _highlightText(body, term, "highlighted"));
97    }, 10);
98
99    const searchBox = document.getElementById("searchbox");
100    if (searchBox === null) return;
101    searchBox.appendChild(
102      document
103        .createRange()
104        .createContextualFragment(
105          '<p class="highlight-link">' +
106            '<a href="javascript:SphinxHighlight.hideSearchWords()">' +
107            _("Hide Search Matches") +
108            "</a></p>"
109        )
110    );
111  },
112
113  /**
114   * helper function to hide the search marks again
115   */
116  hideSearchWords: () => {
117    document
118      .querySelectorAll("#searchbox .highlight-link")
119      .forEach((el) => el.remove());
120    document
121      .querySelectorAll("span.highlighted")
122      .forEach((el) => el.classList.remove("highlighted"));
123    localStorage.removeItem("sphinx_highlight_terms")
124  },
125
126  initEscapeListener: () => {
127    // only install a listener if it is really needed
128    if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;
129
130    document.addEventListener("keydown", (event) => {
131      // bail for input elements
132      if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
133      // bail with special keys
134      if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
135      if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) {
136        SphinxHighlight.hideSearchWords();
137        event.preventDefault();
138      }
139    });
140  },
141};
142
143_ready(SphinxHighlight.highlightSearchWords);
144_ready(SphinxHighlight.initEscapeListener);

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.