20use Wikimedia\Minify\CSSMin;
117 'all' => [
'resources/src/mediawiki.skinning/normalize.less' ],
121 'all' => [
'resources/src/mediawiki.skinning/logo.less' ],
123 'print' => [
'resources/src/mediawiki.skinning/logo-print.less' ],
126 'screen' => [
'resources/src/mediawiki.skinning/content.thumbnails.less' ],
127 'print' => [
'resources/src/mediawiki.skinning/content.thumbnails-print.less' ],
130 'screen' => [
'resources/src/mediawiki.skinning/content.links.less' ]
132 'content-links-external' => [
133 'screen' => [
'resources/src/mediawiki.skinning/content.externallinks.less' ]
136 'screen' => [
'resources/src/mediawiki.skinning/content.body.less' ],
137 'print' => [
'resources/src/mediawiki.skinning/content.body-print.less' ],
139 'content-tables' => [
140 'screen' => [
'resources/src/mediawiki.skinning/content.tables.less' ],
141 'print' => [
'resources/src/mediawiki.skinning/content.tables-print.less' ]
144 'screen' => [
'resources/src/mediawiki.skinning/interface.less' ],
145 'print' => [
'resources/src/mediawiki.skinning/interface-print.less' ],
147 'interface-category' => [
148 'screen' => [
'resources/src/mediawiki.skinning/interface.category.less' ],
149 'print' => [
'resources/src/mediawiki.skinning/interface.category-print.less' ],
151 'interface-message-box' => [
152 'all' => [
'resources/src/mediawiki.skinning/messageBoxes.less' ],
155 'screen' => [
'resources/src/mediawiki.skinning/elements.less' ],
156 'print' => [
'resources/src/mediawiki.skinning/elements-print.less' ],
159 'all' => [
'resources/src/mediawiki.skinning/messageBoxes.less' ],
160 'print' => [
'resources/src/mediawiki.skinning/commonPrint.less' ],
161 'screen' => [
'resources/src/mediawiki.skinning/legacy.less' ],
163 'i18n-ordered-lists' => [
164 'screen' => [
'resources/src/mediawiki.skinning/i18n-ordered-lists.less' ],
166 'i18n-all-lists-margins' => [
167 'screen' => [
'resources/src/mediawiki.skinning/i18n-all-lists-margins.less' ],
170 'screen' => [
'resources/src/mediawiki.skinning/i18n-headings.less' ],
173 'all' => [
'resources/src/mediawiki.skinning/toc/common.css' ],
174 'screen' => [
'resources/src/mediawiki.skinning/toc/screen.less' ],
175 'print' => [
'resources/src/mediawiki.skinning/toc/print.css' ],
189 private const DEFAULT_FEATURES_SPECIFIED = [
190 'content-body' =>
true,
202 private const DEFAULT_FEATURES_ABSENT = [
238 $features = $options[
'features'] ?? self::DEFAULT_FEATURES_ABSENT;
247 foreach (
$features as $key => $enabled ) {
248 if ( !isset( self::FEATURE_FILES[$key] ) ) {
249 throw new InvalidArgumentException(
"Feature '$key' is not recognised" );
253 $this->features = $listMode
254 ? array_keys( array_filter(
$features ) )
255 : array_keys( array_filter(
$features + self::DEFAULT_FEATURES_SPECIFIED ) );
260 if ( in_array(
'toc', $this->features ) ) {
261 $options[
'lessMessages'] = array_merge(
262 $options[
'lessMessages'] ?? [],
268 $messages .=
'More information can be found at [[mw:Manual:ResourceLoaderSkinModule]]. ';
285 $messages .=
'[1.37] The use of the `content` feature with ResourceLoaderSkinModule'
286 .
' is deprecated. Use `content-media` instead. ';
290 if ( isset(
$features[
'content-thumbnails' ] ) ) {
292 $messages .=
'[1.37] The use of the `content-thumbnails` feature with ResourceLoaderSkinModule'
293 .
' is deprecated. Use `content-media` instead. ';
294 unset(
$features[
'content-thumbnails' ] );
298 if ( isset(
$features[
'content-links' ] ) && !isset(
$features[
'content-links-external' ] ) ) {
305 $messages .=
'[1.37] The use of the `legacy` feature with ResourceLoaderSkinModule is deprecated'
319 if ( isset(
$features[
'content-parser-output' ] ) ) {
321 unset(
$features[
'content-parser-output' ] );
334 $styles = parent::getStyleFiles( $context );
338 list( $defaultLocalBasePath, $defaultRemoteBasePath ) =
342 $this->getConfig()->
get(
'ResourceBasePath' )
345 $featureFilePaths = [];
347 foreach ( self::FEATURE_FILES as $feature => $featureFiles ) {
348 if ( in_array( $feature, $this->features ) ) {
349 foreach ( $featureFiles as $mediaType => $files ) {
350 foreach ( $files as $filepath ) {
353 $defaultLocalBasePath,
354 $defaultRemoteBasePath
358 if ( $feature ===
'content-media' && !$this->getConfig()->
get(
'ParserEnableLegacyMediaDOM' ) ) {
360 'resources/src/mediawiki.skinning/content.media.less',
361 $defaultLocalBasePath,
362 $defaultRemoteBasePath
372 foreach ( $styles as $mediaType => $paths ) {
373 $featureFilePaths[$mediaType] = array_merge( $featureFilePaths[$mediaType] ?? [], $paths );
376 return $featureFilePaths;
384 $logo = $this->getLogoData( $this->getConfig() );
385 $styles = parent::getStyles( $context );
386 $this->normalizeStyles( $styles );
388 $isLogoFeatureEnabled = in_array(
'logo', $this->features );
389 if ( $isLogoFeatureEnabled ) {
390 $default = !is_array( $logo ) ? $logo : $logo[
'1x'];
391 $styles[
'all'][] =
'.mw-wiki-logo { background-image: ' .
392 CSSMin::buildUrlValue( $default ) .
395 if ( is_array( $logo ) ) {
396 if ( isset( $logo[
'svg'] ) ) {
397 $styles[
'all'][] =
'.mw-wiki-logo { ' .
398 'background-image: -webkit-linear-gradient(transparent, transparent), ' .
399 CSSMin::buildUrlValue( $logo[
'svg'] ) .
'; ' .
400 'background-image: linear-gradient(transparent, transparent), ' .
401 CSSMin::buildUrlValue( $logo[
'svg'] ) .
';' .
402 'background-size: 135px auto; }';
404 if ( isset( $logo[
'1.5x'] ) ) {
406 '(-webkit-min-device-pixel-ratio: 1.5), ' .
407 '(min-resolution: 1.5dppx), ' .
408 '(min-resolution: 144dpi)'
409 ][] =
'.mw-wiki-logo { background-image: ' .
410 CSSMin::buildUrlValue( $logo[
'1.5x'] ) .
';' .
411 'background-size: 135px auto; }';
413 if ( isset( $logo[
'2x'] ) ) {
415 '(-webkit-min-device-pixel-ratio: 2), ' .
416 '(min-resolution: 2dppx), ' .
417 '(min-resolution: 192dpi)'
418 ][] =
'.mw-wiki-logo { background-image: ' .
419 CSSMin::buildUrlValue( $logo[
'2x'] ) .
';' .
420 'background-size: 135px auto; }';
434 return $this->getLogoPreloadlinks();
442 if ( !in_array(
'logo', $this->features ) ) {
446 $logo = $this->getLogoData( $this->getConfig() );
448 if ( !is_array( $logo ) ) {
450 return [ $logo => [
'as' =>
'image' ] ];
453 if ( isset( $logo[
'svg'] ) ) {
456 return [ $logo[
'svg'] => [
'as' =>
'image' ] ];
460 foreach ( $logo as $dppx => $src ) {
462 $dppx = substr( $dppx, 0, -1 );
463 $logosPerDppx[$dppx] = $src;
467 uksort( $logosPerDppx,
static function ( $a, $b ) {
475 foreach ( $logosPerDppx as $dppx => $src ) {
482 $logosCount = count( $logos );
489 for ( $i = 0; $i < $logosCount; $i++ ) {
494 $media_query =
'not all and (min-resolution: ' . $logos[1][
'dppx'] .
'dppx)';
495 } elseif ( $i !== $logosCount - 1 ) {
500 $upper_bound = floatval( $logos[$i + 1][
'dppx'] ) - 0.000001;
501 $media_query =
'(min-resolution: ' . $logos[$i][
'dppx'] .
502 'dppx) and (max-resolution: ' . $upper_bound .
'dppx)';
505 $media_query =
'(min-resolution: ' . $logos[$i][
'dppx'] .
'dppx)';
508 $preloadLinks[$logos[$i][
'src']] = [
510 'media' => $media_query
514 return $preloadLinks;
526 foreach ( $styles as $key => $val ) {
527 if ( !is_array( $val ) ) {
528 $styles[$key] = [ $val ];
540 $width = $logoElement[
'width'];
541 $height = $logoElement[
'height'];
542 $widthRelative = $width / 16;
543 $heightRelative = $height / 16;
545 $logoElement[
'style'] =
'width: ' . $widthRelative .
'em; height: ' . $heightRelative .
'em;';
564 $logos = $conf->get(
'Logos' );
565 if ( $logos ===
false ) {
573 if ( !isset( $logos[
'1x' ] ) ) {
574 $logo = $conf->get(
'Logo' );
576 $logos[
'1x'] = $logo;
581 $logoHD = $conf->get(
'LogoHD' );
592 if ( !isset( $logos[
'1x'] ) ) {
593 throw new RuntimeException(
"The key `1x` is required for wgLogos or wgLogo must be defined." );
599 if ( isset( $logos[
'wordmark'] ) && $logos[
'wordmark'] ) {
601 $logos[
'wordmark'] = self::getRelativeSizedLogo( $logos[
'wordmark'] );
607 if ( isset( $logos[
'tagline'] ) && $logos[
'tagline'] ) {
608 $logos[
'tagline'] = self::getRelativeSizedLogo( $logos[
'tagline'] );
623 $logoHD = self::getAvailableLogos( $conf );
624 $logo = $logoHD[
'1x'];
626 $logo1Url = OutputPage::transformResourcePath( $conf, $logo );
632 if ( isset( $logoHD[
'svg'] ) ) {
633 $logoUrls[
'svg'] = OutputPage::transformResourcePath(
637 } elseif ( isset( $logoHD[
'1.5x'] ) || isset( $logoHD[
'2x'] ) ) {
639 if ( isset( $logoHD[
'1.5x'] ) ) {
640 $logoUrls[
'1.5x'] = OutputPage::transformResourcePath(
645 if ( isset( $logoHD[
'2x'] ) ) {
646 $logoUrls[
'2x'] = OutputPage::transformResourcePath(
676 $lessVars = parent::getLessVars( $context );
677 $logos = self::getAvailableLogos( $this->getConfig() );
679 if ( isset( $logos[
'wordmark'] ) ) {
680 $logo = $logos[
'wordmark'];
681 $lessVars[
'logo-enabled' ] =
true;
682 $lessVars[
'logo-wordmark-url' ] = CSSMin::buildUrlValue( $logo[
'src'] );
683 $lessVars[
'logo-wordmark-width' ] = intval( $logo[
'width'] );
684 $lessVars[
'logo-wordmark-height' ] = intval( $logo[
'height'] );
686 $lessVars[
'logo-enabled' ] =
false;
692 $summary = parent::getDefinitionSummary( $context );
694 'logos' => self::getAvailableLogos( $this->getConfig() ),
if(ini_get('mbstring.func_overload')) if(!defined('MW_ENTRY_POINT'))
Pre-config setup: Before loading LocalSettings.php.
Exceptions for config failures.
Context object that contains information about the state of a specific ResourceLoader web request.
string $localBasePath
Local base path, see __construct()
static extractBasePaths(array $options=[], $localBasePath=null, $remoteBasePath=null)
Extract a pair of local and remote base paths from module definition information.
array $messages
List of message keys used by this module.
string $remoteBasePath
Remote base path, see __construct()
An object to represent a path to a JavaScript/CSS file, along with a remote and local base path,...
Module augmented with context-specific LESS variables.
Module for skin stylesheets.
const FEATURE_FILES
Every skin should define which features it would like to reuse for core inside a ResourceLoader modul...
static getRelativeSizedLogo(array $logoElement)
Modifies configured logo width/height to ensure they are present and scaleable with different font-si...
$targets
All skins are assumed to be compatible with mobile.
normalizeStyles(array &$styles)
Ensure all media keys use array values.
getDefinitionSummary(ResourceLoaderContext $context)
Get the definition summary for this module.
getStyleFiles(ResourceLoaderContext $context)
Get styles defined in the module definition, plus any enabled feature styles.
getStyles(ResourceLoaderContext $context)
getPreloadLinks(ResourceLoaderContext $context)
getLessVars(ResourceLoaderContext $context)
Get language-specific LESS variables for this module.
static getAvailableLogos( $conf)
Return an array of all available logos that a skin may use.
isKnownEmpty(ResourceLoaderContext $context)
getLogoData(Config $conf)
getLogoPreloadlinks()
Helper method for getPreloadLinks()
__construct(array $options=[], $localBasePath=null, $remoteBasePath=null)
static applyFeaturesCompatibility(array $features, &$messages='')
Interface for configuration instances.