ResourceLoader: Basic client side user preferences
This allows the body classes of skins to be customized for anonymous
users. Enable using $wgResourceLoaderClientPreferences = true;
* Only classes of the form <prefix>-(disabled|enabled)
can be toggled.
* For now no client side API is provided as this should not be
considered stable.
* Storage mechanism is cookie, stored under "mwclientprefs"
* Preferences apply to all skins. This means setting a preference
in Vector 2022 would also lead to class manipulation in Minerva.
This is by design to allow for skin-agnostic preferences. Up to
caller to make sure the class being manipulated is limited to the
skin if required ie. don't use generic classes.
* Avoids try/catch and JSON parsing by storaging as a string
* Places inline script before body tag before first stylesheet to
avoid breaking the article's ability to parse the article
concurrently with stylesheet download.
Usage:
Given a document with classes
"client-js vector-feature-limited-width-enabled ext-feature-enabled"
Set:
document.cookie = 'mwclientprefs=vector-feature-limited-width'
Will result in toggling off the limited width.
Bug: T321498
Change-Id: Ic3b6eec19953932c697ab5bf48c33a4ac1841b07
This commit is contained in:
parent
66682881f1
commit
d4d6156c3b
7 changed files with 66 additions and 1 deletions
|
|
@ -3202,6 +3202,11 @@ config-schema:
|
|||
via the `useskin` query parameter. To uninstall a skin, remove its inclusion
|
||||
from LocalSettings.php.
|
||||
@see \SkinFactory::getAllowedSkins
|
||||
ResourceLoaderClientPreferences:
|
||||
default: false
|
||||
description: |-
|
||||
Whether skins support client side (anonymous) preferences.
|
||||
@see RL/ClientHtml
|
||||
DisableOutputCompression:
|
||||
default: false
|
||||
description: 'Disable output compression (enabled by default if zlib is available)'
|
||||
|
|
|
|||
|
|
@ -1990,6 +1990,12 @@ class MainConfigNames {
|
|||
*/
|
||||
public const SkipSkins = 'SkipSkins';
|
||||
|
||||
/**
|
||||
* Name constant for the ResourceLoaderClientPreferences setting, for use with Config::get()
|
||||
* @see MainConfigSchema::ResourceLoaderClientPreferences
|
||||
*/
|
||||
public const ResourceLoaderClientPreferences = 'ResourceLoaderClientPreferences';
|
||||
|
||||
/**
|
||||
* Name constant for the DisableOutputCompression setting, for use with Config::get()
|
||||
* @see MainConfigSchema::DisableOutputCompression
|
||||
|
|
|
|||
|
|
@ -5152,6 +5152,15 @@ class MainConfigSchema {
|
|||
'type' => 'map',
|
||||
];
|
||||
|
||||
/**
|
||||
* Whether skins support client side (anonymous) preferences.
|
||||
*
|
||||
* @see RL/ClientHtml
|
||||
*/
|
||||
public const ResourceLoaderClientPreferences = [
|
||||
'default' => false,
|
||||
];
|
||||
|
||||
/**
|
||||
* Disable output compression (enabled by default if zlib is available)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
namespace MediaWiki\ResourceLoader;
|
||||
|
||||
use Html;
|
||||
use MediaWiki\MainConfigNames;
|
||||
use Wikimedia\WrappedString;
|
||||
use Wikimedia\WrappedStringList;
|
||||
|
||||
|
|
@ -289,6 +290,15 @@ RLPAGEMODULES = {$pageModulesJson};
|
|||
";
|
||||
}
|
||||
|
||||
$config = $this->resourceLoader->getConfig();
|
||||
$user = $this->context->getUserIdentity();
|
||||
$isAnon = !$user || !$user->isRegistered();
|
||||
// This code is only loaded for anonymous users. Logged in users should use preferences.
|
||||
if ( $config->get( MainConfigNames::ResourceLoaderClientPreferences ) && $isAnon ) {
|
||||
$script .= $this->getClientSidePreferencesScript(
|
||||
$config->get( MainConfigNames::CookiePrefix )
|
||||
);
|
||||
}
|
||||
if ( !$this->context->getDebug() ) {
|
||||
$script = ResourceLoader::filter( 'minify-js', $script, [ 'cache' => false ] );
|
||||
}
|
||||
|
|
@ -383,6 +393,32 @@ RLPAGEMODULES = {$pageModulesJson};
|
|||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds ability for anonymous users to change classes on document.documentElement
|
||||
*
|
||||
* @param string $cookiePrefix
|
||||
* @return string
|
||||
*/
|
||||
private function getClientSidePreferencesScript( string $cookiePrefix ) {
|
||||
return <<<END
|
||||
(function () {
|
||||
// Client side preferences
|
||||
var doc = document.documentElement;
|
||||
var clientPrefCookie = document.cookie.match(/(?:^|; )${cookiePrefix}mwclientprefs=([^;]+)/);
|
||||
// For now, only support disabling a feature
|
||||
// Only supports a single feature (modifying a single class) at this stage.
|
||||
// In future this may be expanded to multiple once this has been proven as viable.
|
||||
if ( clientPrefCookie ) {
|
||||
var featureName = clientPrefCookie[1];
|
||||
doc.className = doc.className.replace(
|
||||
featureName + '-enabled',
|
||||
featureName + '-disabled'
|
||||
);
|
||||
}
|
||||
} () );
|
||||
END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly load or embed modules on a page.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -645,6 +645,7 @@ return [
|
|||
'FallbackSkin' => 'fallback',
|
||||
'SkipSkins' => [
|
||||
],
|
||||
'ResourceLoaderClientPreferences' => false,
|
||||
'DisableOutputCompression' => false,
|
||||
'FragmentMode' => [
|
||||
0 => 'html5',
|
||||
|
|
|
|||
|
|
@ -1974,6 +1974,12 @@ $wgFallbackSkin = null;
|
|||
*/
|
||||
$wgSkipSkins = null;
|
||||
|
||||
/**
|
||||
* Config variable stub for the ResourceLoaderClientPreferences setting, for use by phpdoc and IDEs.
|
||||
* @see MediaWiki\MainConfigSchema::ResourceLoaderClientPreferences
|
||||
*/
|
||||
$wgResourceLoaderClientPreferences = null;
|
||||
|
||||
/**
|
||||
* Config variable stub for the DisableOutputCompression setting, for use by phpdoc and IDEs.
|
||||
* @see MediaWiki\MainConfigSchema::DisableOutputCompression
|
||||
|
|
|
|||
|
|
@ -348,7 +348,9 @@ class ClientHtmlTest extends \PHPUnit\Framework\TestCase {
|
|||
}
|
||||
|
||||
private static function makeContext( $extraQuery = [] ) {
|
||||
$conf = new HashConfig( [] );
|
||||
$conf = new HashConfig( [
|
||||
'ResourceLoaderClientPreferences' => false
|
||||
] );
|
||||
return new Context(
|
||||
new ResourceLoader( $conf, null, null, [
|
||||
'loadScript' => '/w/load.php',
|
||||
|
|
|
|||
Loading…
Reference in a new issue