Searchbox correctly tracks the current book

Before this fix there were two issues with the taskbar search box:

1. The book used for the suggestions API was resolved only once during
   the page load and didn't change during navigation.

2. The current book could not be resolved from a search URL.

Now both issues are fixed.
This commit is contained in:
Veloman Yunkan 2022-08-10 12:51:27 +04:00
parent 29efb88d48
commit 2083c390b5
2 changed files with 44 additions and 16 deletions

View File

@ -25,12 +25,12 @@ function getBookFromUserUrl(url) {
if ( url.startsWith('search?') ) { if ( url.startsWith('search?') ) {
const p = new URLSearchParams(url.slice("search?".length)); const p = new URLSearchParams(url.slice("search?".length));
return p.get('books.name'); return p.get('books.name') || p.get('content');
} }
return url.split('/')[0]; return url.split('/')[0];
} }
let currentBook = null; let currentBook = getBookFromUserUrl(location.hash.slice(1));
let currentBookTitle = null; let currentBookTitle = null;
const bookUIGroup = document.getElementById('kiwix_serve_taskbar_book_ui_group'); const bookUIGroup = document.getElementById('kiwix_serve_taskbar_book_ui_group');
@ -56,22 +56,26 @@ function performSearch() {
gotoUrl(`${root}/search?books.name=${currentBook}&pattern=${q}`); gotoUrl(`${root}/search?books.name=${currentBook}&pattern=${q}`);
} }
function suggestionsApiURL()
{
return `${root}/suggest?content=${encodeURIComponent(currentBook)}`;
}
function setCurrentBook(book, title) { function setCurrentBook(book, title) {
currentBook = book; currentBook = book;
currentBookTitle = title; currentBookTitle = title;
homeButton.title = `Go to the main page of '${title}'`; homeButton.title = `Go to the main page of '${title}'`;
homeButton.setAttribute("aria-label", homeButton.title); homeButton.setAttribute("aria-label", homeButton.title);
homeButton.innerHTML = `<button>${title}</button>`; homeButton.innerHTML = `<button>${title}</button>`;
const searchbox = document.getElementById('kiwixsearchbox');
searchbox.title = `Search '${title}'`;
searchbox.setAttribute("aria-label", searchbox.title);
bookUIGroup.style.display = 'inline'; bookUIGroup.style.display = 'inline';
updateSearchBoxForBookChange();
} }
function noCurrentBook() { function noCurrentBook() {
currentBook = null; currentBook = null;
currentBookTitle = null; currentBookTitle = null;
bookUIGroup.style.display = 'none'; bookUIGroup.style.display = 'none';
updateSearchBoxForBookChange();
} }
function updateCurrentBookIfNeeded(userUrl) { function updateCurrentBookIfNeeded(userUrl) {
@ -112,6 +116,32 @@ function iframeUrl2UserUrl(url, query) {
return url.split('/').slice(2).join('/'); return url.split('/').slice(2).join('/');
} }
function getSearchPattern() {
const url = window.location.hash.slice(1);
if ( url.startsWith('search?') ) {
const p = new URLSearchParams(url.slice("search?".length));
return p.get("pattern");
}
return null;
}
function updateSearchBoxForLocationChange() {
document.getElementById("kiwixsearchbox").value = getSearchPattern();
}
function updateSearchBoxForBookChange() {
const searchbox = document.getElementById('kiwixsearchbox');
const kiwixSearchFormWrapper = document.querySelector('.kiwix_searchform');
if ( currentBookTitle ) {
searchbox.title = `Search '${currentBookTitle}'`;
searchbox.placeholder = searchbox.title;
searchbox.setAttribute("aria-label", searchbox.title);
kiwixSearchFormWrapper.style.display = 'inline';
} else {
kiwixSearchFormWrapper.style.display = 'none';
}
}
function handle_visual_viewport_change() { function handle_visual_viewport_change() {
contentIframe.height = window.visualViewport.height - contentIframe.offsetTop - 4; contentIframe.height = window.visualViewport.height - contentIframe.offsetTop - 4;
} }
@ -124,6 +154,7 @@ function handle_location_hash_change() {
if ( iframeContentUrl != contentIframe.contentWindow.location.pathname ) { if ( iframeContentUrl != contentIframe.contentWindow.location.pathname ) {
contentIframe.contentWindow.location.replace(iframeContentUrl); contentIframe.contentWindow.location.replace(iframeContentUrl);
} }
updateSearchBoxForLocationChange();
} }
function handle_content_url_change() { function handle_content_url_change() {
@ -132,14 +163,16 @@ function handle_content_url_change() {
document.title = contentIframe.contentDocument.title; document.title = contentIframe.contentDocument.title;
const iframeContentUrl = iframeLocation.pathname; const iframeContentUrl = iframeLocation.pathname;
const iframeContentQuery = iframeLocation.search; const iframeContentQuery = iframeLocation.search;
const newHash = '#' + iframeUrl2UserUrl(iframeContentUrl, iframeContentQuery); const newHash = iframeUrl2UserUrl(iframeContentUrl, iframeContentQuery);
const viewerURL = location.origin + location.pathname + location.search; const viewerURL = location.origin + location.pathname + location.search;
window.location.replace(viewerURL + newHash); window.location.replace(viewerURL + '#' + newHash);
updateCurrentBookIfNeeded(newHash);
}; };
window.onresize = handle_visual_viewport_change; window.onresize = handle_visual_viewport_change;
window.onhashchange = handle_location_hash_change; window.onhashchange = handle_location_hash_change;
updateCurrentBook(currentBook);
handle_location_hash_change(); handle_location_hash_change();
function htmlDecode(input) { function htmlDecode(input) {
@ -181,11 +214,6 @@ function setupAutoHidingOfTheToolbar() {
} }
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
const p = location.pathname;
const root = p.slice(0, p.length - '/viewer'.length);
const bookName = location.hash.slice(1).split('/')[0];
const kiwixSearchBox = document.querySelector('#kiwixsearchbox'); const kiwixSearchBox = document.querySelector('#kiwixsearchbox');
const kiwixSearchFormWrapper = document.querySelector('.kiwix_searchform'); const kiwixSearchFormWrapper = document.querySelector('.kiwix_searchform');
@ -199,7 +227,7 @@ document.addEventListener('DOMContentLoaded', function () {
src: async (query) => { src: async (query) => {
try { try {
// Fetch Data from external Source // Fetch Data from external Source
const source = await fetch(`${root}/suggest?content=${encodeURIComponent(bookName)}&term=${encodeURIComponent(query)}`); const source = await fetch(`${suggestionsApiURL()}&term=${encodeURIComponent(query)}`);
const data = await source.json(); const data = await source.json();
return data; return data;
} catch (error) { } catch (error) {
@ -222,9 +250,9 @@ document.addEventListener('DOMContentLoaded', function () {
element: (item, data) => { element: (item, data) => {
let searchLink; let searchLink;
if (data.value.kind == "path") { if (data.value.kind == "path") {
searchLink = `${root}/${bookName}/${htmlDecode(data.value.path)}`; searchLink = `${root}/${currentBook}/${htmlDecode(data.value.path)}`;
} else { } else {
searchLink = `${root}/search?content=${encodeURIComponent(bookName)}&pattern=${encodeURIComponent(htmlDecode(data.value.value))}`; searchLink = `${root}/search?content=${encodeURIComponent(currentBook)}&pattern=${encodeURIComponent(htmlDecode(data.value.value))}`;
} }
item.innerHTML = `<a class="suggest" href="javascript:gotoUrl('${searchLink}')">${htmlDecode(data.value.label)}</a>`; item.innerHTML = `<a class="suggest" href="javascript:gotoUrl('${searchLink}')">${htmlDecode(data.value.label)}</a>`;
}, },

View File

@ -202,7 +202,7 @@ R"EXPECTEDRESULT( <img src="../skin/download.png?
/* url */ "/ROOT/viewer", /* url */ "/ROOT/viewer",
R"EXPECTEDRESULT( <link type="text/css" href="./skin/taskbar.css?cacheid=26082885" rel="Stylesheet" /> R"EXPECTEDRESULT( <link type="text/css" href="./skin/taskbar.css?cacheid=26082885" rel="Stylesheet" />
<link type="text/css" href="./skin/css/autoComplete.css?cacheid=08951e06" rel="Stylesheet" /> <link type="text/css" href="./skin/css/autoComplete.css?cacheid=08951e06" rel="Stylesheet" />
<script type="text/javascript" src="./skin/viewer.js?cacheid=d7d3dac9" defer></script> <script type="text/javascript" src="./skin/viewer.js?cacheid=fd00ded7" defer></script>
<script type="text/javascript" src="./skin/autoComplete.min.js?cacheid=1191aaaf"></script> <script type="text/javascript" src="./skin/autoComplete.min.js?cacheid=1191aaaf"></script>
const blankPageUrl = `${root}/skin/blank.html`; const blankPageUrl = `${root}/skin/blank.html`;
<label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label> <label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label>