summaryrefslogtreecommitdiffstats
path: root/debian/patches/highlight_search_terms.diff
blob: 5aa91599b9e8a213af1b8be63e2e4e7eeed33bc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
From: Dmitry Shachnev <mitya57@debian.org>
Date: Sun, 23 Oct 2022 22:38:55 +0300
Subject: Highlight all search terms on search results page

SphinxHighlight.highlightSearchWords() is called on DOMContentLoaded
event, and it will not highlight page fragments loaded asynchronously.

So we should highlight all such fragments manually.

Forwarded: https://github.com/sphinx-doc/sphinx/pull/10930
---
 sphinx/themes/basic/static/searchtools.js      | 20 ++++++++++++++------
 sphinx/themes/basic/static/sphinx_highlight.js | 20 ++++++++++++++------
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js
index 8279279..0b5537f 100644
--- a/sphinx/themes/basic/static/searchtools.js
+++ b/sphinx/themes/basic/static/searchtools.js
@@ -57,7 +57,7 @@ const _removeChildren = (element) => {
 const _escapeRegExp = (string) =>
   string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
 
-const _displayItem = (item, searchTerms) => {
+const _displayItem = (item, searchTerms, highlightTerms) => {
   const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
   const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
   const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
@@ -86,9 +86,15 @@ const _displayItem = (item, searchTerms) => {
   linkEl.href = linkUrl + anchor;
   linkEl.dataset.score = score;
   linkEl.innerHTML = title;
-  if (descr)
+  const rehighlightListItem = () => window.setTimeout(() => {
+    if (SPHINX_HIGHLIGHT_ENABLED)  // set in sphinx_highlight.js
+      highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
+  }, 10);
+  if (descr) {
     listItem.appendChild(document.createElement("span")).innerHTML =
       " (" + descr + ")";
+    rehighlightListItem();
+  }
   else if (showSearchSummary)
     fetch(requestUrl)
       .then((responseData) => responseData.text())
@@ -97,6 +103,7 @@ const _displayItem = (item, searchTerms) => {
           listItem.appendChild(
             Search.makeSearchSummary(data, searchTerms)
           );
+        rehighlightListItem();
       });
   Search.output.appendChild(listItem);
 };
@@ -115,14 +122,15 @@ const _finishSearch = (resultCount) => {
 const _displayNextItem = (
   results,
   resultCount,
-  searchTerms
+  searchTerms,
+  highlightTerms,
 ) => {
   // results left, load the summary and display it
   // this is intended to be dynamic (don't sub resultsCount)
   if (results.length) {
-    _displayItem(results.pop(), searchTerms);
+    _displayItem(results.pop(), searchTerms, highlightTerms);
     setTimeout(
-      () => _displayNextItem(results, resultCount, searchTerms),
+      () => _displayNextItem(results, resultCount, searchTerms, highlightTerms),
       5
     );
   }
@@ -360,7 +368,7 @@ const Search = {
     // console.info("search results:", Search.lastresults);
 
     // print the results
-    _displayNextItem(results, results.length, searchTerms);
+    _displayNextItem(results, results.length, searchTerms, highlightTerms);
   },
 
   /**
diff --git a/sphinx/themes/basic/static/sphinx_highlight.js b/sphinx/themes/basic/static/sphinx_highlight.js
index aae669d..5fbd3ce 100644
--- a/sphinx/themes/basic/static/sphinx_highlight.js
+++ b/sphinx/themes/basic/static/sphinx_highlight.js
@@ -29,14 +29,16 @@ const _highlight = (node, addItems, text, className) => {
       }
 
       span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+      const rest = document.createTextNode(val.substr(pos + text.length));
       parent.insertBefore(
         span,
-        parent.insertBefore(
-          document.createTextNode(val.substr(pos + text.length)),
-          node.nextSibling
-        )
+        parent.insertBefore(rest, node.nextSibling)
       );
       node.nodeValue = val.substr(0, pos);
+      /* There may be more occurrences of search term in this node. So call this
+       * function recursively on the remaining fragment.
+       */
+      _highlight(rest, addItems, text, className);
 
       if (isInSVG) {
         const rect = document.createElementNS(
@@ -140,5 +142,11 @@ const SphinxHighlight = {
   },
 };
 
-_ready(SphinxHighlight.highlightSearchWords);
-_ready(SphinxHighlight.initEscapeListener);
+_ready(() => {
+  /* Do not call highlightSearchWords() when we are on the search page.
+   * It will highlight words from the _previous_ search query.
+   */
+  if (typeof Search === "undefined")
+    SphinxHighlight.highlightSearchWords();
+  SphinxHighlight.initEscapeListener();
+});