Skip to content

Commit 9a30ca7

Browse files
authored
[HTML search] use anchor for search preview (#11944)
1 parent 4ef8752 commit 9a30ca7

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Features added
3333
Bugs fixed
3434
----------
3535

36+
* #11944: Use anchor in search preview.
37+
Patch by Will Lachance.
3638
* #11668: Raise a useful error when ``theme.conf`` is missing.
3739
Patch by Vinay Sajip.
3840
* #11622: Ensure that the order of keys in ``searchindex.js`` is deterministic.

sphinx/themes/basic/static/searchtools.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const _displayItem = (item, searchTerms, highlightTerms) => {
9999
.then((data) => {
100100
if (data)
101101
listItem.appendChild(
102-
Search.makeSearchSummary(data, searchTerms)
102+
Search.makeSearchSummary(data, searchTerms, anchor)
103103
);
104104
// highlight search terms in the summary
105105
if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
@@ -160,11 +160,22 @@ const Search = {
160160
_queued_query: null,
161161
_pulse_status: -1,
162162

163-
htmlToText: (htmlString) => {
163+
htmlToText: (htmlString, anchor) => {
164164
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
165165
htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
166+
if (anchor) {
167+
const anchorContent = htmlElement.querySelector(anchor);
168+
if (anchorContent) return anchorContent.textContent;
169+
170+
console.warn(
171+
`Anchor block not found. Sphinx search tries to obtain it via '${anchor}'. Check your theme or template.`
172+
);
173+
}
174+
175+
// if anchor not specified or not found, fall back to main content
166176
const docContent = htmlElement.querySelector('[role="main"]');
167177
if (docContent) return docContent.textContent;
178+
168179
console.warn(
169180
"Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
170181
);
@@ -549,8 +560,8 @@ const Search = {
549560
* search summary for a given text. keywords is a list
550561
* of stemmed words.
551562
*/
552-
makeSearchSummary: (htmlText, keywords) => {
553-
const text = Search.htmlToText(htmlText);
563+
makeSearchSummary: (htmlText, keywords, anchor) => {
564+
const text = Search.htmlToText(htmlText, anchor);
554565
if (text === "") return null;
555566

556567
const textLower = text.toLowerCase();

tests/js/searchtools.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,38 @@ describe('Basic html theme search', function() {
3131

3232
});
3333

34+
describe("htmlToText", function() {
35+
36+
const testHTML = `<html>
37+
<div class="body" role="main">
38+
<section id="getting-started">
39+
<h1>Getting Started</h1>
40+
<p>Some text</p>
41+
</section>
42+
<section id="other-section">
43+
<h1>Other Section</h1>
44+
<p>Other text</p>
45+
</section>
46+
<section id="yet-another-section">
47+
<h1>Yet Another Section</h1>
48+
<p>More text</p>
49+
</section>
50+
</div>
51+
</html>`;
52+
53+
it("basic case", () => {
54+
expect(Search.htmlToText(testHTML).trim().split(/\s+/)).toEqual([
55+
'Getting', 'Started', 'Some', 'text',
56+
'Other', 'Section', 'Other', 'text',
57+
'Yet', 'Another', 'Section', 'More', 'text'
58+
]);
59+
});
60+
61+
it("will start reading from the anchor", () => {
62+
expect(Search.htmlToText(testHTML, '#other-section').trim().split(/\s+/)).toEqual(['Other', 'Section', 'Other', 'text']);
63+
});
64+
});
65+
3466
// This is regression test for https://github.com/sphinx-doc/sphinx/issues/3150
3567
describe('splitQuery regression tests', () => {
3668

0 commit comments

Comments
 (0)