mirror of
https://github.com/kiwix/kiwix-js.git
synced 2025-08-03 11:16:38 -04:00
Added Wikipedia's own Dark Mode solution (#1320)
* Addede wikipedia's dark mode Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Fixed codefactor issue Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Removed overriding classes Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Fixed dark mode conversion Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * fixed another little update Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Added wikipedia's dark theme for zim Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * fixed codefactor Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * adding css file in sw file Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Added feature to switch to a standard inversion dark mode if the user loads a non-Wikimedia ZIM Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * added explicit check for the theme Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Fixed dropdown issue and add asterisk Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * fixing white flash Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * fixing eslint Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Fixing codeerror Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * REVERTING Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Revert "REVERTING" This reverts commit c515392dcf1acdafdd8023989ddeb8bb0da60c74. * Fixed color * Removing unncessary code which was added to fix flash issue Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Add translations in i18n dir Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Added in description Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> * Update i18n/es.jsonp.js Co-authored-by: Jaifroid <egk10@cam.ac.uk> * Update i18n/fr.jsonp.js Co-authored-by: Jaifroid <egk10@cam.ac.uk> * Update i18n/fr.jsonp.js Co-authored-by: Jaifroid <egk10@cam.ac.uk> --------- Signed-off-by: THEBOSS0369 <anujkumsharma9876@gmail.com> Co-authored-by: Jaifroid <egk10@cam.ac.uk>
This commit is contained in:
parent
ec52b0a6b7
commit
0e531b6e3c
@ -57,11 +57,13 @@ document.localeJson = {
|
||||
"configure-display-themeoption-dark-apponly": "Dark (app only)",
|
||||
"configure-display-themeoption-dark-invert": "Dark (generic invert)",
|
||||
"configure-display-themeoption-dark-mwinvert": "Dark (wikimedia invert)",
|
||||
"configure-display-themeoption-dark-wikivector": "Dark (wikipedia vector)",
|
||||
"configure-display-themeoption-auto-apponly": "Auto (app only)",
|
||||
"configure-display-themeoption-auto-invert": "Auto (generic invert)",
|
||||
"configure-display-themeoption-auto-mwinvert": "Auto (wikimedia invert)",
|
||||
"configure-display-apptheme-auto-description": " (Auto themes match the dark/light mode of your device.)",
|
||||
"configure-display-apptheme-mwinvert-description": "* Implements workarounds specific to Wikimedia ZIMs. Try generic option if there are display errors with recent ZIMs.",
|
||||
"configure-display-apptheme-wikivector-description": "* Only applies to Wikimedia ZIMs. Falls back to generic inversion when other archives are loaded.",
|
||||
"configure-display-apptheme-info": "[ Show article with applied theme ]",
|
||||
"configure-display-libzimsearchtype": "<b>Add snippets to libzim fulltext search</b> (if available)",
|
||||
"configure-display-libzimsearchtype-tip": "If checked, uses libzim fulltext search with snippet previews if available, otherwise just gets fulltext titles. Hover, click or press enter on keyboard to expand the snippet.",
|
||||
|
@ -57,11 +57,13 @@ document.localeJson = {
|
||||
"configure-display-themeoption-dark-apponly": "Oscuro (sólo aplicación)",
|
||||
"configure-display-themeoption-dark-invert": "Oscuro (inversión genérica)",
|
||||
"configure-display-themeoption-dark-mwinvert": "Oscuro (inversión wikimedia)",
|
||||
"configure-display-themeoption-dark-wikivector": "Oscuro (estilo vector de wikipedia)",
|
||||
"configure-display-themeoption-auto-apponly": "Auto (sólo aplicación)",
|
||||
"configure-display-themeoption-auto-invert": "Auto (inversión genérica)",
|
||||
"configure-display-themeoption-auto-mwinvert": "Auto (inversión wikimedia)",
|
||||
"configure-display-apptheme-auto-description": " (Temas automáticos se adaptan al modo oscuro/claro de su dispositivo.)",
|
||||
"configure-display-apptheme-mwinvert-description": "* Implementa soluciones específicas para ZIMs de Wikimedia. Pruebe la opción genérica si hay errores de visualización con otros ZIMs.",
|
||||
"configure-display-apptheme-wikivector-description": "* Solo se aplica a los ZIM de Wikimedia. Se revierte a la inversión genérica cuando se cargan otros archivos.",
|
||||
"configure-display-apptheme-info": "[ Mostrar artículo con tema seleccionado ]",
|
||||
"configure-display-libzimsearchtype": "<b>Agregar fragmentos a la búsqueda de texto completo libzim</b> (si están disponibles)",
|
||||
"configure-display-libzimsearchtype-tip": "Si está marcado, usa la búsqueda de texto completo libzim con vistas previas de fragmentos si están disponibles, de lo contrario solo obtiene títulos de texto completo. Pase el cursor, haga clic o presione enter en el teclado para expandir el fragmento.",
|
||||
|
@ -57,11 +57,13 @@ document.localeJson = {
|
||||
"configure-display-themeoption-dark-apponly": "Sombre (application uniquement)",
|
||||
"configure-display-themeoption-dark-invert": "Sombre (inversion générique)",
|
||||
"configure-display-themeoption-dark-mwinvert": "Sombre (inversion Wikimédia)",
|
||||
"configure-display-themeoption-dark-wikivector": "Sombre (style vector de Wikipédia)",
|
||||
"configure-display-themeoption-auto-apponly": "Automatique (application uniquement)",
|
||||
"configure-display-themeoption-auto-invert": "Automatique (inversion générique)",
|
||||
"configure-display-themeoption-auto-mwinvert": "Automatique (inversion Wikimédia)",
|
||||
"configure-display-apptheme-auto-description": " (Les thèmes automatiques s'adaptent au mode sombre/clair de votre appareil.)",
|
||||
"configure-display-apptheme-mwinvert-description": "* Implémente des solutions spécifiques aux ZIM de Wikimédia. Essayez l'option générique si vous rencontrez des problèmes d'affichage avec d'autres ZIM.",
|
||||
"configure-display-apptheme-wikivector-description": "* S’applique uniquement aux ZIMs de Wikimédia. Revient à l’inversion générique lorsque d’autres archives sont chargées.",
|
||||
"configure-display-apptheme-info": "[ Afficher l'article avec le thème sélectionné ]",
|
||||
"configure-display-libzimsearchtype": "<b>Ajouter des extraits à la recherche en texte intégral libzim</b> (si disponible)",
|
||||
"configure-display-libzimsearchtype-tip": "Si coché, utilise la recherche en texte intégral libzim avec des aperçus d'extraits si disponibles, sinon obtient seulement les titres en texte intégral. Survolez, cliquez ou appuyez sur Entrée au clavier pour développer l'extrait.",
|
||||
|
@ -116,6 +116,7 @@ const precacheFiles = [
|
||||
'www/css/app.css',
|
||||
'www/css/kiwixJS_invert.css',
|
||||
'www/css/kiwixJS_mwInvert.css',
|
||||
'www/css/kiwixJS_wikiVector.css',
|
||||
'www/css/transition.css',
|
||||
'www/img/icons/kiwix-256.png',
|
||||
'www/img/icons/kiwix-32.png',
|
||||
|
@ -550,3 +550,4 @@ button {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
1247
www/css/kiwixJS_wikiVector.css
Normal file
1247
www/css/kiwixJS_wikiVector.css
Normal file
File diff suppressed because it is too large
Load Diff
@ -567,12 +567,14 @@
|
||||
<option data-i18n="configure-display-themeoption-dark-apponly" value="dark">Dark (app only)</option>
|
||||
<option data-i18n="configure-display-themeoption-dark-invert" value="dark_invert">Dark (generic invert)</option>
|
||||
<option data-i18n="configure-display-themeoption-dark-mwinvert" value="dark_mwInvert">Dark (wikimedia invert)*</option>
|
||||
<option data-i18n="configure-display-themeoption-dark-wikivector" id="theme-vector-option" title="Vector style only available for Wikimedia ZIMs" value="dark_wikiVector">Dark (Wikipedia Vector)*</option>
|
||||
<option data-i18n="configure-display-themeoption-auto-apponly" class="auto" value="auto">Auto (app only)</option>
|
||||
<option data-i18n="configure-display-themeoption-auto-invert" class="auto" value="auto_invert">Auto (generic invert)</option>
|
||||
<option data-i18n="configure-display-themeoption-auto-mwinvert" class="auto" value="auto_mwInvert">Auto (wikimedia invert)*</option>
|
||||
</select>
|
||||
<p data-i18n="configure-display-apptheme-auto-description" class="text-muted" id="kiwix-auto-description" style="margin-bottom: 0;"> (Auto themes match the dark/light mode of your device.)</p>
|
||||
<p data-i18n="configure-display-apptheme-mwinvert-description" id="mwInvert-help" class="appThemeInfo form-text text-muted">* Implements workarounds specific to Wikimedia ZIMs. Try generic option if there are display errors with recent ZIMs.</p>
|
||||
<p data-i18n="configure-display-apptheme-wikivector-description" id="wikiVector-help" class="appThemeInfo form-text text-muted">* Only applies to Wikimedia ZIMs. Falls back to generic inversion when other archives are loaded.</p>
|
||||
<a data-i18n="configure-display-apptheme-info" id="viewArticle" class="appThemeInfo form-text" href="#">[ Show article with applied theme ]</a>
|
||||
</div>
|
||||
<div class="checkbox" id="libzimSearchTypeCheckBox">
|
||||
|
@ -126,6 +126,50 @@ darkPreference.onchange = function () {
|
||||
uiUtil.applyAppTheme(params.appTheme);
|
||||
}
|
||||
|
||||
// Vector Dark theme update the Dropdown UI State
|
||||
function updateThemeOptions() {
|
||||
const vectorOption = document.getElementById('theme-vector-option');
|
||||
if (vectorOption) {
|
||||
// Only disable if a ZIM is loaded and it's not a Wikimedia ZIM
|
||||
const zimLoaded = selectedArchive && selectedArchive.file && selectedArchive.file.name;
|
||||
vectorOption.disabled = zimLoaded && !params.isWikimediaZim;
|
||||
vectorOption.title = (!zimLoaded || params.isWikimediaZim) ? "" : "Vector style only available for Wikimedia ZIMs";
|
||||
|
||||
// Check that dropdown matches actual theme
|
||||
const currentTheme = document.getElementById('appThemeSelect')?.value;
|
||||
if (currentTheme && currentTheme.includes('_wikiVector') && !params.isWikimediaZim) {
|
||||
// If somehow Vector is selected for non Wikimedia ZIM then correct it
|
||||
handleThemeFallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleThemeFallback() {
|
||||
const themeSelect = document.getElementById('appThemeSelect');
|
||||
if (!themeSelect) return;
|
||||
const currentTheme = themeSelect.value || settingsStore.getItem('appTheme') || 'light';
|
||||
|
||||
// When switching to Wikimedia ZIM
|
||||
if (params.isWikimediaZim) {
|
||||
// If current theme is invert then try to restore Vector if it was previously used
|
||||
if (currentTheme.includes('_invert')) {
|
||||
const baseTheme = currentTheme.replace('_invert', '_wikiVector');
|
||||
if (themeSelect.querySelector(`option[value="${baseTheme}"]`)) {
|
||||
themeSelect.value = baseTheme;
|
||||
uiUtil.applyAppTheme(baseTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When switching from Wikimedia ZIM
|
||||
else if (currentTheme.includes('_wikiVector')) {
|
||||
const newTheme = currentTheme.replace('_wikiVector', '_invert');
|
||||
themeSelect.value = newTheme;
|
||||
uiUtil.applyAppTheme(newTheme);
|
||||
}
|
||||
updateThemeOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize the IFrame height, so that it fills the whole available height in the window
|
||||
*/
|
||||
@ -1868,6 +1912,9 @@ async function archiveReadyCallback (archive) {
|
||||
}
|
||||
// This flag will be reset each time a new archive is loaded
|
||||
appstate.wikimediaZimLoaded = /wikipedia|wikivoyage|mdwiki|wiktionary/i.test(archive.file.name);
|
||||
params.isWikimediaZim = /wikipedia|wikimedia|wikivoyage|wiktionary|wikibooks|wikiquote|wikisource|wikinews|wikiversity/i.test(archive.file.name);
|
||||
updateThemeOptions();
|
||||
handleThemeFallback();
|
||||
// Set contentInjectionMode to serviceWorker when opening a new archive in case the user switched to Restricted Mode/jquery Mode when opening the previous archive
|
||||
if (params.contentInjectionMode === 'jquery') {
|
||||
params.contentInjectionMode = settingsStore.getItem('contentInjectionMode');
|
||||
@ -2306,6 +2353,7 @@ function articleLoadedSW (iframeArticleContent) {
|
||||
// Display the iframe content
|
||||
iframeArticleContent.style.display = '';
|
||||
articleContainer.style.display = '';
|
||||
|
||||
// Deflect drag-and-drop of ZIM file on the iframe to Config
|
||||
if (!params.disableDragAndDrop) {
|
||||
var doc = iframeArticleContent.contentDocument ? iframeArticleContent.contentDocument.documentElement : null;
|
||||
@ -2720,6 +2768,7 @@ function displayArticleContentInIframe (dirEntry, htmlArticle) {
|
||||
if (!isDirEntryExpectedToBeDisplayed(dirEntry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Display Bootstrap warning alert if the landing page contains active content
|
||||
if (!params.hideActiveContentWarning && params.isLandingPage) {
|
||||
if (regexpActiveContent.test(htmlArticle) || /zimit/.test(selectedArchive.zimType)) {
|
||||
|
@ -853,10 +853,21 @@ function tabTransitionToSection (toSection, isAnimationRequired = false) {
|
||||
* @param {String} theme The theme to apply (light|dark[_invert|_mwInvert]|auto[_invert|_mwInvert])
|
||||
*/
|
||||
function applyAppTheme (theme) {
|
||||
// Validate the theme parameter to prevent XSS
|
||||
// Only allow specific valid theme formats
|
||||
if (!theme.match(/^(light|dark|auto)(_invert|_mwInvert|_wikiVector)?$/)) {
|
||||
console.error('Invalid theme format:', theme);
|
||||
theme = 'light';
|
||||
}
|
||||
|
||||
// Resolve the app theme from the matchMedia preference (for auto themes) or from the theme string
|
||||
var appTheme = isDarkTheme(theme) ? 'dark' : 'light';
|
||||
// Get contentTheme from chosen theme
|
||||
var contentTheme = theme.replace(/^[^_]*/, '');
|
||||
// Revert to '_invert' or default dark theme if trying to use '_wikiVector' on non-Wikimedia ZIMs
|
||||
if (contentTheme === '_wikiVector' && !params.isWikimediaZim) {
|
||||
contentTheme = '_invert';
|
||||
}
|
||||
var htmlEl = document.querySelector('html');
|
||||
var footer = document.querySelector('footer');
|
||||
var oldTheme = htmlEl.dataset.theme || '';
|
||||
@ -877,19 +888,28 @@ function applyAppTheme (theme) {
|
||||
footer.classList.add(contentTheme || '_light');
|
||||
// Embed a reference to applied theme, so we can remove it generically in the future
|
||||
htmlEl.dataset.theme = appTheme + contentTheme;
|
||||
|
||||
// Safely handle help element IDs
|
||||
var safeOldContentTheme = oldContentTheme.replace(/[^a-zA-Z0-9-]/g, '');
|
||||
var safeContentTheme = contentTheme.replace(/[^a-zA-Z0-9-]/g, '');
|
||||
|
||||
// Hide any previously displayed help
|
||||
var oldHelp = document.getElementById(oldContentTheme.replace(/_/, '') + '-help');
|
||||
var oldHelp = document.getElementById(safeOldContentTheme.replace(/_/, '') + '-help');
|
||||
if (oldHelp) oldHelp.style.display = 'none';
|
||||
// Show any specific help for selected contentTheme
|
||||
var help = document.getElementById(contentTheme.replace(/_/, '') + '-help');
|
||||
var help = document.getElementById(safeContentTheme.replace(/_/, '') + '-help');
|
||||
if (help) help.style.display = 'block';
|
||||
// Remove the contentTheme for auto themes whenever system is in light mode
|
||||
if (/^auto/.test(theme) && appTheme === 'light') contentTheme = null;
|
||||
// Hide any previously displayed description for auto themes
|
||||
var oldDescription = document.getElementById('kiwix-auto-description');
|
||||
if (oldDescription) oldDescription.style.display = 'none';
|
||||
|
||||
// Safely handle description element IDs
|
||||
var safeThemeBase = theme.replace(/_.*$/, '').replace(/[^a-zA-Z0-9-]/g, '');
|
||||
|
||||
// Show description for auto themes
|
||||
var description = document.getElementById('kiwix-' + theme.replace(/_.*$/, '') + '-description');
|
||||
var description = document.getElementById('kiwix-' + safeThemeBase + '-description');
|
||||
if (description) description.style.display = 'block';
|
||||
// If there is no ContentTheme or we are applying a different ContentTheme, remove any previously applied ContentTheme
|
||||
if (oldContentTheme && oldContentTheme !== contentTheme) {
|
||||
@ -913,7 +933,8 @@ function applyAppTheme (theme) {
|
||||
link.setAttribute('id', 'kiwixJSTheme');
|
||||
link.setAttribute('rel', 'stylesheet');
|
||||
link.setAttribute('type', 'text/css');
|
||||
link.setAttribute('href', prefix + '/css/kiwixJS' + contentTheme + '.css');
|
||||
var safeContentThemeForURL = contentTheme.replace(/[^a-zA-Z0-9_-]/g, '');
|
||||
link.setAttribute('href', prefix + '/css/kiwixJS' + safeContentThemeForURL + '.css');
|
||||
doc.head.appendChild(link);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user