diff --git a/static/skin/viewer.js b/static/skin/viewer.js
index b73150950..1181f99d5 100644
--- a/static/skin/viewer.js
+++ b/static/skin/viewer.js
@@ -211,6 +211,7 @@ function handle_location_hash_change() {
}
updateSearchBoxForLocationChange();
previousScrollTop = Infinity;
+ history.replaceState(viewerState, null);
}
function handle_content_url_change() {
@@ -220,8 +221,7 @@ function handle_content_url_change() {
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);
+ history.replaceState(viewerState, null, makeURL(location.search, newHash));
updateCurrentBookIfNeeded(newHash);
};
@@ -403,6 +403,16 @@ function setupSuggestions() {
});
}
+function makeURL(search, hash) {
+ let url = location.origin + location.pathname;
+ if (search != "") {
+ url += (search[0] == '?' ? search : '?' + search);
+ }
+
+ url += (hash[0] == '#' ? hash : '#' + hash);
+ return url;
+}
+
function initUILanguageSelector() {
const languageSelector = document.getElementById("ui_language");
for (const lang of uiLanguages ) {
@@ -413,12 +423,32 @@ function initUILanguageSelector() {
}
}
+function updateUILanguageSelector(userLang) {
+ console.log(`updateUILanguageSelector(${userLang})`);
+ const languageSelector = document.getElementById("ui_language");
+ for (const opt of languageSelector.children ) {
+ if ( opt.value == userLang ) {
+ opt.selected = true;
+ }
+ }
+}
+
+function handle_history_state_change(event) {
+ console.log(`handle_history_state_change`);
+ if ( event.state ) {
+ viewerState = event.state;
+ updateUILanguageSelector(viewerState.uiLanguage);
+ setUserLanguage(viewerState.uiLanguage, updateUIText);
+ }
+}
+
function changeUILanguage() {
const s = document.getElementById("ui_language");
const lang = s.options[s.selectedIndex].value;
viewerState.uiLanguage = lang;
setUserLanguage(lang, () => {
updateUIText();
+ history.pushState(viewerState, null);
});
}
@@ -474,6 +504,7 @@ function finishViewerSetupOnceTranslationsAreLoaded()
handle_location_hash_change();
window.onhashchange = handle_location_hash_change;
+ window.onpopstate = handle_history_state_change;
viewerSetupComplete = true;
}
diff --git a/test/server.cpp b/test/server.cpp
index 836408a2b..8f2af7d22 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -73,7 +73,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT/skin/taskbar.css" },
{ STATIC_CONTENT, "/ROOT/skin/taskbar.css?cacheid=2cbac34b" },
{ DYNAMIC_CONTENT, "/ROOT/skin/viewer.js" },
- { STATIC_CONTENT, "/ROOT/skin/viewer.js?cacheid=eca8fdbe" },
+ { STATIC_CONTENT, "/ROOT/skin/viewer.js?cacheid=4f0e70d6" },
{ DYNAMIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf" },
{ STATIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf?cacheid=af705837" },
{ DYNAMIC_CONTENT, "/ROOT/skin/fonts/Roboto.ttf" },
@@ -302,7 +302,7 @@ R"EXPECTEDRESULT(
-
+
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";