PageSourceSearch

https://matplotlib.org/stable/_static/sphinx_highlight.js?v=6ffebe34

js matplotlib.org collected 2026-09-24 07:16:42 UTC 5,325 bytes, 159 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      const rest = document.createTextNode(val.substr(pos + text.length));
33      parent.insertBefore(span, parent.insertBefore(rest, node.nextSibling));
34      node.nodeValue = val.substr(0, pos);
35      /* There may be more occurrences of search term in this node. So call this
36       * function recursively on the remaining fragment.
37       */
38      _highlight(rest, addItems, text, className);
39
40      if (isInSVG) {
41        const rect = document.createElementNS(
42          "http://www.w3.org/2000/svg",
43          "rect",
44        );
45        const bbox = parent.getBBox();
46        rect.x.baseVal.value = bbox.x;
47        rect.y.baseVal.value = bbox.y;
48        rect.width.baseVal.value = bbox.width;
49        rect.height.baseVal.value = bbox.height;
50        rect.setAttribute("class", className);
51        addItems.push({ parent: parent, target: rect });
52      }
53    }
54  } else if (node.matches && !node.matches("button, select, textarea")) {
55    node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
56  }
57};
58const _highlightText = (thisNode, text, className) => {
59  let addItems = [];
60  _highlight(thisNode, addItems, text, className);
61  addItems.forEach((obj) =>
62    obj.parent.insertAdjacentElement("beforebegin", obj.target),
63  );
64};
65
66/**
67 * Small JavaScript module for the documentation.
68 */
69const SphinxHighlight = {
70  /**
71   * highlight the search words provided in localstorage in the text
72   */
73  highlightSearchWords: () => {
74    if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
75
76    // get and clear terms from localstorage
77    const url = new URL(window.location);
78    const highlight =
79      localStorage.getItem("sphinx_highlight_terms")
80      || url.searchParams.get("highlight")
81      || "";
82    localStorage.removeItem("sphinx_highlight_terms");
83    // Update history only if '?highlight' is present; otherwise it
84    // clears text fragments (not set in window.location by the browser)
85    if (url.searchParams.has("highlight")) {
86      url.searchParams.delete("highlight");
87      window.history.replaceState({}, "", url);
88    }
89
90    // get individual terms from highlight string
91    const terms = highlight
92      .toLowerCase()
93      .split(/\s+/)
94      .filter((x) => x);
95    if (terms.length === 0) return; // nothing to do
96
97    // There should never be more than one element matching "div.body"
98    const divBody = document.querySelectorAll("div.body");
99    const body = divBody.length ? divBody[0] : document.querySelector("body");
100    window.setTimeout(() => {
101      terms.forEach((term) => _highlightText(body, term, "highlighted"));
102    }, 10);
103
104    const searchBox = document.getElementById("searchbox");
105    if (searchBox === null) return;
106    searchBox.appendChild(
107      document
108        .createRange()
109        .createContextualFragment(
110          '<p class="highlight-link">'
111            + '<a href="javascript:SphinxHighlight.hideSearchWords()">'
112            + _("Hide Search Matches")
113            + "</a></p>",
114        ),
115    );
116  },
117
118  /**
119   * helper function to hide the search marks again
120   */
121  hideSearchWords: () => {
122    document
123      .querySelectorAll("#searchbox .highlight-link")
124      .forEach((el) => el.remove());
125    document
126      .querySelectorAll("span.highlighted")
127      .forEach((el) => el.classList.remove("highlighted"));
128    localStorage.removeItem("sphinx_highlight_terms");
129  },
130
131  initEscapeListener: () => {
132    // only install a listener if it is really needed
133    if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;
134
135    document.addEventListener("keydown", (event) => {
136      // bail for input elements
137      if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName))
138        return;
139      // bail with special keys
140      if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
141        return;
142      if (
143        DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
144        && event.key === "Escape"
145      ) {
146        SphinxHighlight.hideSearchWords();
147        event.preventDefault();
148      }
149    });
150  },
151};
152
153_ready(() => {
154  /* Do not call highlightSearchWords() when we are on the search page.
155   * It will highlight words from the *previous* search query.
156   */
157  if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords();
158  SphinxHighlight.initEscapeListener();
159});

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.