. * * @file * @ingroup Skins */ declare( strict_types=1 ); namespace MediaWiki\Skins\Citizen\Hooks; use MediaWiki\Hook\BeforePageDisplayHook; use MediaWiki\Hook\SkinTemplateNavigation__UniversalHook; use MediaWiki\Skins\Hook\SkinPageReadyConfigHook; use OutputPage; use Skin; /** * Hooks to run relating the skin */ class SkinHooks implements BeforePageDisplayHook, SkinPageReadyConfigHook, SkinTemplateNavigation__UniversalHook { /** * Adds the inline theme switcher script to the page * * @param OutputPage $out * @param Skin $skin */ public function onBeforePageDisplay( $out, $skin ): void { // It's better to exit before any additional check if ( $skin->getSkinName() !== 'citizen' ) { return; } $nonce = $out->getCSP()->getNonce(); // Script content at 'skins.citizen.scripts.theme/inline.js // phpcs:disable Generic.Files.LineLength.TooLong $script = sprintf( '%s', $nonce !== false ? sprintf( ' nonce="%s"', $nonce ) : '', 'window.applyPref=()=>{const a="skin-citizen-",b="skin-citizen-theme",c=a=>window.localStorage.getItem(a),d=c("skin-citizen-theme"),e=()=>{const d={fontsize:"font-size",pagewidth:"--width-layout",lineheight:"--line-height"},e=()=>["auto","dark","light"].map(b=>a+b),f=a=>{let b=document.getElementById("citizen-style");null===b&&(b=document.createElement("style"),b.setAttribute("id","citizen-style"),document.head.appendChild(b)),b.textContent=`:root{${a}}`};try{const g=c(b);let h="";if(null!==g){const b=document.documentElement;b.classList.remove(...e(a)),b.classList.add(a+g)}for(const[b,e]of Object.entries(d)){const d=c(a+b);null!==d&&(h+=`${e}:${d};`)}h&&f(h)}catch(a){}};if("auto"===d){const a=window.matchMedia("(prefers-color-scheme: dark)"),c=a.matches?"dark":"light",d=(a,b)=>window.localStorage.setItem(a,b);d(b,c),e(),a.addEventListener("change",()=>{e()}),d(b,"auto")}else e()},(()=>{window.applyPref()})();' ); // phpcs:enable Generic.Files.LineLength.TooLong $out->addHeadItem( 'skin.citizen.inline', $script ); } /** * SkinPageReadyConfig hook handler * * Replace searchModule provided by skin. * * @since 1.35 * @param ResourceLoaderContext $context * @param mixed[] &$config Associative array of configurable options * @return void This hook must not abort, it must return no value */ public function onSkinPageReadyConfig( $context, array &$config ): void { // It's better to exit before any additional check if ( $context->getSkin() !== 'citizen' ) { return; } // Tell the `mediawiki.page.ready` module not to wire up search. $config['search'] = false; } /** * Modify navigation links * * @see https://www.mediawiki.org/wiki/Manual:Hooks/SkinTemplateNavigation::Universal * @param SkinTemplate $sktemplate * @param array &$links */ public function onSkinTemplateNavigation__Universal( $sktemplate, &$links ): void { // Remove userpage from user menu since it is used in user menu info if ( isset( $links['user-menu']['userpage'] ) ) { unset( $links['user-menu']['userpage'] ); } if ( isset( $links['user-menu']['anonuserpage'] ) ) { unset( $links['user-menu']['anonuserpage'] ); } } }