mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Support type-dependent search result highlighting via CSS (#12474)
Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com> Co-authored-by: James Addison <55152140+jayaddison@users.noreply.github.com>
This commit is contained in:
parent
9171f533cc
commit
646a5d7482
@ -28,6 +28,8 @@ Features added
|
||||
|
||||
* #11328: Mention evaluation of templated content during production of static
|
||||
output files.
|
||||
* #12474: Support type-dependent search result highlighting via CSS.
|
||||
Patch by Tim Hoffmann.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
23
doc/_themes/sphinx13/static/sphinx13.css
vendored
23
doc/_themes/sphinx13/static/sphinx13.css
vendored
@ -691,7 +691,28 @@ div.sphinx-feature > p.admonition-title::before {
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.sphinx-users-logos .headerlink {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* -- search results -------------------------------------------------------- */
|
||||
|
||||
ul.search {
|
||||
padding-left: 30px;
|
||||
}
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 10px;
|
||||
list-style-type: "\25A1"; /* Unicode: White Square */
|
||||
}
|
||||
ul.search li.context-index {
|
||||
list-style-type: "\1F4D1"; /* Unicode: Bookmark Tabs */
|
||||
}
|
||||
ul.search li.context-object {
|
||||
list-style-type: "\1F4E6"; /* Unicode: Package */
|
||||
}
|
||||
ul.search li.context-title {
|
||||
list-style-type: "\1F4C4"; /* Unicode: Page Facing Up */
|
||||
}
|
||||
ul.search li.context-text {
|
||||
list-style-type: "\1F4C4"; /* Unicode: Page Facing Up */
|
||||
}
|
||||
|
@ -221,6 +221,64 @@ If your theme package contains two or more themes, please call
|
||||
``sphinx.html_themes`` entry_points feature.
|
||||
|
||||
|
||||
Styling with CSS
|
||||
----------------
|
||||
|
||||
The :confval:`!stylesheets` setting can be used to add custom CSS files to a theme.
|
||||
|
||||
.. caution::
|
||||
|
||||
The structure of the HTML elements and their classes are currently not a
|
||||
well-defined public API. Please infer them from inspecting the built HTML
|
||||
pages. While we cannot guarantee full stability, they tend to be fairly
|
||||
stable.
|
||||
|
||||
Styling search result entries by category
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 8.0
|
||||
|
||||
The search result items have classes indicating the context in which the
|
||||
search term was found. You can use the CSS selectors:
|
||||
|
||||
- ``ul.search li.context-index``:
|
||||
For results in an index, such as the glossary
|
||||
- ``ul.search li.context-object``:
|
||||
For results in source code, like Python function definitions
|
||||
- ``ul.search li.context-title``:
|
||||
For results found in section headings
|
||||
- ``ul.search li.context-text``:
|
||||
For results found anywhere else in the documentation text
|
||||
|
||||
As a base for inheritance by other themes, the ``basic`` theme is
|
||||
intentionally minimal and does not define CSS rules using these.
|
||||
Derived themes are encouraged to use these selectors as they see fit.
|
||||
For example, the following stylesheet adds contextual icons to the
|
||||
search result list:
|
||||
|
||||
.. code-block:: css
|
||||
|
||||
ul.search {
|
||||
padding-left: 30px;
|
||||
}
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 10px;
|
||||
list-style-type: "\25A1"; /* Unicode: White Square */
|
||||
}
|
||||
ul.search li.context-index {
|
||||
list-style-type: "\1F4D1"; /* Unicode: Bookmark Tabs */
|
||||
}
|
||||
ul.search li.context-object {
|
||||
list-style-type: "\1F4E6"; /* Unicode: Package */
|
||||
}
|
||||
ul.search li.context-title {
|
||||
list-style-type: "\1F4C4"; /* Unicode: Page Facing Up */
|
||||
}
|
||||
ul.search li.context-text {
|
||||
list-style-type: "\1F4C4"; /* Unicode: Page Facing Up */
|
||||
}
|
||||
|
||||
|
||||
Templating
|
||||
----------
|
||||
|
||||
|
@ -115,15 +115,11 @@ img {
|
||||
/* -- search page ----------------------------------------------------------- */
|
||||
|
||||
ul.search {
|
||||
margin: 10px 0 0 20px;
|
||||
padding: 0;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 20px;
|
||||
background-image: url(file.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 7px;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
ul.search li a {
|
||||
|
@ -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, context] = result
|
||||
return score
|
||||
},
|
||||
*/
|
||||
@ -47,6 +47,14 @@ if (typeof Scorer === "undefined") {
|
||||
};
|
||||
}
|
||||
|
||||
// Global search result kind enum, used by themes to style search results.
|
||||
class SearchResultContext {
|
||||
static get index() { return "index"; }
|
||||
static get object() { return "object"; }
|
||||
static get text() { return "text"; }
|
||||
static get title() { return "title"; }
|
||||
}
|
||||
|
||||
const _removeChildren = (element) => {
|
||||
while (element && element.lastChild) element.removeChild(element.lastChild);
|
||||
};
|
||||
@ -64,9 +72,13 @@ 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, context] = item;
|
||||
|
||||
let listItem = document.createElement("li");
|
||||
// Add a class representing the item's type:
|
||||
// can be used by a theme's CSS selector for styling
|
||||
// See SearchResultContext for the class names.
|
||||
listItem.classList.add(`context-${context}`);
|
||||
let requestUrl;
|
||||
let linkUrl;
|
||||
if (docBuilder === "dirhtml") {
|
||||
@ -140,7 +152,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, context].
|
||||
// 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) => {
|
||||
@ -250,6 +262,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");
|
||||
@ -320,7 +333,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, context].
|
||||
const normalResults = [];
|
||||
const nonMainIndexResults = [];
|
||||
|
||||
@ -339,6 +352,7 @@ const Search = {
|
||||
null,
|
||||
score + boost,
|
||||
filenames[file],
|
||||
SearchResultContext.title,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -356,6 +370,7 @@ const Search = {
|
||||
null,
|
||||
score,
|
||||
filenames[file],
|
||||
SearchResultContext.index,
|
||||
];
|
||||
if (isMain) {
|
||||
normalResults.push(result);
|
||||
@ -477,6 +492,7 @@ const Search = {
|
||||
descr,
|
||||
score,
|
||||
filenames[match[0]],
|
||||
SearchResultContext.object,
|
||||
]);
|
||||
};
|
||||
Object.keys(objects).forEach((prefix) =>
|
||||
@ -587,6 +603,7 @@ const Search = {
|
||||
null,
|
||||
score,
|
||||
filenames[file],
|
||||
SearchResultContext.text,
|
||||
]);
|
||||
}
|
||||
return results;
|
||||
|
@ -38,7 +38,8 @@ describe('Basic html theme search', function() {
|
||||
"",
|
||||
null,
|
||||
5,
|
||||
"index.rst"
|
||||
"index.rst",
|
||||
"text"
|
||||
]];
|
||||
expect(Search.performTermsSearch(searchterms, excluded)).toEqual(hits);
|
||||
});
|
||||
@ -53,7 +54,9 @@ describe('Basic html theme search', function() {
|
||||
'',
|
||||
null,
|
||||
15,
|
||||
'index.rst']];
|
||||
'index.rst',
|
||||
'text'
|
||||
]];
|
||||
expect(Search.performTermsSearch(searchterms, excluded)).toEqual(hits);
|
||||
});
|
||||
|
||||
@ -68,7 +71,8 @@ describe('Basic html theme search', function() {
|
||||
"",
|
||||
null,
|
||||
7,
|
||||
"index.rst"
|
||||
"index.rst",
|
||||
"text"
|
||||
]];
|
||||
expect(Search.performTermsSearch(searchterms, excluded)).toEqual(hits);
|
||||
});
|
||||
@ -86,7 +90,8 @@ describe('Basic html theme search', function() {
|
||||
"",
|
||||
null,
|
||||
2,
|
||||
"index.rst"
|
||||
"index.rst",
|
||||
"text"
|
||||
]];
|
||||
expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits);
|
||||
});
|
||||
@ -107,7 +112,8 @@ describe('Basic html theme search', function() {
|
||||
'',
|
||||
null,
|
||||
16,
|
||||
'index.rst'
|
||||
'index.rst',
|
||||
'title'
|
||||
]
|
||||
];
|
||||
expect(Search._performSearch(...searchParameters)).toEqual(hits);
|
||||
|
Loading…
Reference in New Issue
Block a user