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);