Skip to content

Commit df0c5c7

Browse files
committed
adding req. file
1 parent 4d149fb commit df0c5c7

1 file changed

Lines changed: 154 additions & 0 deletions

File tree

_static/sphinx_highlight.js

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/* Highlighting utilities for Sphinx HTML documentation. */
2+
"use strict";
3+
4+
const 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+
*/
10+
const _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(
34+
span,
35+
parent.insertBefore(
36+
rest,
37+
node.nextSibling
38+
)
39+
);
40+
node.nodeValue = val.substr(0, pos);
41+
/* There may be more occurrences of search term in this node. So call this
42+
* function recursively on the remaining fragment.
43+
*/
44+
_highlight(rest, addItems, text, className);
45+
46+
if (isInSVG) {
47+
const rect = document.createElementNS(
48+
"http://www.w3.org/2000/svg",
49+
"rect"
50+
);
51+
const bbox = parent.getBBox();
52+
rect.x.baseVal.value = bbox.x;
53+
rect.y.baseVal.value = bbox.y;
54+
rect.width.baseVal.value = bbox.width;
55+
rect.height.baseVal.value = bbox.height;
56+
rect.setAttribute("class", className);
57+
addItems.push({ parent: parent, target: rect });
58+
}
59+
}
60+
} else if (node.matches && !node.matches("button, select, textarea")) {
61+
node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
62+
}
63+
};
64+
const _highlightText = (thisNode, text, className) => {
65+
let addItems = [];
66+
_highlight(thisNode, addItems, text, className);
67+
addItems.forEach((obj) =>
68+
obj.parent.insertAdjacentElement("beforebegin", obj.target)
69+
);
70+
};
71+
72+
/**
73+
* Small JavaScript module for the documentation.
74+
*/
75+
const SphinxHighlight = {
76+
77+
/**
78+
* highlight the search words provided in localstorage in the text
79+
*/
80+
highlightSearchWords: () => {
81+
if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
82+
83+
// get and clear terms from localstorage
84+
const url = new URL(window.location);
85+
const highlight =
86+
localStorage.getItem("sphinx_highlight_terms")
87+
|| url.searchParams.get("highlight")
88+
|| "";
89+
localStorage.removeItem("sphinx_highlight_terms")
90+
url.searchParams.delete("highlight");
91+
window.history.replaceState({}, "", url);
92+
93+
// get individual terms from highlight string
94+
const terms = highlight.toLowerCase().split(/\s+/).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)) return;
138+
// bail with special keys
139+
if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
140+
if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) {
141+
SphinxHighlight.hideSearchWords();
142+
event.preventDefault();
143+
}
144+
});
145+
},
146+
};
147+
148+
_ready(() => {
149+
/* Do not call highlightSearchWords() when we are on the search page.
150+
* It will highlight words from the *previous* search query.
151+
*/
152+
if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords();
153+
SphinxHighlight.initEscapeListener();
154+
});

0 commit comments

Comments
 (0)