From 3e479d772bbf084ccf1fa4f46af05e2762231e24 Mon Sep 17 00:00:00 2001 From: Daniel Hofmann Date: Wed, 19 Aug 2020 16:41:20 +0200 Subject: [PATCH] Closes #8123: Fix plus-handling (+) in search terms for basic html theme search Note, that the default splitter will not index +, so this isn't of much of much use, unless the splitter of the search-language is reconfigured. --- CHANGES | 3 +++ karma.conf.js | 1 + sphinx/themes/basic/static/doctools.js | 7 ++++- sphinx/themes/basic/static/searchtools.js | 12 +++++++-- tests/js/doctools.js | 4 +++ tests/js/searchtools.js | 32 +++++++++++++++++++++++ 6 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 tests/js/searchtools.js diff --git a/CHANGES b/CHANGES index 5176d8372..b1d679a01 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,9 @@ Features added Bugs fixed ---------- +* #8123: html-search: fix searching for terms containing + (Requires a + custom search language that does not split on +) + Testing -------- diff --git a/karma.conf.js b/karma.conf.js index d0c11aa21..82be18a71 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -18,6 +18,7 @@ module.exports = function(config) { 'sphinx/themes/basic/static/underscore.js', 'sphinx/themes/basic/static/jquery.js', 'sphinx/themes/basic/static/doctools.js', + 'sphinx/themes/basic/static/searchtools.js', 'tests/js/*.js' ], diff --git a/sphinx/themes/basic/static/doctools.js b/sphinx/themes/basic/static/doctools.js index daccd209d..a98364ae1 100644 --- a/sphinx/themes/basic/static/doctools.js +++ b/sphinx/themes/basic/static/doctools.js @@ -29,9 +29,14 @@ if (!window.console || !console.firebug) { /** * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL */ jQuery.urldecode = function(x) { - return decodeURIComponent(x).replace(/\+/g, ' '); + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); }; /** diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js index 970d0d975..889eaf57a 100644 --- a/sphinx/themes/basic/static/searchtools.js +++ b/sphinx/themes/basic/static/searchtools.js @@ -379,6 +379,13 @@ var Search = { return results; }, + /** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions + */ + escapeRegExp : function(string) { + return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string + }, + /** * search for full-text terms in the index */ @@ -402,13 +409,14 @@ var Search = { ]; // add support for partial matches if (word.length > 2) { + var word_regex = this.escapeRegExp(word); for (var w in terms) { - if (w.match(word) && !terms[word]) { + if (w.match(word_regex) && !terms[word]) { _o.push({files: terms[w], score: Scorer.partialTerm}) } } for (var w in titleterms) { - if (w.match(word) && !titleterms[word]) { + if (w.match(word_regex) && !titleterms[word]) { _o.push({files: titleterms[w], score: Scorer.partialTitle}) } } diff --git a/tests/js/doctools.js b/tests/js/doctools.js index 54246f635..a28f3ceb3 100644 --- a/tests/js/doctools.js +++ b/tests/js/doctools.js @@ -12,6 +12,10 @@ describe('jQuery extensions', function() { expect(jQuery.urldecode(test_encoded_string)).toEqual(test_decoded_string); }); + it('+ should result in " "', function() { + expect(jQuery.urldecode('+')).toEqual(' '); + }); + }); describe('getQueryParameters', function() { diff --git a/tests/js/searchtools.js b/tests/js/searchtools.js new file mode 100644 index 000000000..007eeb7db --- /dev/null +++ b/tests/js/searchtools.js @@ -0,0 +1,32 @@ +describe('Basic html theme search', function() { + + describe('terms search', function() { + + it('should find "C++" when in index', function() { + index = { + docnames:["index"], + filenames:["index.rst"], + terms:{'c++':0}, + titles:["<no title>"], + titleterms:{} + } + Search.setIndex(index); + searchterms = ['c++']; + excluded = []; + terms = index.terms; + titleterms = index.titleterms; + + hits = [[ + "index", + "<no title>", + "", + null, + 2, + "index.rst" + ]]; + expect(Search.performTermsSearch(searchterms, excluded, terms, titleterms)).toEqual(hits); + }); + + }); + +});