// Terminology // // user url: identifier of the page that has to be displayed in the viewer // and that is used as the hash component of the viewer URL. For // book resources the address url is {book}/{resource} . // // iframe url: the URL to be loaded in the viewer iframe. function userUrl2IframeUrl(url) { if ( url == '' ) { return blankPageUrl; } if ( url.startsWith('search?') ) { return `${root}/${url}`; } return `${root}/content/${url}`; } function getBookFromUserUrl(url) { if ( url == '' ) { return null; } if ( url.startsWith('search?') ) { const p = new URLSearchParams(url.slice("search?".length)); return p.get('books.name') || p.get('content'); } return url.split('/')[0]; } let currentBook = getBookFromUserUrl(location.hash.slice(1)); let currentBookTitle = null; const bookUIGroup = document.getElementById('kiwix_serve_taskbar_book_ui_group'); const homeButton = document.getElementById('kiwix_serve_taskbar_home_button'); const contentIframe = document.getElementById('content_iframe'); function gotoMainPageOfCurrentBook() { location.hash = currentBook + '/'; } function gotoUrl(url) { contentIframe.src = url; } function gotoRandomPage() { gotoUrl(`${root}/random?content=${currentBook}`); } function performSearch() { const searchbox = document.getElementById('kiwixsearchbox'); const q = encodeURIComponent(searchbox.value); gotoUrl(`${root}/search?books.name=${currentBook}&pattern=${q}`); } function suggestionsApiURL() { return `${root}/suggest?content=${encodeURIComponent(currentBook)}`; } function setCurrentBook(book, title) { currentBook = book; currentBookTitle = title; homeButton.title = `Go to the main page of '${title}'`; homeButton.setAttribute("aria-label", homeButton.title); homeButton.innerHTML = ``; bookUIGroup.style.display = 'inline'; updateSearchBoxForBookChange(); } function noCurrentBook() { currentBook = null; currentBookTitle = null; bookUIGroup.style.display = 'none'; updateSearchBoxForBookChange(); } function updateCurrentBookIfNeeded(userUrl) { const book = getBookFromUserUrl(userUrl); if ( currentBook != book ) { updateCurrentBook(book); } } function updateCurrentBook(book) { if ( book == null ) { noCurrentBook(); } else { fetch(`./raw/${book}/meta/Title`).then(async (resp) => { if ( resp.ok ) { setCurrentBook(book, await resp.text()); } else { noCurrentBook(); } }).catch((err) => { console.log("Error fetching book title: " + err); noCurrentBook(); }); } } function iframeUrl2UserUrl(url, query) { if ( url == blankPageUrl ) { return ''; } if ( url == `${root}/search` ) { return `search${query}`; } url = url.slice(root.length); 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() { contentIframe.height = window.visualViewport.height - contentIframe.offsetTop - 4; } function handle_location_hash_change() { const hash = window.location.hash.slice(1); console.log("handle_location_hash_change: " + hash); updateCurrentBookIfNeeded(hash); const iframeContentUrl = userUrl2IframeUrl(hash); if ( iframeContentUrl != contentIframe.contentWindow.location.pathname ) { contentIframe.contentWindow.location.replace(iframeContentUrl); } updateSearchBoxForLocationChange(); } function handle_content_url_change() { const iframeLocation = contentIframe.contentWindow.location; console.log('handle_content_url_change: ' + iframeLocation.href); document.title = contentIframe.contentDocument.title; const iframeContentUrl = iframeLocation.pathname; const iframeContentQuery = iframeLocation.search; const newHash = iframeUrl2UserUrl(iframeContentUrl, iframeContentQuery); const viewerURL = location.origin + location.pathname + location.search; window.location.replace(viewerURL + '#' + newHash); updateCurrentBookIfNeeded(newHash); }; window.onresize = handle_visual_viewport_change; window.onhashchange = handle_location_hash_change; updateCurrentBook(currentBook); handle_location_hash_change(); function htmlDecode(input) { var doc = new DOMParser().parseFromString(input, "text/html"); return doc.documentElement.textContent; } function setupAutoHidingOfTheToolbar() { let lastScrollTop = 0; const delta = 5; let didScroll = false; const kiwixToolBar = document.querySelector('#kiwixtoolbar'); window.addEventListener('scroll', () => { didScroll = true; }); setInterval(function() { if (didScroll) { hasScrolled(); didScroll = false; } }, 250); function hasScrolled() { const st = document.documentElement.scrollTop || document.body.scrollTop; if (Math.abs(lastScrollTop - st) <= delta) return; if (st > lastScrollTop) { kiwixToolBar.style.top = '-100%'; } else { kiwixToolBar.style.top = '0'; } lastScrollTop = st; } } document.addEventListener('DOMContentLoaded', function () { const kiwixSearchBox = document.querySelector('#kiwixsearchbox'); const kiwixSearchFormWrapper = document.querySelector('.kiwix_searchform'); const autoCompleteJS = new autoComplete( { selector: "#kiwixsearchbox", placeHolder: kiwixSearchBox.title, threshold: 1, debounce: 300, data : { src: async (query) => { try { // Fetch Data from external Source const source = await fetch(`${suggestionsApiURL()}&term=${encodeURIComponent(query)}`); const data = await source.json(); return data; } catch (error) { return error; } }, keys: ['label'], }, submit: true, searchEngine: (query, record) => { // We accept all records return true; }, resultsList: { noResults: true, // We must display 10 results (requested) + 1 potential link to do a full text search. maxResults: 11, }, resultItem: { element: (item, data) => { let searchLink; if (data.value.kind == "path") { searchLink = `${root}/${currentBook}/${htmlDecode(data.value.path)}`; } else { searchLink = `${root}/search?content=${encodeURIComponent(currentBook)}&pattern=${encodeURIComponent(htmlDecode(data.value.value))}`; } item.innerHTML = `${htmlDecode(data.value.label)}`; }, highlight: "autoComplete_highlight", selected: "autoComplete_selected" } } ); document.querySelector('#kiwixsearchform').addEventListener('submit', function(event) { try { const selectedElem = document.querySelector('.autoComplete_selected > a'); if (selectedElem) { event.preventDefault(); selectedElem.click(); } } catch (err) {} }); kiwixSearchBox.addEventListener('focus', () => { kiwixSearchFormWrapper.classList.add('full_width'); document.querySelector('label[for="kiwix_button_show_toggle"]').classList.add('searching'); document.querySelector('.kiwix_button_cont').classList.add('searching'); }); kiwixSearchBox.addEventListener('blur', () => { kiwixSearchFormWrapper.classList.remove('full_width'); document.querySelector('label[for="kiwix_button_show_toggle"]').classList.remove('searching'); document.querySelector('.kiwix_button_cont').classList.remove('searching'); }); // cybook hack if (navigator.userAgent.indexOf("bookeen/cybook") != -1) { document.querySelector('html').classList.add('cybook'); } if (document.body.clientWidth < 520) { setupAutoHidingOfTheToolbar(); } });