From 57a5da89620b7cc9b85fe6f5aef597389f9e0e23 Mon Sep 17 00:00:00 2001
From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
Date: Mon, 24 Jun 2024 23:07:49 +0200
Subject: [PATCH] ENH: Show type-dependent icon on search result entries
It's helpful to visually distinguish different content types.
This PR adds `itemType` to the javascript result entries
(one of "title", "index", "object", "text") and adds
them as a class to the
item in the result list.
This allows styling via CSS.
For simplicity, I've styled with unicode symbols, which
should give a decent look without the need to ship our
own symbols. Derived themes have the ability to adapt
this via their CSS settings.
---
sphinx/themes/basic/static/basic.css_t | 25 +++++++++++++++--------
sphinx/themes/basic/static/searchtools.js | 21 +++++++++++++++----
tests/js/searchtools.js | 16 ++++++++++-----
3 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t
index 297b9bfaeff..7723d9a902f 100644
--- a/sphinx/themes/basic/static/basic.css_t
+++ b/sphinx/themes/basic/static/basic.css_t
@@ -114,16 +114,25 @@ img {
/* -- search page ----------------------------------------------------------- */
-ul.search {
- margin: 10px 0 0 20px;
- padding: 0;
-}
-
ul.search li {
padding: 5px 0 5px 20px;
- background-image: url(file.png);
- background-repeat: no-repeat;
- background-position: 0 7px;
+ list-style: initial;
+}
+
+ul.search li.index {
+ list-style: "\1F4D1"; /* Unicode: Bookmark Tabs */
+}
+
+ul.search li.object {
+ list-style: "\1F4E6"; /* Unicode: Package */
+}
+
+ul.search li.title {
+ list-style: "\1F4C4"; /* Unicode: Page Facing Up */
+}
+
+ul.search li.text {
+ list-style: "\1F4C4"; /* Unicode: Page Facing Up */
}
ul.search li a {
diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js
index eaed90953f4..3d44ed224ed 100644
--- a/sphinx/themes/basic/static/searchtools.js
+++ b/sphinx/themes/basic/static/searchtools.js
@@ -20,7 +20,7 @@ if (typeof Scorer === "undefined") {
// and returns the new score.
/*
score: result => {
- const [docname, title, anchor, descr, score, filename] = result
+ const [docname, title, anchor, descr, score, filename, resultType] = result
return score
},
*/
@@ -47,6 +47,13 @@ if (typeof Scorer === "undefined") {
};
}
+const SearchResultType = {
+ index: "index",
+ object: "object",
+ text: "text",
+ title: "title",
+}
+
const _removeChildren = (element) => {
while (element && element.lastChild) element.removeChild(element.lastChild);
};
@@ -64,9 +71,10 @@ const _displayItem = (item, searchTerms, highlightTerms) => {
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
const contentRoot = document.documentElement.dataset.content_root;
- const [docName, title, anchor, descr, score, _filename] = item;
+ const [docName, title, anchor, descr, score, _filename, resultType] = item;
let listItem = document.createElement("li");
+ listItem.classList.add(resultType)
let requestUrl;
let linkUrl;
if (docBuilder === "dirhtml") {
@@ -138,7 +146,7 @@ const _displayNextItem = (
else _finishSearch(resultCount);
};
// Helper function used by query() to order search results.
-// Each input is an array of [docname, title, anchor, descr, score, filename].
+// Each input is an array of [docname, title, anchor, descr, score, filename, resultType].
// Order the results by score (in opposite order of appearance, since the
// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically.
const _orderResultsByScoreThenName = (a, b) => {
@@ -248,6 +256,7 @@ const Search = {
searchSummary.classList.add("search-summary");
searchSummary.innerText = "";
const searchList = document.createElement("ul");
+ searchList.setAttribute("role", "list")
searchList.classList.add("search");
const out = document.getElementById("search-results");
@@ -318,7 +327,7 @@ const Search = {
const indexEntries = Search._index.indexentries;
// Collect multiple result groups to be sorted separately and then ordered.
- // Each is an array of [docname, title, anchor, descr, score, filename].
+ // Each is an array of [docname, title, anchor, descr, score, filename, resultType].
const normalResults = [];
const nonMainIndexResults = [];
@@ -336,6 +345,7 @@ const Search = {
null,
score,
filenames[file],
+ SearchResultType.title,
]);
}
}
@@ -353,6 +363,7 @@ const Search = {
null,
score,
filenames[file],
+ SearchResultType.index,
];
if (isMain) {
normalResults.push(result);
@@ -474,6 +485,7 @@ const Search = {
descr,
score,
filenames[match[0]],
+ SearchResultType.object,
]);
};
Object.keys(objects).forEach((prefix) =>
@@ -584,6 +596,7 @@ const Search = {
null,
score,
filenames[file],
+ SearchResultType.text,
]);
}
return results;
diff --git a/tests/js/searchtools.js b/tests/js/searchtools.js
index 5e97572fb3e..09b8d1a31be 100644
--- a/tests/js/searchtools.js
+++ b/tests/js/searchtools.js
@@ -22,7 +22,8 @@ describe('Basic html theme search', function() {
"",
null,
5,
- "index.rst"
+ "index.rst",
+ "text"
]];
expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits);
});
@@ -39,7 +40,9 @@ describe('Basic html theme search', function() {
'',
null,
15,
- 'index.rst']];
+ 'index.rst',
+ 'text'
+ ]];
expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits);
});
@@ -56,7 +59,8 @@ describe('Basic html theme search', function() {
"",
null,
7,
- "index.rst"
+ "index.rst",
+ "text"
]];
expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits);
});
@@ -78,7 +82,8 @@ describe('Basic html theme search', function() {
'',
null,
15,
- 'index.rst'
+ 'index.rst',
+ 'text'
],
[
'index',
@@ -86,7 +91,8 @@ describe('Basic html theme search', function() {
'#main-page',
null,
100,
- 'index.rst'
+ 'index.rst',
+ 'title'
]
];
expect(Search._performSearch(...searchParameters)).toEqual(hits);