vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
{% extends "!layout.html" %}
|
||||
{%- set _doxy = ('../' * ((pagename or '').count('/') + 2)) ~ 'doc/doxygen/html/' %}
|
||||
{%- set _search = _doxy ~ 'search/' %}
|
||||
{% block extrahead %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ _search }}search.css"/>
|
||||
<script src="{{ pathto('_static/search_map.js', 1) }}"></script>
|
||||
<script src="{{ _doxy }}cookie.js"></script>
|
||||
<script src="{{ _search }}searchdata.js"></script>
|
||||
<script src="{{ _search }}search.js"></script>
|
||||
<script>
|
||||
// SearchBox lives in search.js; guard so a load failure can't abort this
|
||||
// script (which would leave the modal trigger unwired).
|
||||
var searchBox;
|
||||
try { searchBox = new SearchBox("searchBox", "{{ _search }}", '.html'); } catch (e) {}
|
||||
|
||||
// Open/close the centered modal. Defined early so the Ctrl+K handler can use
|
||||
// them, and kept independent of the Doxygen backend so opening always works.
|
||||
function opencvOpenSearch() {
|
||||
var ov = document.getElementById("opencvSearchOverlay");
|
||||
if (!ov) return;
|
||||
ov.classList.add("opencv-search-open");
|
||||
var f = document.getElementById("MSearchField");
|
||||
if (f) { f.focus(); f.select(); }
|
||||
}
|
||||
function opencvCloseSearch() {
|
||||
var ov = document.getElementById("opencvSearchOverlay");
|
||||
if (ov) ov.classList.remove("opencv-search-open");
|
||||
if (window.searchBox && searchBox.CloseResultsWindow) searchBox.CloseResultsWindow();
|
||||
}
|
||||
|
||||
// Win Ctrl+K over the theme's deferred handler + the browser (registered
|
||||
// before the theme's, so stopImmediatePropagation pre-empts it).
|
||||
window.addEventListener("keydown", function (e) {
|
||||
if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey && /^k$/i.test(e.key)) {
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
opencvOpenSearch();
|
||||
}
|
||||
}, true);
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// The theme renders navbar_end twice (desktop header + mobile drawer), so
|
||||
// the search component appears twice → duplicate #opencvSearchTrigger /
|
||||
// #opencvSearchOverlay IDs. Keep ONE overlay; wire EVERY trigger to it
|
||||
// (the visible button may be the second copy — getElementById sees only the
|
||||
// first, which is why clicking did nothing before).
|
||||
var overlays = document.querySelectorAll("#opencvSearchOverlay");
|
||||
for (var k = overlays.length - 1; k >= 1; k--) overlays[k].parentNode.removeChild(overlays[k]);
|
||||
var overlay = overlays[0];
|
||||
if (overlay && overlay.parentNode !== document.body) document.body.appendChild(overlay);
|
||||
|
||||
// 1) Wire opening FIRST so the modal works even if Doxygen init throws.
|
||||
document.querySelectorAll("#opencvSearchTrigger").forEach(function (btn) {
|
||||
btn.addEventListener("click", function (e) { e.preventDefault(); opencvOpenSearch(); });
|
||||
});
|
||||
if (overlay) overlay.addEventListener("mousedown", function (e) { if (e.target === overlay) opencvCloseSearch(); });
|
||||
document.addEventListener("keydown", function (e) { if (/^Escape$/i.test(e.key)) opencvCloseSearch(); });
|
||||
|
||||
// 2) Doxygen search backend (guarded: a failure must not break typing).
|
||||
try {
|
||||
var boxes = document.querySelectorAll("#MSearchBox");
|
||||
for (var i = 1; i < boxes.length; i++) boxes[i].remove();
|
||||
|
||||
var sel = document.createElement("div");
|
||||
sel.id = "MSearchSelectWindow";
|
||||
sel.setAttribute("onmouseover", "return searchBox.OnSearchSelectShow()");
|
||||
sel.setAttribute("onmouseout", "return searchBox.OnSearchSelectHide()");
|
||||
sel.setAttribute("onkeydown", "return searchBox.OnSearchSelectKey(event)");
|
||||
document.body.appendChild(sel);
|
||||
|
||||
var res = document.createElement("div");
|
||||
res.id = "MSearchResultsWindow";
|
||||
res.innerHTML = '<div id="MSearchResults"><div class="SRPage"><div id="SRIndex">' +
|
||||
'<div id="SRResults"></div>' +
|
||||
'<div class="SRStatus" id="Loading">Loading...</div>' +
|
||||
'<div class="SRStatus" id="Searching">Searching...</div>' +
|
||||
'<div class="SRStatus" id="NoMatches">No Matches</div></div></div></div>';
|
||||
document.body.appendChild(res);
|
||||
|
||||
init_search();
|
||||
searchBox.OnSelectItem(0); // default to "All" on every page load
|
||||
|
||||
var sphinxRoot = "{{ '../' * (pagename or '').count('/') }}";
|
||||
// Doxygen result href -> Sphinx page, or "" if that page is not in our build.
|
||||
function resolveSphinx(href) {
|
||||
if (!href || href.indexOf("javascript:") === 0) return "";
|
||||
var map = (typeof sphinxPageMap !== "undefined") ? sphinxPageMap : {};
|
||||
var stem = href.split("/").pop().replace(/#.*$/, "").replace(/\.html$/, "");
|
||||
var key = stem.replace(/^group__/, "").replace(/^tutorial_/, "").replace(/__/g, "_");
|
||||
var path = map[stem] || map[key];
|
||||
if (!path && stem.indexOf("namespace") === 0) path = map["core_basic"];
|
||||
var rest = stem;
|
||||
while (!path && rest.indexOf("_1_1") >= 0) {
|
||||
rest = rest.substring(0, rest.lastIndexOf("_1_1"));
|
||||
path = map[rest];
|
||||
}
|
||||
return path || "";
|
||||
}
|
||||
|
||||
document.body.addEventListener("click", function (e) {
|
||||
var a = e.target.closest ? e.target.closest("a.SRSymbol, a.SRScope") : null;
|
||||
if (!a) return;
|
||||
var href = a.getAttribute("href") || "";
|
||||
var sphinxPath = resolveSphinx(href);
|
||||
if (sphinxPath) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
// Doxygen #autotoc_md anchors don't exist in Sphinx; rebuild from heading text.
|
||||
var frag = "";
|
||||
if (/#autotoc_md/.test(href)) {
|
||||
var slug = (a.textContent || "").trim().toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
||||
if (slug) frag = "#" + slug;
|
||||
}
|
||||
window.location.href = sphinxRoot + sphinxPath + frag;
|
||||
} else if (href.indexOf("doc/doxygen/html/") >= 0) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}, true);
|
||||
|
||||
// Pin the Doxygen popups under the (centered) box with position:fixed
|
||||
// (Doxygen places them absolute at document-top → off-screen here).
|
||||
var box = boxes[0];
|
||||
function pin(w, left) {
|
||||
if (!box) return;
|
||||
var r = box.getBoundingClientRect();
|
||||
w.style.setProperty("position", "fixed", "important");
|
||||
w.style.setProperty("top", (r.bottom + 4) + "px", "important");
|
||||
var x = left ? r.left : Math.max(8, r.right - (w.offsetWidth || 300));
|
||||
w.style.setProperty("left", x + "px", "important");
|
||||
}
|
||||
[[res, false], [sel, true]].forEach(function (p) {
|
||||
var w = p[0], opt = { attributes: true, attributeFilter: ["style"] };
|
||||
var obs = new MutationObserver(function () {
|
||||
if (w.style.display === "block") { obs.disconnect(); pin(w, p[1]); obs.observe(w, opt); }
|
||||
});
|
||||
obs.observe(w, opt);
|
||||
});
|
||||
} catch (err) {
|
||||
if (window.console) console.error("Doxygen search init failed:", err);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,37 @@
|
||||
{# OpenCV navbar logo: the built-in pydata `navbar-logo`, plus an
|
||||
"Open Source Computer Vision" subtitle stacked under the wordmark —
|
||||
mirrors the legacy docs.opencv.org header. The title + subtitle are
|
||||
wrapped in `.logo__textwrap` so they form a column to the right of the
|
||||
SVG mark; the version switcher (a separate navbar_start slot) still sits
|
||||
inline beside the title. Link-resolution logic is copied verbatim from
|
||||
the theme's own navbar-logo.html so the brand href behaves identically. #}
|
||||
{% if theme_logo_link %}
|
||||
{% set href = theme_logo_link %}
|
||||
{% else %}
|
||||
{% if not theme_logo.get("link") %}
|
||||
{% set href = pathto(root_doc) %}
|
||||
{% elif hasdoc(theme_logo.get("link")) %}
|
||||
{% set href = pathto(theme_logo.get("link")) %} {# internal page #}
|
||||
{% else %}
|
||||
{% set href = theme_logo.get("link") %} {# external url #}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<a class="navbar-brand logo" href="{{ href }}">
|
||||
{% set is_logo = "light" in theme_logo["image_relative"] %}
|
||||
{% set alt = theme_logo.get("alt_text", "" if theme_logo.get("text") else "%s - Home" % docstitle) %}
|
||||
{% if is_logo %}
|
||||
{% if default_mode is undefined or default_mode == "auto" %}
|
||||
{% set default_mode = "light" %}
|
||||
{% endif %}
|
||||
{% set js_mode = "light" if default_mode == "dark" else "dark" %}
|
||||
<img src="{{ theme_logo['image_relative'][default_mode] }}" class="logo__image only-{{ default_mode }}" alt="{{ alt }}"/>
|
||||
<img src="{{ theme_logo['image_relative'][js_mode] }}" class="logo__image only-{{ js_mode }} pst-js-only" alt="{{ alt }}"/>
|
||||
{% endif %}
|
||||
{% if not is_logo or theme_logo.get("text") %}
|
||||
<span class="logo__textwrap">
|
||||
<p class="title logo__title">{{ theme_logo.get("text") or docstitle }}</p>
|
||||
<p class="logo__subtitle">Open Source Computer Vision</p>
|
||||
</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
@@ -0,0 +1,36 @@
|
||||
{# Override of pydata_sphinx_theme's components/navbar-nav.html.
|
||||
|
||||
PyData's default renders both top-level toctree items AND the configured
|
||||
external_links in one bar. For OpenCV we want ONLY this header nav (the
|
||||
tutorial module tree belongs in the left sidebar, not the header), so we
|
||||
render the `external_links` slot exclusively.
|
||||
|
||||
These are NOT external links: conf.py declares them via the theme's
|
||||
`external_links` key only because that's the data slot for a custom header
|
||||
nav. Each entry is one of:
|
||||
* internal -> {"docname": "<docname>", "name": ...}
|
||||
resolved with `pathto` so the relative URL is correct at ANY page depth
|
||||
and points at the Sphinx-rendered page (landing, tutorials, module roots);
|
||||
* external -> {"url": "<abs-url>", "name": ..., "external": true}
|
||||
rendered verbatim and opened in a new tab (e.g. the Java docs, which
|
||||
have no Sphinx equivalent).
|
||||
|
||||
Internal entries carry no target="_blank" / nav-external glyph since
|
||||
navigation never leaves the site. #}
|
||||
<nav>
|
||||
<ul class="bd-navbar-elements navbar-nav">
|
||||
{%- for link in (theme_external_links or []) %}
|
||||
{%- if link.docname %}
|
||||
{%- set _href = pathto(link.docname) %}
|
||||
{%- set _external = false %}
|
||||
{%- else %}
|
||||
{%- set _href = link.url %}
|
||||
{%- set _external = link.get('external', false) %}
|
||||
{%- endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ _href }}"
|
||||
{%- if _external %} target="_blank" rel="noopener noreferrer"{% endif %}>{{ link.name }}</a>
|
||||
</li>
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
@@ -0,0 +1,81 @@
|
||||
{# Navbar version switcher: a plain `<select>` rendered right after the
|
||||
`navbar-logo` slot, mirroring the legacy docs.opencv.org header where the
|
||||
version selector sits inline with the wordmark.
|
||||
|
||||
Single source of truth: the options are built client-side from
|
||||
`window.OPENCV_DOC_VERSIONS`, defined in `_static/version.js` — the SAME
|
||||
list the legacy Doxygen pages carry. There is no build-time scrape and no
|
||||
second list: publishing a release is one edit to that file. We load it via
|
||||
`pathto('_static/version.js', 1)` (the theme's own idiom for JS assets) so
|
||||
the script resolves relative to each page, which means the dropdown
|
||||
populates fully in a local `sphinx-build` preview AND on the deployed site,
|
||||
regardless of how deep the page sits or which prefix it lands under.
|
||||
|
||||
The option whose label equals this build's `release` is marked selected;
|
||||
every other option carries that version's site-absolute path and the
|
||||
`onchange` handler navigates the same tab there. #}
|
||||
<form class="opencv-version-switcher" role="search"
|
||||
aria-label="OpenCV documentation version"
|
||||
onsubmit="return false">
|
||||
<select id="opencv-version-select"
|
||||
aria-label="Select OpenCV documentation version"
|
||||
onchange="if(this.value){window.location.href=this.value;}">
|
||||
<option value="" selected>{{ release }}</option>
|
||||
</select>
|
||||
</form>
|
||||
<script src="{{ pathto('_static/version.js', 1) }}"></script>
|
||||
<script>
|
||||
(function () {
|
||||
var current = {{ release | tojson }};
|
||||
|
||||
// Each version.js entry is a bare directory path (e.g. "/4.13.0"). Link
|
||||
// straight to that directory's index document: the S3 *website* endpoint
|
||||
// would resolve "/4.13.0/" to index.html on its own, but the plain REST
|
||||
// endpoint (bucket.s3.amazonaws.com) does NOT — there "/4.13.0" is a
|
||||
// missing object key. Appending "/index.html" works on both endpoints.
|
||||
function toHref(path) {
|
||||
if (/\.html?($|[?#])/.test(path)) return path; // already a file
|
||||
return path.replace(/\/+$/, '') + '/index.html';
|
||||
}
|
||||
|
||||
function populate() {
|
||||
var versions = window.OPENCV_DOC_VERSIONS;
|
||||
if (!Array.isArray(versions)) return; // version.js absent (list stays at current release)
|
||||
document.querySelectorAll('#opencv-version-select').forEach(function (sel) {
|
||||
// Rebuild from the canonical list so the order matches the legacy
|
||||
// docs.opencv.org dropdown exactly.
|
||||
while (sel.firstChild) sel.removeChild(sel.firstChild);
|
||||
versions.forEach(function (v) {
|
||||
var label = v[0], path = v[1];
|
||||
var opt = document.createElement('option');
|
||||
// Selecting the current version is a no-op (empty value -> the
|
||||
// inline `onchange` guard skips navigation); every other option
|
||||
// navigates to that version's index document.
|
||||
opt.value = (label === current) ? '' : toHref(path);
|
||||
opt.textContent = label;
|
||||
if (label === current) opt.selected = true;
|
||||
sel.appendChild(opt);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function resetSelection() {
|
||||
// After picking an older version and hitting Back, the browser can
|
||||
// restore the <select> from bfcache with the OLD choice. Snap it back
|
||||
// to the current release (the option whose value is empty).
|
||||
document.querySelectorAll('#opencv-version-select').forEach(function (sel) {
|
||||
for (var i = 0; i < sel.options.length; i++) {
|
||||
if (sel.options[i].value === '') { sel.selectedIndex = i; break; }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', populate);
|
||||
} else {
|
||||
populate();
|
||||
}
|
||||
// `pageshow` fires on initial load AND on bfcache restore (Back button).
|
||||
window.addEventListener('pageshow', resetSelection);
|
||||
})();
|
||||
</script>
|
||||
@@ -0,0 +1,40 @@
|
||||
{%- set _search = ('../' * ((pagename or '').count('/') + 2)) ~ 'doc/doxygen/html/search/' %}
|
||||
{# Set magnifier directly; a CSS var here resolves against search.css and 404s. #}
|
||||
<style>
|
||||
#MSearchSelect { background-image: url('{{ _search }}mag_sel.svg') !important; }
|
||||
html[data-theme="dark"] #MSearchSelect { background-image: url('{{ _search }}mag_seld.svg') !important; }
|
||||
</style>
|
||||
{# Navbar trigger: native PyData look (.search-button-field), but NOT the
|
||||
.search-button__button class — that is the theme's own show-modal hook. #}
|
||||
<button id="opencvSearchTrigger" type="button" class="btn search-button-field"
|
||||
title="{{ _('Search') }}" aria-label="{{ _('Search') }}">
|
||||
<i class="fa-solid fa-magnifying-glass"></i>
|
||||
<span class="search-button__default-text">{{ _('Search') }}</span>
|
||||
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
|
||||
</button>
|
||||
{# Centered modal overlay (layout.html moves it to <body> and toggles the open
|
||||
class). Holds the Doxygen search box; results render via Doxygen's search.js. #}
|
||||
<div id="opencvSearchOverlay" class="opencv-search-overlay" role="dialog"
|
||||
aria-modal="true" aria-label="{{ _('Search') }}">
|
||||
<div class="opencv-search-modal">
|
||||
<div id="MSearchBox" class="MSearchBoxInactive">
|
||||
<span class="left">
|
||||
<span id="MSearchSelect"
|
||||
onmouseover="return searchBox.OnSearchSelectShow()"
|
||||
onmouseout="return searchBox.OnSearchSelectHide()"> </span>
|
||||
<input type="text" id="MSearchField" value="" placeholder="Search the docs ..."
|
||||
accesskey="S"
|
||||
onfocus="searchBox.OnSearchFieldFocus(true)"
|
||||
onblur="searchBox.OnSearchFieldFocus(false)"
|
||||
onkeyup="searchBox.OnSearchFieldChange(event)"/>
|
||||
</span>
|
||||
<span class="right">
|
||||
<span id="MSearchKbd" class="search-button__kbd-shortcut">
|
||||
<kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd>
|
||||
</span>
|
||||
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()">
|
||||
<img id="MSearchCloseImg" border="0" src="{{ _search }}close.svg" alt=""/></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user