|
|
|
"use strict"; |
|
|
|
const SPHINX_HIGHLIGHT_ENABLED = true |
|
|
|
|
|
|
|
|
|
|
|
const _highlight = (node, addItems, text, className) => { |
|
if (node.nodeType === Node.TEXT_NODE) { |
|
const val = node.nodeValue; |
|
const parent = node.parentNode; |
|
const pos = val.toLowerCase().indexOf(text); |
|
if ( |
|
pos >= 0 && |
|
!parent.classList.contains(className) && |
|
!parent.classList.contains("nohighlight") |
|
) { |
|
let span; |
|
|
|
const closestNode = parent.closest("body, svg, foreignObject"); |
|
const isInSVG = closestNode && closestNode.matches("svg"); |
|
if (isInSVG) { |
|
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); |
|
} else { |
|
span = document.createElement("span"); |
|
span.classList.add(className); |
|
} |
|
|
|
span.appendChild(document.createTextNode(val.substr(pos, text.length))); |
|
const rest = document.createTextNode(val.substr(pos + text.length)); |
|
parent.insertBefore( |
|
span, |
|
parent.insertBefore( |
|
rest, |
|
node.nextSibling |
|
) |
|
); |
|
node.nodeValue = val.substr(0, pos); |
|
|
|
|
|
|
|
_highlight(rest, addItems, text, className); |
|
|
|
if (isInSVG) { |
|
const rect = document.createElementNS( |
|
"http://www.w3.org/2000/svg", |
|
"rect" |
|
); |
|
const bbox = parent.getBBox(); |
|
rect.x.baseVal.value = bbox.x; |
|
rect.y.baseVal.value = bbox.y; |
|
rect.width.baseVal.value = bbox.width; |
|
rect.height.baseVal.value = bbox.height; |
|
rect.setAttribute("class", className); |
|
addItems.push({ parent: parent, target: rect }); |
|
} |
|
} |
|
} else if (node.matches && !node.matches("button, select, textarea")) { |
|
node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); |
|
} |
|
}; |
|
const _highlightText = (thisNode, text, className) => { |
|
let addItems = []; |
|
_highlight(thisNode, addItems, text, className); |
|
addItems.forEach((obj) => |
|
obj.parent.insertAdjacentElement("beforebegin", obj.target) |
|
); |
|
}; |
|
|
|
|
|
|
|
|
|
const SphinxHighlight = { |
|
|
|
|
|
|
|
|
|
highlightSearchWords: () => { |
|
if (!SPHINX_HIGHLIGHT_ENABLED) return; |
|
|
|
|
|
const url = new URL(window.location); |
|
const highlight = |
|
localStorage.getItem("sphinx_highlight_terms") |
|
|| url.searchParams.get("highlight") |
|
|| ""; |
|
localStorage.removeItem("sphinx_highlight_terms") |
|
url.searchParams.delete("highlight"); |
|
window.history.replaceState({}, "", url); |
|
|
|
|
|
const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); |
|
if (terms.length === 0) return; |
|
|
|
|
|
const divBody = document.querySelectorAll("div.body"); |
|
const body = divBody.length ? divBody[0] : document.querySelector("body"); |
|
window.setTimeout(() => { |
|
terms.forEach((term) => _highlightText(body, term, "highlighted")); |
|
}, 10); |
|
|
|
const searchBox = document.getElementById("searchbox"); |
|
if (searchBox === null) return; |
|
searchBox.appendChild( |
|
document |
|
.createRange() |
|
.createContextualFragment( |
|
'<p class="highlight-link">' + |
|
'<a href="javascript:SphinxHighlight.hideSearchWords()">' + |
|
_("Hide Search Matches") + |
|
"</a></p>" |
|
) |
|
); |
|
}, |
|
|
|
|
|
|
|
|
|
hideSearchWords: () => { |
|
document |
|
.querySelectorAll("#searchbox .highlight-link") |
|
.forEach((el) => el.remove()); |
|
document |
|
.querySelectorAll("span.highlighted") |
|
.forEach((el) => el.classList.remove("highlighted")); |
|
localStorage.removeItem("sphinx_highlight_terms") |
|
}, |
|
|
|
initEscapeListener: () => { |
|
|
|
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; |
|
|
|
document.addEventListener("keydown", (event) => { |
|
|
|
if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; |
|
|
|
if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; |
|
if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { |
|
SphinxHighlight.hideSearchWords(); |
|
event.preventDefault(); |
|
} |
|
}); |
|
}, |
|
}; |
|
|
|
_ready(() => { |
|
|
|
|
|
|
|
if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); |
|
SphinxHighlight.initEscapeListener(); |
|
}); |
|
|