feat: implement theme toggle (#201)

这个提交包含在:
H. C. Kruse 2021-01-11 18:13:59 +01:00 提交者 GitHub
父节点 bf7f458b79
当前提交 e30e6ce52c
找不到此签名对应的密钥
GPG 密钥 ID: 4AEE18F83AFDEB23
共有 17 个文件被更改,包括 797 次插入640 次删除

查看文件

@ -7,4 +7,5 @@
# ES6 files
resources/skins.citizen.scripts.search/typeahead-init.js
resources/skins.citizen.scripts.search/underscore.partial.js
resources/skins.citizen.scripts.search/wm-typeahead.js
resources/skins.citizen.scripts.search/wm-typeahead.js
resources/skins.citizen.scripts.theme-switcher/inline.js

查看文件

@ -1,26 +1,27 @@
{
"@metadata": {
"authors": [
"[https://www.mediawiki.org/wiki/User:Alistair3149 Alistair3149]",
"[https://www.mediawiki.org/wiki/User:Octfx Octfx]"
]
},
"skinname-citizen": "Citizen",
"citizen-skin-desc": "A responsive skin developed for the Star Citizen Wiki",
"citizen.css": "/* All CSS here will be loaded for users of the Citizen skin */",
"citizen.js": "/* All JavaScript here will be loaded for users of the Citizen skin */",
"citizen-drawer-toggle": "Toggle menu",
"citizen-search-toggle": "Toggle search",
"citizen-footer-desc": "Edit this text on MediaWiki:Citizen-footer-desc",
"citizen-footer-tagline": "Edit this text on MediaWiki:Citizen-footer-tagline",
"citizen-search-fulltext": "Search pages containing",
"prefs-citizen-theme-label": "Theme",
"prefs-citizen-theme-option-auto": "Auto",
"prefs-citizen-theme-option-light": "Light",
"prefs-citizen-theme-option-dark": "Dark"
}
{
"@metadata": {
"authors": [
"[https://www.mediawiki.org/wiki/User:Alistair3149 Alistair3149]",
"[https://www.mediawiki.org/wiki/User:Octfx Octfx]"
]
},
"skinname-citizen": "Citizen",
"citizen-skin-desc": "A responsive skin developed for the Star Citizen Wiki",
"citizen.css": "/* All CSS here will be loaded for users of the Citizen skin */",
"citizen.js": "/* All JavaScript here will be loaded for users of the Citizen skin */",
"citizen-drawer-toggle": "Toggle menu",
"citizen-search-toggle": "Toggle search",
"citizen-theme-toggle": "Toggle theme color",
"citizen-footer-desc": "Edit this text on MediaWiki:Citizen-footer-desc",
"citizen-footer-tagline": "Edit this text on MediaWiki:Citizen-footer-tagline",
"citizen-search-fulltext": "Search pages containing",
"prefs-citizen-theme-label": "Theme",
"prefs-citizen-theme-option-auto": "Auto",
"prefs-citizen-theme-option-light": "Light",
"prefs-citizen-theme-option-dark": "Dark"
}

查看文件

@ -12,6 +12,7 @@
"citizen.js": "{{optional}}",
"citizen-drawer-toggle": "Tooltip of drawer menu toggle",
"citizen-search-toggle": "Tooltip of search box toggle",
"citizen-theme-toggle": "Tooltip of theme color toggle",
"citizen-footer-desc": "Edit this text on MediaWiki:Citizen-footer-desc",
"citizen-footer-tagline": "Edit this text on MediaWiki:Citizen-footer-tagline",
"citizen-search-fulltext": "Fulltext search suggestion",

查看文件

@ -196,4 +196,21 @@ class CitizenHooks {
$prefs += $citizenPrefs;
}
}
/**
* Delete the override cookie if the theme was changed through the user preferences
*
* @param array $formData Array of user submitted data
* @param \HTMLForm $form HTMLForm object, also a ContextSource
* @param User $user User with preferences to be saved
* @param bool &$result Boolean indicating success
* @param array $oldUserOptions Array with user's old options (before save)
* @return bool|void True or no return value to continue or false to abort
*/
public static function onPreferencesFormPreSave( $formData, $form, $user, &$result, $oldUserOptions ) {
if (isset($formData['CitizenThemeUser']) && $formData['CitizenThemeUser'] !== 'auto') {
// Reset override cookie from theme toggle
$form->getOutput()->getRequest()->response()->setCookie('skin-citizen-theme-override', null);
}
}
}

查看文件

@ -45,7 +45,7 @@ class SkinCitizen extends SkinMustache {
$out = $skin->getOutput();
// Theme handler
$skin->setSkinTheme( $out, $options );
$skin->setSkinTheme( $out );
// Responsive layout
// Replace with core responsive option if it is implemented in 1.36+
@ -153,6 +153,7 @@ class SkinCitizen extends SkinMustache {
'data-drawer' => $this->buildDrawer(),
'data-extratools' => $this->getExtraTools(),
'data-search-box' => $this->buildSearchProps(),
'data-theme-toggle' => $this->buildThemeToggleProps(),
],
'data-pagetools' => $this->buildPageTools(),
@ -452,6 +453,22 @@ class SkinCitizen extends SkinMustache {
];
}
/**
* Render the theme toggle
*
* @return array
* @throws MWException
*/
private function buildThemeToggleProps() : array {
$skin = $this->getSkin();
$toggleMsg = $skin->msg( 'citizen-theme-toggle' )->text();
return [
'msg-citizen-theme-toggle-shortcut' => $toggleMsg,
];
}
/**
* Render page-related tools
* Possible visibility conditions:
@ -742,26 +759,31 @@ class SkinCitizen extends SkinMustache {
* If the theme is set to auto, the theme switcher script will be added
*
* @param OutputPage $out
* @param array &$skinOptions
*/
private function setSkinTheme( OutputPage $out, array &$skinOptions ) {
private function setSkinTheme( OutputPage $out ) {
// Set theme to site theme
$theme = $this->getConfigValue( 'CitizenThemeDefault' );
$theme = $this->getConfigValue( 'CitizenThemeDefault' ) ?? 'auto';
// Set theme to user theme if registered
if ( $this->getUser()->isRegistered() ) {
$theme = $this->getUser()->getOption( 'CitizenThemeUser' );
$theme = MediaWikiServices::getInstance()->getUserOptionsLookup()->getOption(
$this->getUser(),
'CitizenThemeUser',
'auto'
);
}
// Add HTML class based on theme set
$out->addHtmlClasses( 'skin-citizen-' . $theme );
// Load theme switcher script if auto
if ( $theme === 'auto' ) {
$skinOptions['scripts'] = array_merge(
$skinOptions['scripts'],
[ 'skins.citizen.scripts.theme-switcher' ]
);
if ($this->getRequest()->getCookie('skin-citizen-theme-override') === null) {
// Only set the theme cookie if the theme wasn't overridden by the user through the button
$this->getRequest()->response()->setCookie('skin-citizen-theme', $theme, 0, [
'httpOnly' => false,
]);
}
// Script content at 'skins.citizen.scripts.theme-switcher/inline.js
$this->getOutput()->addHeadItem('theme-switcher', '<script>(()=>{try{const t=document.cookie.match(/skin-citizen-theme=(dark|light|auto)/),e=null!==t?t.pop():null;null!==e&&(document.documentElement.classList.remove(...["auto","dark","light"].map(t=>"skin-citizen-"+t)),document.documentElement.classList.add("skin-citizen-"+e))}catch(t){}})();</script>');
$this->getOutput()->addModules('skins.citizen.scripts.theme-switcher');
}
}

查看文件

@ -8,5 +8,6 @@
<div class="mw-header-tools">
{{#data-extratools}}{{>Menu}}{{/data-extratools}}
{{#data-search-box}}{{>SearchBox}}{{/data-search-box}}
{{#data-theme-toggle}}{{>ThemeToggle}}{{/data-theme-toggle}}
</div>
</header>
</header>

查看文件

@ -0,0 +1,9 @@
{{!
string msg-citizen-theme-toggle-shortcut message with shortcut key for search toggle
}}
<button
role="button"
id="theme-toggle"
class="mw-theme-toggle"
title="{{msg-citizen-theme-toggle-shortcut}}">X</button>

查看文件

@ -50,4 +50,4 @@
{{#data-footer}}{{>Footer}}{{/data-footer}}
<aside class="mw-sidebar-sitename">
<a class="mw-wiki-title" {{{html-mainpage-attributes}}}>{{{msg-sitetitle}}}</a>
</aside>
</aside>

查看文件

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" viewBox="0 0 24 24" fill="black" width="20px"
height="20px">
<rect fill="none" height="24" width="24"/>
<path
d="M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36c-0.98,1.37-2.58,2.26-4.4,2.26 c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/>
</svg>

之后

宽度:  |  高度:  |  大小: 388 B

查看文件

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" viewBox="0 0 24 24" fill="black" width="20px"
height="20px">
<rect fill="none" height="24" width="24"/>
<path
d="M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0 c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2 c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1 C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06 c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41 l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41 c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36 c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/>
</svg>

之后

宽度:  |  高度:  |  大小: 1.1 KiB

查看文件

@ -0,0 +1,19 @@
/*
* Citizen - Inline script used in SkinCitizen.php
*
* https://starcitizen.tools
*/
(() => {
try {
const cookieTheme = document.cookie.match(/skin-citizen-theme=(dark|light|auto)/);
const theme = cookieTheme !== null ? cookieTheme.pop() : null;
if (theme !== null) {
document.documentElement.classList.remove(...['auto', 'dark', 'light'].map(theme => {
return 'skin-citizen-' + theme;
}));
document.documentElement.classList.add('skin-citizen-' + theme);
}
} catch (e) {
}
})();

查看文件

@ -4,53 +4,50 @@
*/
( function () {
var isGlobalAutoSet,
isUserPreferenceAuto,
enableAutoSwitcher,
switchColorScheme,
useDarkTheme,
prefersColorSchemeDarkQuery;
var prefersColorSchemeDarkQuery,
userTheme,
theme;
if ( typeof window.mw === 'undefined' ) {
return;
}
isGlobalAutoSet = window.mw.config.get( 'wgCitizenThemeDefault' ) === 'auto' ||
window.mw.config.get( 'wgCitizenThemeDefault' ) === null;
isUserPreferenceAuto = window.mw.user.options.get( 'CitizenThemeUser' ) === 'auto';
enableAutoSwitcher = isGlobalAutoSet || isUserPreferenceAuto;
if ( !enableAutoSwitcher ) {
return;
theme = window.mw.config.get( 'wgCitizenThemeDefault' );
if ( theme === null ) {
theme = 'auto';
}
switchColorScheme = function ( useDark ) {
var dark;
userTheme = window.mw.user.options.get( 'CitizenThemeUser' );
if ( useDark ) {
document.documentElement.classList.add( 'skin-citizen-dark' );
document.documentElement.classList.remove( 'skin-citizen-light' );
dark = true;
} else {
document.documentElement.classList.add( 'skin-citizen-light' );
document.documentElement.classList.remove( 'skin-citizen-dark' );
dark = false;
}
try {
localStorage.setItem( 'skin-citizen-dark', dark );
} catch ( e ) {}
};
if ( userTheme !== null ) {
theme = userTheme;
}
if ( theme !== 'auto' ) {
return;
}
try {
useDarkTheme = localStorage.getItem( 'skin-citizen-dark' );
if ( window.mw.cookie.get( 'skin-citizen-theme-override' ) === '1' ) {
return;
}
} catch ( e ) {}
prefersColorSchemeDarkQuery = window.matchMedia( '(prefers-color-scheme: dark)' );
if ( prefersColorSchemeDarkQuery.matches ) {
theme = 'dark';
}
if ( useDarkTheme || prefersColorSchemeDarkQuery.matches ) {
switchColorScheme( true );
prefersColorSchemeDarkQuery.addEventListener( 'change', function ( e ) {
if ( e.matches ) {
theme = 'dark';
} else {
theme = 'light';
}
} );
try {
window.mw.cookie.set( 'skin-citizen-theme', null );
window.mw.cookie.set( 'skin-citizen-theme', theme );
} catch ( e ) {
}
}() );

查看文件

@ -40,3 +40,48 @@ function main() {
}
main();
( function () {
var theme = window.mw.cookie.get( 'skin-citizen-theme' );
var toggleBtn = document.getElementById( 'theme-toggle' );
// * theme-toggle-light
// * theme-toggle-dark
toggleBtn.classList.add( 'theme-toggle-' + theme );
toggleBtn.addEventListener( 'click', function ( clickEvent ) {
try {
theme = theme === 'dark' ? 'light' : 'dark';
clickEvent.target.classList.remove( 'theme-toggle-light', 'theme-toggle-dark' );
// * theme-toggle-light
// * theme-toggle-dark
clickEvent.target.classList.add( 'theme-toggle-' + theme );
try {
window.mw.cookie.set( 'skin-citizen-theme', null );
window.mw.cookie.set( 'skin-citizen-theme', theme );
window.mw.cookie.set( 'skin-citizen-theme-override', '1' );
} catch ( e ) {
}
[ 'auto', 'dark', 'light' ].map( function ( themeSuffix ) {
// * skin-citizen-auto
// * skin-citizen-dark
// * skin-citizen-light
return 'skin-citizen-' + themeSuffix;
} ).forEach( function ( cssClass ) {
// * skin-citizen-auto
// * skin-citizen-dark
// * skin-citizen-light
document.documentElement.classList.remove( cssClass );
} );
// * skin-citizen-auto
// * skin-citizen-dark
// * skin-citizen-light
document.documentElement.classList.add( 'skin-citizen-' + theme );
} catch ( e ) {
}
} );
}() );

查看文件

@ -1,3 +1,6 @@
.search-container {
position: relative;
}
#search {
&form {

查看文件

@ -0,0 +1,16 @@
.mw-theme-toggle {
background-color: transparent;
border: none;
background-repeat: no-repeat;
background-position: center;
font-size: 0;
opacity: 0.4;
width: 39px;
height: 56px;
}
.skin-citizen-dark {
.mw-theme-toggle {
filter: invert(1);
}
}

查看文件

@ -23,6 +23,7 @@
@import 'Catlinks.less';
@import 'Pagelinks.less';
@import 'Footer.less';
@import 'ThemeToggle.less';
}
@media print {

1142
skin.json

文件差异内容过多而无法显示 加载差异