diff --git a/.gitmodules b/.gitmodules
index f0f5637..1f7b564 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,4 @@
[submodule "doxygen-awesome-css"]
path = doxygen-awesome-css
- url = https://github.com/jothepro/doxygen-awesome-css.git
- branch = main
+ url = https://github.com/ReenigneArcher/doxygen-awesome-css.git
+ branch = lizardbyte
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 11ff7ad..b357fdc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,7 +32,6 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/doxyconfig-header.html" DESTINATION "${SO
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/doxyconfig-Doxyfile" DESTINATION "${SOURCE_DOCS_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/doxyconfig-icons.js" DESTINATION "${SOURCE_DOCS_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/doxyconfig.css" DESTINATION "${SOURCE_DOCS_DIR}")
-file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/doxyconfig-readthedocs-search.js" DESTINATION "${SOURCE_DOCS_DIR}")
# append the "${SOURCE_DOCS_DIR}/Doxyfile to the Doxyfile-doxyconfig
file(READ "${SOURCE_DOCS_DIR}/Doxyfile" DOXYFILE_CONTENTS)
diff --git a/doxyconfig-Doxyfile b/doxyconfig-Doxyfile
index f66dbbe..c917baa 100644
--- a/doxyconfig-Doxyfile
+++ b/doxyconfig-Doxyfile
@@ -44,12 +44,12 @@ HTML_EXTRA_FILES += ../third-party/doxyconfig/doxygen-awesome-css/doxygen-awesom
HTML_EXTRA_FILES += ../third-party/doxyconfig/doxygen-awesome-css/doxygen-awesome-paragraph-link.js
HTML_EXTRA_FILES += ../third-party/doxyconfig/doxygen-awesome-css/doxygen-awesome-interactive-toc.js
HTML_EXTRA_FILES += ../third-party/doxyconfig/doxygen-awesome-css/doxygen-awesome-tabs.js
+HTML_EXTRA_FILES += ../third-party/doxyconfig/doxygen-awesome-css/doxygen-awesome-readthedocs-search.js
HTML_EXTRA_FILES += doxyconfig-icons.js
HTML_EXTRA_STYLESHEET = ../third-party/doxyconfig/doxygen-awesome-css/doxygen-awesome.css
+HTML_EXTRA_STYLESHEET += ../third-party/doxyconfig/doxygen-awesome-css/doxygen-awesome-readthedocs-search.css
HTML_HEADER = doxyconfig-header.html
-# readthedocs custom search
-HTML_EXTRA_FILES += doxyconfig-readthedocs-search.js
HTML_EXTRA_STYLESHEET += doxyconfig.css
# custom aliases
diff --git a/doxyconfig-header.html b/doxyconfig-header.html
index 64cfb83..174eaf6 100644
--- a/doxyconfig-header.html
+++ b/doxyconfig-header.html
@@ -42,7 +42,7 @@
-
+
diff --git a/doxyconfig-readthedocs-search.js b/doxyconfig-readthedocs-search.js
deleted file mode 100644
index 0d03899..0000000
--- a/doxyconfig-readthedocs-search.js
+++ /dev/null
@@ -1,392 +0,0 @@
-class ReadtheDocsSearch {
- static searchResultsText=[
- "Sorry, no pages matching your query.",
- "Search finished, found 1 page matching the search query.",
- "Search finished, found $num pages matching the search query.",
- ];
-
- static get serverUrl() {
- const serverUrlSuffix = '_/api/v3/';
- const domainName = globalThis.location.hostname;
- console.log(`Domain name: ${domainName}`);
-
- if (domainName === 'localhost') {
- let tmpServerUrl = serverUrl;
- while (tmpServerUrl.endsWith('/')) {
- tmpServerUrl = tmpServerUrl.slice(0, -1);
- }
- console.warn('Localhost detected, you probably need to bypass CORS');
- return `${tmpServerUrl}/${serverUrlSuffix}`;
- }
- return `https://${domainName}/${serverUrlSuffix}`;
- }
-
- static init() {
- const realSearchBox = globalThis.SearchBox;
- globalThis.SearchBox = function(name, resultsPath, extension) {
- if (realSearchBox) {
- realSearchBox.call(this, name, resultsPath, extension);
- }
-
- this.OnSearchFieldFocus = function() {};
-
- const originalClose = this.CloseResultsWindow;
- this.CloseResultsWindow = function() {
- if (originalClose) {
- originalClose.call(this);
- }
- const field = this.DOMSearchField ? this.DOMSearchField() : null;
- if (field?.id === document.activeElement?.id) {
- return;
- }
- };
- };
-
- // Re-focus the search input if it is replaced in the DOM while focused.
- // On mobile, viewport resize (triggered by the OSK opening) can cause
- // menu.js resetState() to recreate the input element, losing focus.
- const observer = new MutationObserver(function() {
- const field = document.getElementById('MSearchField');
- if (field && ReadtheDocsSearch._searchFieldHadFocus) {
- field.focus();
- }
- });
-
- if (document.body) {
- observer.observe(document.body, { childList: true, subtree: true });
- ReadtheDocsSearch._attachLiveSearch();
- } else {
- document.addEventListener('DOMContentLoaded', function() {
- observer.observe(document.body, { childList: true, subtree: true });
- ReadtheDocsSearch._attachLiveSearch();
- });
- }
-
- document.addEventListener('focusin', function(e) {
- if (e.target?.id === 'MSearchField') {
- ReadtheDocsSearch._searchFieldHadFocus = true;
- }
- });
- document.addEventListener('focusout', function(e) {
- if (e.target?.id === 'MSearchField') {
- setTimeout(function() {
- ReadtheDocsSearch._searchFieldHadFocus = false;
- }, 0);
- }
- });
-
- document.addEventListener('click', function(e) {
- const dropdown = document.getElementById('RTDLiveResults');
- const field = document.getElementById('MSearchField');
- if (dropdown && !dropdown.contains(e.target) && e.target !== field) {
- ReadtheDocsSearch._hideLiveResults();
- }
- });
-
- globalThis.searchFor = function(query, page, count) {
- const results = document.getElementById('searchresults');
-
- // Get the title
- const pageTitle = document.querySelector('div.title');
- const originalTitle = pageTitle ? pageTitle.textContent : '';
- let pageTitleStates = ["Searching", "Searching .", "Searching ..", "Searching ..."];
- let pageTitleIndex = 0;
-
- // Function to update the page title
- function updatePageTitle() {
- if (pageTitle) pageTitle.textContent = pageTitleStates[pageTitleIndex];
- pageTitleIndex = (pageTitleIndex + 1) % pageTitleStates.length;
- }
-
- // Start the interval to update the page title
- let titleInterval = setInterval(updatePageTitle, 500);
-
- // The summary will be displayed at the top of the search results
- let resultSummary = document.createElement('p');
- resultSummary.className = 'search-summary';
- results.appendChild(resultSummary);
-
- // Put all results into an unordered list
- let resultList = document.createElement('ul');
- resultList.className = 'search';
- results.appendChild(resultList);
-
- // readthedocs metadata
- let projectSlug = ReadtheDocsSearch.getMetaValue("readthedocs-project-slug") || "doxyconfig";
- let projectVersion = ReadtheDocsSearch.getMetaValue("readthedocs-version-slug") || "latest";
-
- const ctx = {
- query, resultSummary, resultList, titleInterval, pageTitle, originalTitle, firstUrl: true
- };
-
- // pull requests are not indexed, so use the default version
- const versionReady = /^\d+$/.test(projectVersion)
- ? ReadtheDocsSearch.getReadTheDocsDefaultVersion(projectSlug)
- : Promise.resolve(projectVersion);
-
- versionReady.then(function(resolvedVersion) {
- const url = `${ReadtheDocsSearch.serverUrl}search/?q=project:${projectSlug}/${resolvedVersion}+${query}&page=${page + 1}&page_size=${count}`;
- console.log(url);
- ReadtheDocsSearch.fetchResults(url, ctx);
- });
- }
- }
-
- static _attachLiveSearch() {
- let debounceTimer = null;
-
- function onInput() {
- clearTimeout(debounceTimer);
- const field = document.getElementById('MSearchField');
- if (!field) return;
- const query = field.value.trim();
- if (!query) {
- ReadtheDocsSearch._hideLiveResults();
- return;
- }
- debounceTimer = setTimeout(function() {
- ReadtheDocsSearch._runLiveSearch(query);
- }, 300);
- }
-
- function attachToField() {
- const field = document.getElementById('MSearchField');
- if (!field || field._rtdLiveSearchAttached) return;
- field._rtdLiveSearchAttached = true;
- field.setAttribute('autocomplete', 'off');
- field.addEventListener('input', onInput);
- field.addEventListener('keydown', function(e) {
- if (e.key === 'Escape') {
- ReadtheDocsSearch._hideLiveResults();
- } else if (e.key === 'ArrowDown') {
- e.preventDefault();
- ReadtheDocsSearch._moveLiveResultFocus(1);
- } else if (e.key === 'ArrowUp') {
- e.preventDefault();
- ReadtheDocsSearch._moveLiveResultFocus(-1);
- } else if (e.key === 'Enter') {
- const focused = document.querySelector('#RTDLiveResults .rtd-live-item:focus');
- if (focused) {
- e.preventDefault();
- focused.click();
- }
- }
- });
- }
-
- attachToField();
-
- // Re-attach when the DOM changes (e.g. menu.js recreates the field on mobile)
- const fieldObserver = new MutationObserver(attachToField);
- fieldObserver.observe(document.body, { childList: true, subtree: true });
- }
-
- static _runLiveSearch(query) {
- const projectSlug = ReadtheDocsSearch.getMetaValue("readthedocs-project-slug") || "doxyconfig";
- const projectVersion = ReadtheDocsSearch.getMetaValue("readthedocs-version-slug") || "latest";
-
- const versionReady = /^\d+$/.test(projectVersion)
- ? ReadtheDocsSearch.getReadTheDocsDefaultVersion(projectSlug)
- : Promise.resolve(projectVersion);
-
- versionReady.then(function(resolvedVersion) {
- const url = `${ReadtheDocsSearch.serverUrl}search/?q=project:${projectSlug}/${resolvedVersion}+${query}&page=1&page_size=5`;
- fetch(url)
- .then(function(response) {
- if (!response.ok) throw new Error(response.statusText);
- return response.json();
- })
- .then(function(data) {
- ReadtheDocsSearch._showLiveResults(query, data.results || []);
- })
- .catch(function() {
- ReadtheDocsSearch._hideLiveResults();
- });
- });
- }
-
- static _showLiveResults(query, results) {
- let dropdown = document.getElementById('RTDLiveResults');
- if (!dropdown) {
- dropdown = document.createElement('div');
- dropdown.id = 'RTDLiveResults';
- document.body.appendChild(dropdown);
- }
-
- dropdown.innerHTML = '';
-
- if (results.length === 0) {
- const empty = document.createElement('div');
- empty.className = 'rtd-live-empty';
- empty.textContent = 'No results found.';
- dropdown.appendChild(empty);
- } else {
- const list = document.createElement('ul');
- list.className = 'rtd-live-list';
- for (const item of results) {
- const li = document.createElement('li');
- const a = document.createElement('a');
- a.className = 'rtd-live-item';
- a.href = `${item.domain}${item.path}`;
- a.tabIndex = 0;
-
- const title = document.createElement('span');
- title.className = 'rtd-live-title';
- title.textContent = item.title;
- a.appendChild(title);
-
- if (item.blocks && item.blocks.length > 0) {
- const snippet = document.createElement('span');
- snippet.className = 'rtd-live-snippet';
- let snipHtml = item.blocks[0].highlights.content.join(' … ');
- snipHtml = snipHtml.replaceAll(/(.*?)<\/span>/g, '$1');
- snippet.innerHTML = snipHtml;
- a.appendChild(snippet);
- }
-
- li.appendChild(a);
- list.appendChild(li);
- }
- dropdown.appendChild(list);
- }
-
- ReadtheDocsSearch._positionLiveResults(dropdown);
- dropdown.style.display = 'block';
- }
-
- static _positionLiveResults(dropdown) {
- const field = document.getElementById('MSearchField');
- const box = document.getElementById('MSearchBox');
- const anchor = box || field;
- if (!anchor) return;
- const rect = anchor.getBoundingClientRect();
- const scrollY = window.scrollY;
- const viewportWidth = document.documentElement.clientWidth;
- dropdown.style.top = `${rect.bottom + scrollY}px`;
- dropdown.style.left = '';
- dropdown.style.right = `${viewportWidth - rect.right}px`;
- dropdown.style.minWidth = `${Math.max(rect.width, 260)}px`;
- }
-
- static _hideLiveResults() {
- const dropdown = document.getElementById('RTDLiveResults');
- if (dropdown) {
- dropdown.style.display = 'none';
- }
- }
-
- static _moveLiveResultFocus(direction) {
- const items = Array.from(document.querySelectorAll('#RTDLiveResults .rtd-live-item'));
- if (items.length === 0) return;
- const current = document.activeElement;
- const idx = items.indexOf(current);
- let next;
- if (idx === -1) {
- next = direction > 0 ? items[0] : items.at(-1);
- } else {
- next = items[idx + direction];
- }
- if (next) next.focus();
- }
-
- static fetchResults(url, ctx) {
- fetch(url)
- .then(function(response) {
- if (!response.ok) throw new Error(response.statusText);
- return response.json();
- })
- .then(function(data) {
- // Add the query to the search field
- // This seems only be working if applied in the fetch success handler...
- // maybe the field is not available before this point
- const searchField = document.getElementById('MSearchField');
- if (searchField) searchField.value = ctx.query;
-
- if (ctx.firstUrl) {
- if (data.count === 1) {
- ctx.resultSummary.innerHTML = ReadtheDocsSearch.searchResultsText[1];
- } else if (data.count > 1) {
- ctx.resultSummary.innerHTML = ReadtheDocsSearch.searchResultsText[2].replace(/\$num/, data.count);
- } else {
- ctx.resultSummary.innerHTML = ReadtheDocsSearch.searchResultsText[0];
- }
- ctx.firstUrl = false;
- }
-
- data.results.forEach(function(item) {
- ReadtheDocsSearch.appendResultItem(ctx.resultList, item);
- });
-
- if (data.next) {
- ReadtheDocsSearch.fetchResults(data.next, ctx);
- } else {
- // Clear the interval when the search is complete
- clearInterval(ctx.titleInterval);
- if (ctx.pageTitle) ctx.pageTitle.textContent = ctx.originalTitle;
- }
- });
- }
-
- static appendResultItem(resultList, item) {
- const resultItem = document.createElement('li');
- resultItem.className = 'search-result';
- const resultItemUrl = `${item.domain}${item.path}`;
- const resultItemTitleLink = document.createElement('a');
- const resultItemTitleHeading = document.createElement('h3');
- resultItemTitleHeading.appendChild(resultItemTitleLink);
- resultItemTitleLink.href = resultItemUrl;
- resultItemTitleLink.textContent = item.title;
- resultItem.append(resultItemTitleHeading);
- resultList.append(resultItem);
-
- const resultItemParagraph = document.createElement('p');
- resultItemParagraph.className = 'context';
- for (const block of item.blocks) {
- let blockContent = block.highlights.content.join(', ');
- blockContent = blockContent.replaceAll(/(.*?)<\/span>/g, '$1');
- resultItemParagraph.innerHTML += blockContent;
-
- const blockName = `#${block.title.toLowerCase().replaceAll(' ', '-')}`;
- const blockUrl = resultItemUrl + blockName;
- const blockLink = document.createElement('a');
- blockLink.href = blockUrl;
- blockLink.textContent = "More...";
- resultItemParagraph.append(document.createTextNode(' '));
- resultItemParagraph.append(blockLink);
- resultItemParagraph.append(document.createElement('br'));
- }
- resultItem.append(resultItemParagraph);
- }
-
- // Function to extract the value of a specified Read the Docs meta property
- static getMetaValue(propertyName) {
- const metaTags = document.getElementsByTagName('meta');
-
- for (let meta of metaTags) {
- if (meta.name === propertyName) {
- return meta.content;
- }
- }
-
- return null;
- }
-
- static getReadTheDocsDefaultVersion(project) {
- console.log('Pull request detected, getting default version from ReadTheDocs API');
- const url = `${ReadtheDocsSearch.serverUrl}projects/${project}/`;
- return fetch(url)
- .then(function(response) {
- if (!response.ok) throw new Error(response.statusText);
- return response.json();
- })
- .then(function(data) {
- console.log(data);
- return data.default_version || 'latest';
- })
- .catch(function(err) {
- console.error('Error:', err);
- console.log(`Cannot determine default version for ${project}, assuming "latest"`);
- return 'latest';
- });
- }
-}
diff --git a/doxyconfig.css b/doxyconfig.css
index 700ce61..ada60d2 100644
--- a/doxyconfig.css
+++ b/doxyconfig.css
@@ -1,24 +1,3 @@
-/* Highlight text in search results */
-span.highlighted {
- background-color:var(--warning-color);
- color: var(--page-foreground-color);
- padding: 2px;
- border-radius: 3px;
-}
-
-/* Remove list bullets for search results */
-ul.search {
- list-style-type: none;
- padding: 0;
-}
-
-/* Add horizontal divider for search results */
-ul.search li.search-result {
- border-bottom: 1px solid var(--separator-color);
- padding-bottom: 10px;
- margin-bottom: 10px;
-}
-
.lucide {
display: inline-block;
height: 1em;
@@ -52,70 +31,3 @@ table.code-result-table td {
vertical-align: top;
width: 50%;
}
-
-/* Live search dropdown */
-#RTDLiveResults {
- display: none;
- position: absolute;
- z-index: 10000;
- left: unset;
- background: var(--page-background-color);
- border: 1px solid var(--separator-color);
- border-radius: var(--border-radius-large);
- box-shadow: var(--box-shadow);
- max-height: 420px;
- overflow-y: auto;
-}
-
-#RTDLiveResults .rtd-live-list {
- list-style: none;
- margin: 0;
- padding: var(--spacing-small) 0;
-}
-
-#RTDLiveResults .rtd-live-list li {
- margin: 0;
-}
-
-#RTDLiveResults .rtd-live-item {
- display: block;
- padding: var(--spacing-small) var(--spacing-medium);
- color: var(--page-foreground-color);
- text-decoration: none;
- outline: none;
-}
-
-#RTDLiveResults .rtd-live-item:hover,
-#RTDLiveResults .rtd-live-item:focus {
- background: var(--menu-focus-background);
- color: var(--menu-focus-foreground);
-}
-
-#RTDLiveResults .rtd-live-title {
- display: block;
- font-weight: bold;
- font-size: var(--navigation-font-size);
-}
-
-#RTDLiveResults .rtd-live-snippet {
- display: block;
- font-size: calc(var(--navigation-font-size) * 0.9);
- color: var(--page-secondary-foreground-color);
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 400px;
-}
-
-#RTDLiveResults .rtd-live-snippet mark {
- background-color: var(--warning-color);
- color: var(--page-foreground-color);
- padding: 0 2px;
- border-radius: 2px;
-}
-
-#RTDLiveResults .rtd-live-empty {
- padding: var(--spacing-medium);
- color: var(--page-secondary-foreground-color);
- font-size: var(--navigation-font-size);
-}
diff --git a/doxygen-awesome-css b/doxygen-awesome-css
index d52eafe..24c4f96 160000
--- a/doxygen-awesome-css
+++ b/doxygen-awesome-css
@@ -1 +1 @@
-Subproject commit d52eafe3e9303399fda15661f3d7bb8fe3d7eabc
+Subproject commit 24c4f966e375ed92e9805e075177d34a9849a43e
diff --git a/readthedocs_build.sh b/readthedocs_build.sh
index 05185a9..b2092d8 100644
--- a/readthedocs_build.sh
+++ b/readthedocs_build.sh
@@ -57,7 +57,6 @@ function merge_doxyconfigs {
cp "${DOXYCONFIG_DIR}/doxyconfig-header.html" "${docs_dir}"
cp "${DOXYCONFIG_DIR}/doxyconfig-icons.js" "${docs_dir}"
cp "${DOXYCONFIG_DIR}/doxyconfig.css" "${docs_dir}"
- cp "${DOXYCONFIG_DIR}/doxyconfig-readthedocs-search.js" "${docs_dir}"
cat "${docs_dir}Doxyfile" >> "${docs_dir}doxyconfig-Doxyfile"
return 0
}