From a27d75d75778df2022d63340101dfee709330d6e Mon Sep 17 00:00:00 2001 From: James Addison Date: Sat, 2 Mar 2024 15:30:44 +0000 Subject: [PATCH 1/5] [HTML search] prevent partial term/title matches from clobbering exact-match results Co-authored-by: William Lachance --- sphinx/themes/basic/static/searchtools.js | 6 ++--- tests/js/searchtools.js | 27 ++++++++++++++++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js index e9a43fa5d3e..2183f3d8827 100644 --- a/sphinx/themes/basic/static/searchtools.js +++ b/sphinx/themes/basic/static/searchtools.js @@ -478,12 +478,12 @@ const Search = { if (word.length > 2) { const escapedWord = _escapeRegExp(word); Object.keys(terms).forEach((term) => { - if (term.match(escapedWord) && !terms[word]) + if (term.match(escapedWord) && terms[word] === undefined) arr.push({ files: terms[term], score: Scorer.partialTerm }); }); Object.keys(titleTerms).forEach((term) => { - if (term.match(escapedWord) && !titleTerms[word]) - arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + if (term.match(escapedWord) && titleTerms[word] === undefined) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); }); } diff --git a/tests/js/searchtools.js b/tests/js/searchtools.js index b70c2d32528..a3d939ee64b 100644 --- a/tests/js/searchtools.js +++ b/tests/js/searchtools.js @@ -21,7 +21,32 @@ describe('Basic html theme search', function() { "<no title>", "", null, - 2, + 5, + "index.rst" + ]]; + expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits); + }); + + it('should partially-match "sphinx" when in title index', function() { + index = { + docnames:["index"], + filenames:["index.rst"], + terms:{'useful': 0, 'utilities': 0}, + titles:["sphinx_utils module"], + titleterms:{'sphinx_utils': 0} + } + Search.setIndex(index); + searchterms = ['sphinx']; + excluded = []; + terms = index.terms; + titleterms = index.titleterms; + + hits = [[ + "index", + "sphinx_utils module", + "", + null, + 7, "index.rst" ]]; expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits); From 23da660da5a2411318f60b90f638d0283248e493 Mon Sep 17 00:00:00 2001 From: James Addison Date: Sat, 2 Mar 2024 18:08:14 +0000 Subject: [PATCH 2/5] Partial revert: remove unit-test and fix code related to sphinx-doc/sphinx#12040 --- sphinx/themes/basic/static/searchtools.js | 2 +- tests/js/searchtools.js | 25 ----------------------- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js index 2183f3d8827..839fa03ba59 100644 --- a/sphinx/themes/basic/static/searchtools.js +++ b/sphinx/themes/basic/static/searchtools.js @@ -483,7 +483,7 @@ const Search = { }); Object.keys(titleTerms).forEach((term) => { if (term.match(escapedWord) && titleTerms[word] === undefined) - arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); }); } diff --git a/tests/js/searchtools.js b/tests/js/searchtools.js index a3d939ee64b..82282e3e8af 100644 --- a/tests/js/searchtools.js +++ b/tests/js/searchtools.js @@ -27,31 +27,6 @@ describe('Basic html theme search', function() { expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits); }); - it('should partially-match "sphinx" when in title index', function() { - index = { - docnames:["index"], - filenames:["index.rst"], - terms:{'useful': 0, 'utilities': 0}, - titles:["sphinx_utils module"], - titleterms:{'sphinx_utils': 0} - } - Search.setIndex(index); - searchterms = ['sphinx']; - excluded = []; - terms = index.terms; - titleterms = index.titleterms; - - hits = [[ - "index", - "sphinx_utils module", - "", - null, - 7, - "index.rst" - ]]; - expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits); - }); - }); }); From 36bfce9f990f0a039a44631c5eddfb92ab860bff Mon Sep 17 00:00:00 2001 From: James Addison Date: Sat, 2 Mar 2024 18:12:20 +0000 Subject: [PATCH 3/5] Re-apply "remove unit-test and fix code related to sphinx-doc/sphinx#12040" This reverts commit 23da660da5a2411318f60b90f638d0283248e493. --- sphinx/themes/basic/static/searchtools.js | 2 +- tests/js/searchtools.js | 25 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js index 839fa03ba59..2183f3d8827 100644 --- a/sphinx/themes/basic/static/searchtools.js +++ b/sphinx/themes/basic/static/searchtools.js @@ -483,7 +483,7 @@ const Search = { }); Object.keys(titleTerms).forEach((term) => { if (term.match(escapedWord) && titleTerms[word] === undefined) - arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); }); } diff --git a/tests/js/searchtools.js b/tests/js/searchtools.js index 82282e3e8af..a3d939ee64b 100644 --- a/tests/js/searchtools.js +++ b/tests/js/searchtools.js @@ -27,6 +27,31 @@ describe('Basic html theme search', function() { expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits); }); + it('should partially-match "sphinx" when in title index', function() { + index = { + docnames:["index"], + filenames:["index.rst"], + terms:{'useful': 0, 'utilities': 0}, + titles:["sphinx_utils module"], + titleterms:{'sphinx_utils': 0} + } + Search.setIndex(index); + searchterms = ['sphinx']; + excluded = []; + terms = index.terms; + titleterms = index.titleterms; + + hits = [[ + "index", + "sphinx_utils module", + "", + null, + 7, + "index.rst" + ]]; + expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits); + }); + }); }); From 0f6af1df0027a90c1b1f1906d42bbaf9a7a03f01 Mon Sep 17 00:00:00 2001 From: James Addison Date: Sun, 3 Mar 2024 13:06:09 +0000 Subject: [PATCH 4/5] [HTML search] performance: skip term/title-term partial match iteration entirely when we have already found exact-matches --- sphinx/themes/basic/static/searchtools.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js index 839fa03ba59..c5826b1376a 100644 --- a/sphinx/themes/basic/static/searchtools.js +++ b/sphinx/themes/basic/static/searchtools.js @@ -477,14 +477,18 @@ const Search = { // add support for partial matches if (word.length > 2) { const escapedWord = _escapeRegExp(word); - Object.keys(terms).forEach((term) => { - if (term.match(escapedWord) && terms[word] === undefined) - arr.push({ files: terms[term], score: Scorer.partialTerm }); - }); - Object.keys(titleTerms).forEach((term) => { - if (term.match(escapedWord) && titleTerms[word] === undefined) - arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); - }); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } } // no match but word was a required one From 5d182347ead90a3d0a1bc69d60b557fcc29c893f Mon Sep 17 00:00:00 2001 From: James Addison Date: Sun, 3 Mar 2024 14:33:57 +0000 Subject: [PATCH 5/5] Add CHANGES.rst entry --- CHANGES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 64ce5772341..c13b87cc925 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -88,6 +88,9 @@ Bugs fixed Patch by Bénédikt Tran. * #12008: Fix case-sensitive lookup of ``std:label`` names in intersphinx inventory. Patch by Michael Goerz. +* #12040: HTML Search: Ensure that document titles that are partially-matched by + the user search query are included in search results. + Patch by James Addison. Testing -------