diff --git a/static/skin/viewer.js b/static/skin/viewer.js index c28cbb18f..085777aab 100644 --- a/static/skin/viewer.js +++ b/static/skin/viewer.js @@ -1,3 +1,146 @@ +// 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'); + } + return url.split('/')[0]; +} + +let currentBook = null; +let currentBookTitle = null; + +const bookUIGroup = document.getElementById('kiwix_serve_taskbar_book_ui_group'); +const homeButton = document.getElementById('kiwix_serve_taskbar_home_button'); + +function gotoMainPageOfCurrentBook() { + location.hash = currentBook + '/'; +} + +function gotoUrl(url) { + cf.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 setCurrentBook(book, title) { + currentBook = book; + currentBookTitle = title; + homeButton.title = `Go to the main page of '${title}'`; + homeButton.setAttribute("aria-label", homeButton.title); + homeButton.innerHTML = ``; + const searchbox = document.getElementById('kiwixsearchbox'); + searchbox.title = `Search '${title}'`; + searchbox.setAttribute("aria-label", searchbox.title); + bookUIGroup.style.display = 'inline'; +} + +function noCurrentBook() { + currentBook = null; + currentBookTitle = null; + bookUIGroup.style.display = 'none'; +} + +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('/'); +} + +const cf = document.getElementById('content_iframe'); + +function handle_visual_viewport_change() { + cf.height = window.visualViewport.height - cf.offsetTop - 4; +} + +function handle_location_hash_change() { + const hash = window.location.hash.slice(1); + updateCurrentBookIfNeeded(hash); + const iframeContentUrl = userUrl2IframeUrl(hash); + console.log("handle_location_hash_change: " + hash); + if ( iframeContentUrl != cf.contentWindow.location.pathname ) { + cf.contentWindow.location.replace(iframeContentUrl); + } +} + +function handle_content_url_change() { + document.title = cf.contentDocument.title; + const iframeContentUrl = cf.contentWindow.location.pathname; + const iframeContentQuery = cf.contentWindow.location.search; + console.log('handle_content_url_change: ' + cf.contentWindow.location.href); + const newHash = '#' + iframeUrl2UserUrl(iframeContentUrl, iframeContentQuery); + const viewerURL = location.origin + location.pathname + location.search; + window.location.replace(viewerURL + newHash); +}; + +window.onresize = handle_visual_viewport_change; +window.onhashchange = handle_location_hash_change; + +handle_location_hash_change(); + function htmlDecode(input) { var doc = new DOMParser().parseFromString(input, "text/html"); return doc.documentElement.textContent; diff --git a/static/viewer.html b/static/viewer.html index 42a785caf..7948cd17c 100644 --- a/static/viewer.html +++ b/static/viewer.html @@ -62,149 +62,6 @@ diff --git a/test/server.cpp b/test/server.cpp index 2bce3bb68..feca68b2e 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -202,7 +202,7 @@ R"EXPECTEDRESULT( - + const blankPageUrl = `${root}/skin/blank.html`;