From 947744caea679c39ddb17374a1a9673e01b45c19 Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Wed, 22 Jun 2022 13:46:30 +0530
Subject: [PATCH 1/8] Introduce updateVisibleParams()
Adds a function to wrap logic to update select boxes on history change
---
static/skin/index.js | 40 +++++++++++++++++++---------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/static/skin/index.js b/static/skin/index.js
index 15cc0b166..08a8dccee 100644
--- a/static/skin/index.js
+++ b/static/skin/index.js
@@ -358,19 +358,13 @@
window.history.pushState({}, null, `${window.location.href.split('?')[0]}?${params.toString()}`);
setCookie(filterCookieName, params.toString());
}
- document.querySelectorAll('.filter').forEach(filter => {
- if (filter.value) {
- filter.style = 'background-color: #858585; color: #fff';
- } else {
- filter.style = 'background-color: #ffffff; color: black';
- }
- });
+ updateFilterColors();
await loadAndDisplayBooks(true);
}
window.addEventListener('popstate', async () => {
await resetAndFilter();
- document.querySelectorAll('.filter').forEach(filter => {filter.value = params.get(filter.name) || ''});
+ updateVisibleParams();
});
async function loadSubset() {
@@ -384,6 +378,21 @@
}
}
+ function updateFilterColors() {
+ document.querySelectorAll('.filter').forEach(filter => {
+ if (filter.value) {
+ filter.style = 'background-color: #858585; color: #fff';
+ } else {
+ filter.style = 'background-color: #ffffff; color: black';
+ }
+ });
+ }
+
+ function updateVisibleParams() {
+ document.querySelectorAll('.filter').forEach(filter => {filter.value = params.get(filter.name) || ''});
+ updateFilterColors();
+ }
+
window.addEventListener('resize', (event) => {
if (timer) {clearTimeout(timer)}
timer = setTimeout(() => {
@@ -422,12 +431,7 @@
if (filters) {
window.history.pushState({}, null, `${window.location.href.split('?')[0]}?${params.toString()}`);
}
- params.forEach((value, key) => {
- const selectBox = document.getElementsByName(key)[0];
- if (selectBox) {
- selectBox.value = value
- }
- });
+ updateVisibleParams();
document.getElementById('kiwixSearchForm').onsubmit = (event) => {event.preventDefault()};
if (!window.location.search) {
const browserLang = navigator.language.split('-')[0];
@@ -438,13 +442,7 @@
langFilter.dispatchEvent(new Event('change'));
}
}
- document.querySelectorAll('.filter').forEach(filter => {
- if (filter.value) {
- filter.style = 'background-color: #858585; color: #fff';
- } else {
- filter.style = 'background-color: #ffffff; color: black';
- }
- });
setCookie(filterCookieName, params.toString());
}
})();
+
From 37b39430d1cf6d00ca789223ca69e09a8c9a5510 Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Fri, 24 Jun 2022 15:53:26 +0530
Subject: [PATCH 2/8] Use shortened URL in pushState
Earlier we were using the full URL, now only query string is passed in pushState, much cleaner!
---
static/skin/index.js | 6 +++---
test/server.cpp | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/static/skin/index.js b/static/skin/index.js
index 08a8dccee..8f5ed557b 100644
--- a/static/skin/index.js
+++ b/static/skin/index.js
@@ -282,7 +282,7 @@
kiwixHomeBody.setAttribute('style', 'display: flex; justify-content: center; align-items: center');
divTag.getElementsByTagName('a')[0].onclick = (event) => {
event.preventDefault();
- window.history.pushState({}, null, `${window.location.href.split('?')[0]}?lang=`);
+ window.history.pushState({}, null, `?lang=`);
setCookie(filterCookieName, 'lang=');
resetAndFilter();
document.querySelectorAll('.filter').forEach(filter => {
@@ -355,7 +355,7 @@
params = new URLSearchParams(window.location.search);
if (filterType) {
params.set(filterType, filterValue);
- window.history.pushState({}, null, `${window.location.href.split('?')[0]}?${params.toString()}`);
+ window.history.pushState({}, null, `?${params.toString()}`);
setCookie(filterCookieName, params.toString());
}
updateFilterColors();
@@ -429,7 +429,7 @@
filter.addEventListener('change', () => {resetAndFilter(filter.name, filter.value)});
});
if (filters) {
- window.history.pushState({}, null, `${window.location.href.split('?')[0]}?${params.toString()}`);
+ window.history.pushState({}, null, `?${params.toString()}`);
}
updateVisibleParams();
document.getElementById('kiwixSearchForm').onsubmit = (event) => {event.preventDefault()};
diff --git a/test/server.cpp b/test/server.cpp
index 9d7c38293..12909fe64 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -184,7 +184,7 @@ R"EXPECTEDRESULT( src="/ROOT/skin/jquery-ui/external/jquery/jquery.js?cache
src: url("/ROOT/skin/fonts/Roboto.ttf?cacheid=84d10248") format("truetype");
-
+
)EXPECTEDRESULT"
},
{
From 0c549af30768058c35ad54d37ea3967ccef39284 Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Sat, 25 Jun 2022 18:14:42 +0530
Subject: [PATCH 3/8] Add check to not add same link in session history
Previously, if the following steps were executed:
1. Click a book tile/visit an unrelated link from the address bar
2. Press back button
Then forward history was discarded (forward button gets disabled).
This happened because of the window.history.pushState on every window.onload event. This led to the same link being added in history and thus discarding the previous "forward-history"
This change adds a condition to only push the current state if the queries are not same.
---
static/skin/index.js | 6 +++++-
test/server.cpp | 2 +-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/static/skin/index.js b/static/skin/index.js
index 8f5ed557b..2b5a4149d 100644
--- a/static/skin/index.js
+++ b/static/skin/index.js
@@ -429,7 +429,11 @@
filter.addEventListener('change', () => {resetAndFilter(filter.name, filter.value)});
});
if (filters) {
- window.history.pushState({}, null, `?${params.toString()}`);
+ const currentLink = window.location.search;
+ const newLink = `?${params.toString()}`;
+ if (currentLink != newLink) {
+ window.history.pushState({}, null, newLink);
+ }
}
updateVisibleParams();
document.getElementById('kiwixSearchForm').onsubmit = (event) => {event.preventDefault()};
diff --git a/test/server.cpp b/test/server.cpp
index 12909fe64..992ffb9c5 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -184,7 +184,7 @@ R"EXPECTEDRESULT( src="/ROOT/skin/jquery-ui/external/jquery/jquery.js?cache
src: url("/ROOT/skin/fonts/Roboto.ttf?cacheid=84d10248") format("truetype");
-
+
)EXPECTEDRESULT"
},
{
From 596b223a9dd6160b18d1212a53b06b4e7fcc450a Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Sat, 25 Jun 2022 18:26:22 +0530
Subject: [PATCH 4/8] Drop onclick handler for reset-filter link
This removes the onclick handler around the reset-filter link which redirected to '/?lang='
Everything under the handler was already done on window.onload
---
static/skin/index.js | 16 +---------------
test/server.cpp | 2 +-
2 files changed, 2 insertions(+), 16 deletions(-)
diff --git a/static/skin/index.js b/static/skin/index.js
index 2b5a4149d..c33c47d93 100644
--- a/static/skin/index.js
+++ b/static/skin/index.js
@@ -277,23 +277,9 @@
setTimeout(() => {
const divTag = document.createElement('div');
divTag.setAttribute('class', 'noResults');
- divTag.innerHTML = `No result. Would you like to reset filter?`;
+ divTag.innerHTML = `No result. Would you like to reset filter?`;
kiwixHomeBody.append(divTag);
kiwixHomeBody.setAttribute('style', 'display: flex; justify-content: center; align-items: center');
- divTag.getElementsByTagName('a')[0].onclick = (event) => {
- event.preventDefault();
- window.history.pushState({}, null, `?lang=`);
- setCookie(filterCookieName, 'lang=');
- resetAndFilter();
- document.querySelectorAll('.filter').forEach(filter => {
- filter.value = params.get(filter.name) || '';
- if (filter.value) {
- filter.style = 'background-color: #858585; color: #fff';
- } else {
- filter.style = 'background-color: #ffffff; color: black';
- }
- })
- };
loader.setAttribute('style', 'position: absolute; top: 50%');
}, 300);
}
diff --git a/test/server.cpp b/test/server.cpp
index 992ffb9c5..a0c22362b 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -184,7 +184,7 @@ R"EXPECTEDRESULT( src="/ROOT/skin/jquery-ui/external/jquery/jquery.js?cache
src: url("/ROOT/skin/fonts/Roboto.ttf?cacheid=84d10248") format("truetype");
-
+
)EXPECTEDRESULT"
},
{
From f034018b5cb28f9da0dcc6d88eb0fc38f2743499 Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Fri, 24 Jun 2022 21:46:11 +0530
Subject: [PATCH 5/8] Extract setNoResultsContent() from
checkAndInjectEmptyMessage()
Extracted the code from the un-named function in setTimeout for easier understanding.
---
static/skin/index.js | 19 +++++++++++--------
test/server.cpp | 2 +-
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/static/skin/index.js b/static/skin/index.js
index c33c47d93..a6bcdd744 100644
--- a/static/skin/index.js
+++ b/static/skin/index.js
@@ -267,6 +267,16 @@
});
}
+ function setNoResultsContent() {
+ const kiwixHomeBody = document.querySelector('.kiwixHomeBody');
+ const divTag = document.createElement('div');
+ divTag.setAttribute('class', 'noResults');
+ divTag.innerHTML = `No result. Would you like to reset filter?`;
+ kiwixHomeBody.append(divTag);
+ kiwixHomeBody.setAttribute('style', 'display: flex; justify-content: center; align-items: center');
+ loader.setAttribute('style', 'position: absolute; top: 50%');
+ }
+
function checkAndInjectEmptyMessage() {
const kiwixHomeBody = document.querySelector('.kiwixHomeBody');
if (!bookOrderMap.size) {
@@ -274,14 +284,7 @@
noResultInjected = true;
iso.remove(document.getElementsByClassName('book__list')[0].getElementsByTagName('div'));
iso.layout();
- setTimeout(() => {
- const divTag = document.createElement('div');
- divTag.setAttribute('class', 'noResults');
- divTag.innerHTML = `No result. Would you like to reset filter?`;
- kiwixHomeBody.append(divTag);
- kiwixHomeBody.setAttribute('style', 'display: flex; justify-content: center; align-items: center');
- loader.setAttribute('style', 'position: absolute; top: 50%');
- }, 300);
+ setTimeout(setNoResultsContent, 300);
}
return true;
} else if (noResultInjected) {
diff --git a/test/server.cpp b/test/server.cpp
index a0c22362b..145f59226 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -184,7 +184,7 @@ R"EXPECTEDRESULT( src="/ROOT/skin/jquery-ui/external/jquery/jquery.js?cache
src: url("/ROOT/skin/fonts/Roboto.ttf?cacheid=84d10248") format("truetype");
-
+
)EXPECTEDRESULT"
},
{
From 19a9c84e139acb54cfd63f51494bd3b8564384ed Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Wed, 22 Jun 2022 13:48:20 +0530
Subject: [PATCH 6/8] Change class name "searchButton" to "kiwixButton"
This is done to retain the button design in more button designs (ex: tags)
---
README.md | 2 +-
static/skin/index.css | 6 +++---
static/templates/index.html | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index 8c3991c5c..12c2a4d27 100644
--- a/README.md
+++ b/README.md
@@ -198,7 +198,7 @@ To use JS provided by kiwix-serve you can use the following template to start wi
```
```
diff --git a/static/skin/index.css b/static/skin/index.css
index 073c42f60..1f406452f 100644
--- a/static/skin/index.css
+++ b/static/skin/index.css
@@ -113,7 +113,7 @@ body {
background-size: 15px;
}
-.searchButton {
+.kiwixButton {
margin: 0 17px;
height: 35px;
width: 100px;
@@ -123,7 +123,7 @@ body {
border: solid 1px #b5b2b2;
}
-.searchButton:hover {
+.kiwixButton:hover {
background-color: #858585;
}
@@ -434,7 +434,7 @@ body {
margin-top: 11px;
}
- .searchButton {
+ .kiwixButton {
margin: 19px 0;
width: 229px;
}
diff --git a/static/templates/index.html b/static/templates/index.html
index 39d5afc9e..1f250c421 100644
--- a/static/templates/index.html
+++ b/static/templates/index.html
@@ -58,7 +58,7 @@
From 93f2686a94b33922a959f632259c7033efaf83f7 Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Sun, 13 Mar 2022 22:47:46 +0530
Subject: [PATCH 7/8] Refactoring kiwixButton
Move hover behaviour as a different class - kiwixButtonHover
Add cursor:pointer to kiwixButton
---
static/skin/index.css | 3 ++-
static/templates/index.html | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/static/skin/index.css b/static/skin/index.css
index 1f406452f..800aca210 100644
--- a/static/skin/index.css
+++ b/static/skin/index.css
@@ -121,9 +121,10 @@ body {
color: white;
background-color: #909090;
border: solid 1px #b5b2b2;
+ cursor: pointer;
}
-.kiwixButton:hover {
+.kiwixButtonHover:hover {
background-color: #858585;
}
diff --git a/static/templates/index.html b/static/templates/index.html
index 1f250c421..a62185fa8 100644
--- a/static/templates/index.html
+++ b/static/templates/index.html
@@ -58,7 +58,7 @@
From 43ab6dfb6acc94b1cc3e85569e1ff24d66ecad79 Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Fri, 11 Feb 2022 21:59:26 +0530
Subject: [PATCH 8/8] Add ability to filter by tags in kiwix serve
This change introduces filtering by tags.
To filter, the user can click on the tag name and it will filter it.
A label is added (clickable) to show the tag filter, it can be clicked to remove the filter
---
static/skin/index.css | 38 ++++++++++++++++++++++--
static/skin/index.js | 59 +++++++++++++++++++++++++++++++++----
static/templates/index.html | 1 +
test/server.cpp | 4 +--
4 files changed, 92 insertions(+), 10 deletions(-)
diff --git a/static/skin/index.css b/static/skin/index.css
index 800aca210..8443feacb 100644
--- a/static/skin/index.css
+++ b/static/skin/index.css
@@ -134,6 +134,27 @@ body {
position: relative;
}
+.tagFilterLabel {
+ width: max-content;
+ padding: 10px;
+ font-family: roboto;
+ font-size: 12px;
+ margin: 0 0 0 17px;
+ text-align: center;
+ background-color: transparent;
+ color: #909090;
+ display: none;
+}
+
+.tag__link {
+ cursor: pointer;
+ color: #909090;
+}
+
+.tag__link:hover {
+ font-weight: bolder;
+}
+
.book__list {
position: relative;
}
@@ -144,6 +165,8 @@ body {
.book__link {
text-decoration: none;
+ grid-column: 1 / 3;
+ grid-row: 1 / 3;
}
.book__wrapper {
@@ -165,6 +188,12 @@ body {
transform: scale(1.07);
}
+.book__link__wrapper {
+ display: grid;
+ grid-template-columns: 65px 1fr;
+ grid-template-rows: 70px 120px 1fr 1fr;
+}
+
.book__icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5QQcFgE71alp0QAAAAZiS0dEAP8A/wD/oL2nkwAADqhJREFUeNrtnQtQlWUax18urqi5WnbZq7Xtzlits5Xb7rbZuLWN7bqum9BamqZOKCoIKFflooAgFzGUlKslBCIkYCAqJKDcQUhAUMAUBUEQwXP5vnPUFL79v6dD4zZZ8B2Mr5nnP/PMi3i+b5j3d57nfd47YyQSiUQikUgkEolEIpFIJBKJRBopjZ8yxVDOnDXLfO7cuWPmz59vZfPmmxMWvPXWxMWLFz+4dOnSKe/C+M8LFiyYaGNjM2HevHlWs2fPtpw5c6bZrFmzqBKVpNWrVzOHtWvN7OzsHrBdsWIqyuednZzmeXh4OPj4+AT4+ftHbwkM3B8cHHwoLCzss23bthUaLCwsLyQkJDswMDDFz88vEp/1dnNzW2Jvb//Se7a2T6xcufIBZ0dHszV4P+kHlouLC1u6bJm5k5PTLxwdHf+Gf9tv3rw5bnt4eEFsbGxTyr59fdlZWV8WFBRIlRUV0qlTp6TGhgapualJOtfSYrCW5mbpTGOjVIv/qygvl/KPHRs4mJmpS0xIuPRBZGRx4JYtsZ4eHkvd3dyme7i7/8Tfz48q/n4K4ZRZW1ubL1++/EGAfQWVvjkoKCg/Pj7+EmCKHBIH2HH5snStp0dSXb8uadTqYdn1vj6pu6tLunD+vHSyqmrgUHa2Kj4uri4kOHgHvHyWp6fn+BXOzmydmxsBGSkhZLK1a9daIvQ+CU9dERAQkBUXF9eVl5t7m3tg15UrklqlkrQajaHkYDkobn29vUO2wWf48/w9g8DbLl3iUeDOJ2lpHVFRUdEI739BpPgJPJzgmKJnZ8wwlID7OMA6ob0sSt2/X6ypqZGudHZKGiMEDmQ4IIdrg8C78UWqqa4eyEhPPwOvXoem4FEYgZIjtIEsJTnZYmtQ0D+3bt1akJaaKjScPi31XrtmgKq+z1C/C3R7W5t04vhxzf6UlD1or5/cm5jIkmCkYSgzI4MVFxWZISw6lhQXi4Nghxt27xdo3sYjObt9OCcnO/3Agd9nf/opQRuOJEliR48c4fZ8dXX1mZ6rVxUB95vtddPZs/3IvrNzDh2aBtjs8OHDBG+oOoLKQhY7AV2dxEsXLw6oRiEsDwUyMvc7pSUlCccLCx9F1GEATvCGqs6ODpZ79OgytL+ikjz4bsi8BGRdVWWlZ1lp6RiUBG6oKsjPZzk5OdPQxz3D+6dKhXy1u5tD/qKutvalxoYGAjecMI1EazzC357WCxckpYXpuyEj2vSfa2nZ09zcPLGluZngDRUwF8L0O/V1dcLdYfE7K/yuNvLb7H5A5pl+x+XLbcgXXoOxtrY2Avh94pk0h5ydlfUUwnTNvcK0YQQKfVT0U+9oNJrrWo2mRdBqq2DHYNlarTYLv8uFVaC7dR6fEwdHvEYSMrpP/V1XroR2dXdbdXV1EcChiHc/DmZmPlBYUBB9d5g2Qh0ANBEQG0VBSIJ5iKL4H51ON0Mnir/Dv3+F8jH87jFBEH6Jz/0W9ic8swRfhGi1Wt2M992+PrKeXILyNygZ/kYCOBQvNtpChOk+DhYeeBuQ2gAuGQCX6XW6aXq9foJOr7f48tYtdvPmzXu+D4CZoNGYwavHAfKzeNc2QL4ygt7cg3f9k8MlwEMUQrQhTH9eU1MHIL2AGgubDZsEk/1egGWIAuNRLuu7dq0VNhKA7wCsO8yCAA9Rebm5PNEad/6LLxzhgYtv6PWT+2/fZqbAHRSA8PdYXunstEUm3DPURO57BkCi8aWx4l8g0hCHLm8DKNrUMQjB5iNdcRfOn2f48kw8XV8f097W1m8qYPx9n8ImEmAFCVk6O3HixN9rT53q4pMJciEbAR9HU/IwjCpWKTp48CBLSUl5KD8/P+9ye7vsQRUj4ArA/RkBVpASExNZ+PbtYzMzMnY0nT1r6FfLnlJUqSrQBfs5AVaQYqKj2UYvL8vEhAQvZOsDapmAjd24InTBHgFkqlil6P3t29kqOzuLqKgo1/Kysn5TQjQA56CfPklDgJUjvoju3SVLLHdERGwsKyszzYPV6o8AeBwBVpC8Nm5kixYuHBu+bdv7J0+eNCwRkrmkZwDheZNWq7VESRWrFLm5ubElS5ZMCg8Pzz575oxswPB8Dbx3gQpwtQRYOdqCEO3o6PhcbExMa2dHhyQnRPPwjC/GaYCdriXAytFGhGejFztmZ2ffkDtvzBMzhOZkQat9ECVVrFLk7OzMF9j/PDAwMPd0fb388KxWawB3hZrPWBFgRbW9bN26de/u27evr0fmMCV/BiG5GmCnEVyFyMPDg7e7bNWqVVODgoLyTn3+uSnJ1ZcAu1kUBEsCrBAhLLNFixZZukIHPvlEz9dVyRngMHpvgyAI0wmughQQEMAcHBxmRkREtJw7d0629+K5G/BcNz6vjJIqVglycnLiHvwLX1/f9OLiYsPIldzMGV6bB7BPcLgCAVYG3DVr1oxzc3XdlJqaqhvcMC4zNHcCrPUNnY6R9ypAPKmytrExA+S3oqOjOy62tkpyx50Rmm8BahBsHMFViHx9fHho/nNoaGhtXW2tKVmzhHB8RBTFxwmuAhQZGcns7Ow43Cc3+foeOnH8uKntbgPgvqxD1iyOwOI/kgni48z8uCV7e/uHN2zYEJ2dlXVL7upJQ7ur1XYC6mJRp7MguAppd21tbceiu7shOSlJ09XZKX8yQaMRANULNoHgKkCefLTKwYEnVQuidu++wre/mNDf/RLtbTQ8dwrBVYC8vb3Ze7a23IP/FBwcfKq+rs6UiYQ7SKrSAPbXHC4BHmVFREQMjjM/4uvr+3FBfn6/3KQKzw0A7jF47nSR93dhJAUMZrz99tsWLi4uDsnJyVq+C1/OYIYhYxaEWnjsSxpJYiLtN1JOeHZwcHguPDy8gR9xKCc0GzPmi4BrrdPrzSgsK0TIlrkHT0CXaOdneXl3VDJCszFj1gCqK2wswVWIANUwDYj297XoqKiLfBuKnC4RnulHxvwRwFLGrCTx5Td2dnY/RWIVW1RUJCs0G0eqagH4WRqGVFho5mdJ8znemJiY83K81xia1QC7QicI5gRYYZnz/DfeGOPl5RWAtldWt4i31/DeDIB9jMMlwAqSu7s731/0q+3h4ZX8VHc54Rne241u0XwOVktwlaX9KSk8RL+RkpKikjOJb2x7DwDwQ7QyQ2ne6+bG3lm0yBzhOai4qOi2LO9VqwUAXkKbxhQanl3Wr394W1jYETkDG1+vaxaEqbQyUoHy9PTk65z/8NGHHzbyiznkhGe0vzsFURxL204UJh/A9fH2Zt5eXq9npKd3yDlEBRm3jp+Ad1OSaNOY0rR161YW4O/PtgQELMrLzb0+7EmFr3blnwfYF2hXoAKFdpeFwsLCwlYXFRWJwwVs3JVfihD9G9q0rUDx8zUeGTeO7dyxw6W8rOymnNErPPMpErNHKYNWoACW2a9da7Z71y73qsrKWzIBJwHuZAKsQEVFRbHyvDwWFxvrfLKq6oZaTohWqfYgTE+ko48UKIBlsV+ZbUV5uVYlD3A8bCIdXqZA7YmPNxxkBnurpLi4T87kvkqlSgDcSQRYoUL7y3Z98MG/jxcWdvV9z50N/3d/w+CllCrVJ7ApKgKsTGWkp3P7a1NTUyXfeQBrH7JpNF3oHu2B906hNlih4jedwCYA1HRRFP8oCMIMlEMyfPYFGL/PYQzNIpFIJBKJRCJ9h+bMmcNmz57N5s6da/HG/PlWNjY2462trcfPmzfPCr+3fPHFF9krr7xCFfVj05o1a/iyWcuVK1dOdXR0nLNx40ZPPz+/XVu2bEni5u/vv8vb23uDq4vLv5ydnadu8PCw5Mt9SD8C8R0NTk5Ov3Z1dXUKCQkpSExMvHr0yJH+8vJy6fOaGoNVVlRIxz77rD8tLa0nNibm+Pbw8HUR77//eFBgIFWgkr12+fLl5oD78qZNm3LSUlOFhtOnJX41PJ9Z4uuzvmn8VLsvzp2TCgsLxX3JyYc/Tkx8+WBmpjlfmUlSkPge4IULF/Id/P8IDQ2tKy4uHlwhKd3rhlHj1TfS4MJ4fssKvLouOyvr9RMlJWaHjdfakhQgHx8fDnlGcHBwTVVV1ddgh3nPkcTPy6qoqDhZWlr6bNGJE1SxStD69et5m/ugl5dXgik7+AdBt1261F9fXx/f2Ng46UxjI1XwaIqvg3awt+fnPNvs3bv3Kr882pQr4Ae/GO1tbZ2tra3/RvvM2tvbqaJHS3ybKLpCP/X38/uwAlmy3MNVvuUWb+lqd/duJGETenp6qKJHQ/yOBR6eV69e/XR0dPQphFaTvPdbrAIe/TvDJc+9vVThP7TQFWLbQkP5Qvc5GenpvbzLM4I3ePN38RvBX1VxwHRF7A8vfpD331591Sw0JGRV/rFjt+7VHTIB8A28c/m169fN6A7gURDAMtv33rOIjIx0Lyst7VebcFPoPQDfAVgXtOsWtEZrFBS5cydPsizi4+I8qior7wdg/k43rSBY0BKeUVBcXBxf6G6ekJCwprKycsRDNN53C967StBqzWgh/CgoKSmJ5R49ypKTkuaWl5WBSe+IAob39mo1mrl8nzABHgWlHzjAMjMyWOr+/c+UlJTU8UGOkQJsvH+wDoCfoZ2Go6icnByWkZExqaS4eO9I9oON9w8mwibTRvBRVGFhIauvq2MI0QvONTf3jFR4hvf2CoKwUBBFun9wtFVTU8Oqq6unNDc1pSBMD5gapo3HBqeJgvAInY+lEAEMa71w4S8AXD8CoZlftPESLX5XkACWXWxtNb/W0zMfHtxkwi0qLYD7X1GnM6fDRxUmw6RAX58lQL0OK1L19d0cCmjDyTpq9U2E4xKdKM7R63Rj9ARXuVKjS4N2dJparfYDuGr8LHCI3zTDOi2Nhh96Vg2w/rCndAT2RwBYrWZaGOBaof/6NOxd2G60rbmwMgAtFbXaI/DYSABdDI/lYK1QMgL8I5Puq26OGWBaoU2dDPsZfveYTqebrNPrx97U6cxEvZ4qikQikUgkEolEIpFIJBKJRCKRfjj9DwvcRNne16EUAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIxLTA0LTI4VDIyOjAxOjUxKzAwOjAw1ZQfUAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMS0wNC0yOFQyMjowMTo1MSswMDowMKTJp+wAAAAASUVORK5CYII=');
background-repeat: no-repeat;
@@ -249,7 +278,6 @@ body {
text-align: end;
font-size: 1.1rem;
justify-content: flex-end;
- color: #909090;
font-family: roboto;
margin-right: 10px;
margin-top: 10px;
@@ -424,7 +452,7 @@ body {
@media screen and (max-width: 590px) {
.kiwixNav {
- height: 257px;
+ height: 285px;
}
.kiwixHomeBody {
@@ -436,10 +464,14 @@ body {
}
.kiwixButton {
- margin: 19px 0;
+ margin: 15px 0;
width: 229px;
}
+ .tagFilterLabel {
+ margin: 15px 0 0 0;
+ }
+
.kiwixNav__filters {
grid-template-columns: 1fr;
}
diff --git a/static/skin/index.js b/static/skin/index.js
index a6bcdd744..83ad0e8c8 100644
--- a/static/skin/index.js
+++ b/static/skin/index.js
@@ -77,6 +77,13 @@
return queryNode != null ? queryNode.innerHTML : "";
}
+ function generateTagLink(tagValue) {
+ tagValue = tagValue.toLowerCase();
+ const humanFriendlyTagValue = humanFriendlyTitle(tagValue);
+ const tagMessage = `Filter by tag "${humanFriendlyTagValue}"`;
+ return `
${humanFriendlyTagValue}`
+ }
+
function generateBookHtml(book, sort = false) {
const link = book.querySelector('link[type="text/html"]').getAttribute('href');
let iconUrl;
@@ -91,9 +98,9 @@
const langCode = getInnerHtml(book, 'language');
const language = languages[langCode];
const tags = getInnerHtml(book, 'tags');
- let tagHtml = tags.split(';').filter(tag => {return !(tag.split(':')[0].startsWith('_'))})
- .map((tag) => {return tag.charAt(0).toUpperCase() + tag.slice(1)})
- .join(' | ').replace(/_/g, ' ');
+ const tagList = tags.split(';').filter(tag => {return !(tag.startsWith('_'))});
+ const tagFilterLinks = tagList.map((tagValue) => generateTagLink(tagValue));
+ const tagHtml = tagFilterLinks.join(' | ');
let downloadLink;
let zimSize = 0;
try {
@@ -113,17 +120,21 @@
}
const faviconAttr = iconUrl != undefined ? `style="background-image: url('${iconUrl}')"` : '';
const languageAttr = langCode != '' ? `title="${language}" aria-label="${language}"` : 'style="background-color: transparent"';
- divTag.innerHTML = `
+ divTag.innerHTML = `
+
+
+
${getLanguageCodeToDisplay(langCode)}
-
`;
+ `;
return divTag;
}
@@ -333,6 +344,7 @@
insertModal(downloadButton);
}
});
+ refreshTagLinks();
}
async function resetAndFilter(filterType = '', filterValue = '') {
@@ -376,10 +388,45 @@
}
});
}
+
+ function addTagElement(tagValue, resetFilter) {
+ const tagElement = document.getElementsByClassName('tagFilterLabel')[0];
+ tagElement.style.display = 'inline-block';
+ const humanFriendlyTagValue = humanFriendlyTitle(tagValue);
+ tagElement.innerHTML = `${humanFriendlyTagValue}`;
+ const tagMessage = `Stop filtering by tag "${humanFriendlyTagValue}"`;
+ tagElement.setAttribute('aria-label', tagMessage);
+ tagElement.setAttribute('title', tagMessage);
+ if (resetFilter)
+ resetAndFilter('tag', tagValue);
+ }
+
+ function refreshTagLinks() {
+ const tagLinks = document.getElementsByClassName('tag__link');
+ [...tagLinks].forEach(elem => {
+ if (!elem.getAttribute('click-listener')) {
+ elem.addEventListener('click', () => addTagElement(elem.dataset.tag, true));
+ elem.setAttribute('click-listener', 'true');
+ }
+ });
+ }
+
+ function removeTagElement(resetFilter) {
+ const tagElement = document.getElementsByClassName('tagFilterLabel')[0];
+ tagElement.style.display = 'none';
+ if (resetFilter)
+ resetAndFilter('tag', '');
+ }
function updateVisibleParams() {
document.querySelectorAll('.filter').forEach(filter => {filter.value = params.get(filter.name) || ''});
updateFilterColors();
+ const tagKey = params.get('tag');
+ if (tagKey !== null && tagKey.trim() !== '') {
+ addTagElement(tagKey, false);
+ } else {
+ removeTagElement(false);
+ }
}
window.addEventListener('resize', (event) => {
@@ -417,6 +464,8 @@
document.querySelectorAll('.filter').forEach(filter => {
filter.addEventListener('change', () => {resetAndFilter(filter.name, filter.value)});
});
+ const tagElement = document.getElementsByClassName('tagFilterLabel')[0];
+ tagElement.addEventListener('click', () => removeTagElement(true));
if (filters) {
const currentLink = window.location.search;
const newLink = `?${params.toString()}`;
diff --git a/static/templates/index.html b/static/templates/index.html
index a62185fa8..0dabc45b7 100644
--- a/static/templates/index.html
+++ b/static/templates/index.html
@@ -58,6 +58,7 @@
diff --git a/test/server.cpp b/test/server.cpp
index 145f59226..3e31d1f6d 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -179,12 +179,12 @@ R"EXPECTEDRESULT( src="/ROOT/skin/jquery-ui/external/jquery/jquery.js?cache
src="/ROOT/skin/jquery-ui/jquery-ui.min.js?cacheid=d927c2ff"
href="/ROOT/skin/jquery-ui/jquery-ui.min.css?cacheid=e1de77b3"
href="/ROOT/skin/jquery-ui/jquery-ui.theme.min.css?cacheid=2a5841f9"
- href="/ROOT/skin/index.css?cacheid=1aca980a"
+ href="/ROOT/skin/index.css?cacheid=a1acc52f"
src: url("/ROOT/skin/fonts/Poppins.ttf?cacheid=af705837") format("truetype");
src: url("/ROOT/skin/fonts/Roboto.ttf?cacheid=84d10248") format("truetype");
-
+
)EXPECTEDRESULT"
},
{