From f8fc60ed2f583a713b05c0cd431ac22c96a5bcfb Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Fri, 30 May 2025 12:33:05 +0400 Subject: [PATCH] Enabled smart mode of suggestions --- src/server/internalServer.cpp | 13 +++++++++---- src/tools/otherTools.cpp | 10 +++++++--- static/skin/viewer.js | 20 ++++++++++++++------ test/server.cpp | 4 ++-- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index d364e414..0023db44 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -775,6 +775,7 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r } const auto queryString = request.get_optional_param("term", std::string()); + const auto mode = request.get_optional_param("mode", std::string()); const auto start = request.get_optional_param("start", 0); unsigned int count = request.get_optional_param("count", 10); if (count == 0) { @@ -793,13 +794,17 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r ); const auto lock(searcher->getLock()); auto search = searcher->suggest(queryString); - auto srs = search.getResults(start, count); - for(auto& suggestion: srs) { - results.add(suggestion); + if ( start == 0 && mode == "smart") { + for(const auto& suggestion: search.getSmartSuggestions(count)) { + results.add(suggestion); + } + } else { + for(const auto& suggestion: search.getResults(start, count)) { + results.add(suggestion); + } } - /* Propose the fulltext search if possible */ if (archive->hasFulltextIndex()) { results.addFTSearchSuggestion(request.get_user_language(), queryString); diff --git a/src/tools/otherTools.cpp b/src/tools/otherTools.cpp index e125c2df..4c6467aa 100644 --- a/src/tools/otherTools.cpp +++ b/src/tools/otherTools.cpp @@ -384,9 +384,13 @@ void kiwix::Suggestions::add(const zim::SuggestionItem& suggestion) : suggestion.getTitle(); result.set("label", escapeForJSON(label, DONT_ESCAPE_QUOTE)); - result.set("value", escapeForJSON(suggestion.getTitle(), DONT_ESCAPE_QUOTE)); - result.set("kind", "path"); - result.set("path", escapeForJSON(suggestion.getPath(), DONT_ESCAPE_QUOTE)); + if ( suggestion.getPath().empty() ) { + result.set("kind", "modifiedquery"); + } else { + result.set("kind", "path"); + result.set("value", escapeForJSON(suggestion.getTitle(), DONT_ESCAPE_QUOTE)); + result.set("path", escapeForJSON(suggestion.getPath(), DONT_ESCAPE_QUOTE)); + } result.set("first", m_data.is_empty_list()); m_data.push_back(result); } diff --git a/static/skin/viewer.js b/static/skin/viewer.js index 0b7a6787..e6649b75 100644 --- a/static/skin/viewer.js +++ b/static/skin/viewer.js @@ -102,7 +102,7 @@ function suggestionsApiURL() { const uriEncodedBookName = encodeURIComponent(currentBook); const userLang = viewerState.uiLanguage; - return `${root}/suggest?userlang=${userLang}&content=${uriEncodedBookName}`; + return `${root}/suggest?userlang=${userLang}&mode=smart&content=${uriEncodedBookName}`; } function setTitle(element, text) { @@ -186,9 +186,13 @@ function closeSuggestions() { } } +function setSearchQuery(text) { + document.getElementById("kiwixsearchbox").value = text; +} + function updateSearchBoxForLocationChange() { closeSuggestions(); - document.getElementById("kiwixsearchbox").value = getSearchPattern(); + setSearchQuery(getSearchPattern()); } function updateSearchBoxForBookChange() { @@ -464,7 +468,8 @@ function setupSuggestions() { resultItem: { element: (item, data) => { const uriEncodedBookName = encodeURIComponent(currentBook); - let url; + const linkText = htmlDecode(data.value.label); + let url, modifiedQuery; if (data.value.kind == "path") { // The double quote and backslash symbols are included in the list // of special symbols to URI-encode so that the resulting URL can @@ -473,15 +478,18 @@ function setupSuggestions() { const path = htmlDecode(data.value.path); const quasiUriEncodedPath = quasiUriEncode(path, '#?"\\'); url = `/content/${uriEncodedBookName}/${quasiUriEncodedPath}`; - } else { + } else if (data.value.kind == "pattern") { const pattern = encodeURIComponent(htmlDecode(data.value.value)); url = `/search?content=${uriEncodedBookName}&pattern=${pattern}`; + } else { // data.value.kind == "modifiedquery" + modifiedQuery = htmlDecode(linkText); } // url can't contain any double quote and/or backslash symbols // since they should have been URI-encoded. Therefore putting it // inside double quotes should result in valid javascript. - const jsAction = `gotoUrl("${url}")`; - const linkText = htmlDecode(data.value.label); + const jsAction = url + ? `gotoUrl("${url}")` + : `setSearchQuery("${modifiedQuery}")`; item.innerHTML = makeJSLink(jsAction, linkText, 'class="suggest"'); }, highlight: "autoComplete_highlight", diff --git a/test/server.cpp b/test/server.cpp index d9a14481..1e230f54 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -77,7 +77,7 @@ const ResourceCollection resources200Compressible{ { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" }, { STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=80d56607" }, { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" }, - { STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=7f05bf6c" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=f8c5f4bf" }, { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" }, { STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" }, { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" }, @@ -333,7 +333,7 @@ R"EXPECTEDRESULT( - + const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";