*/
use MediaWiki\MediaWikiServices;
+use Wikimedia\WrappedString;
+use Wikimedia\WrappedStringList;
/**
* @defgroup Skins Skins
public function getDefaultModules() {
$out = $this->getOutput();
$config = $this->getConfig();
- $user = $out->getUser();
+ $user = $this->getUser();
+
+ // Modules declared in the $modules literal are loaded
+ // for ALL users, on ALL pages, in ALL skins.
+ // Keep this list as small as possible!
$modules = [
- // Styles key sets render blocking styles
- // Unlike other keys in this definition it is an associative array
- // where each key is the group name and points to a list of modules
'styles' => [
+ // The 'styles' key sets render-blocking style modules
+ // Unlike other keys in $modules, this is an associative array
+ // where each key is its own group pointing to a list of modules
+ 'core' => [
+ 'mediawiki.legacy.shared',
+ 'mediawiki.legacy.commonPrint',
+ ],
'content' => [],
+ 'syndicate' => [],
],
- // modules not specific to any specific skin or page
'core' => [
- // Enforce various default modules for all pages and all skins
- // Keep this list as small as possible
'site',
'mediawiki.page.startup',
'mediawiki.user',
],
- // modules that enhance the page content in some way
+ // modules that enhance the content in some way
'content' => [
'mediawiki.page.ready',
],
'watch' => [],
// modules which relate to the current users preferences
'user' => [],
+ // modules relating to RSS/Atom Feeds
+ 'syndicate' => [],
];
// Support for high-density display images if enabled
$modules['styles']['content'][] = 'jquery.makeCollapsible.styles';
}
+ // Deprecated since 1.26: Unconditional loading of mediawiki.ui.button
+ // on every page is deprecated. Express a dependency instead.
+ if ( strpos( $out->getHTML(), 'mw-ui-button' ) !== false ) {
+ $modules['styles']['content'][] = 'mediawiki.ui.button';
+ }
+
if ( $out->isTOCEnabled() ) {
$modules['content'][] = 'mediawiki.toc';
}
if ( $out->isArticle() && $user->getOption( 'editondblclick' ) ) {
$modules['user'][] = 'mediawiki.action.view.dblClickEdit';
}
+
+ if ( $out->isSyndicated() ) {
+ $modules['styles']['syndicate'][] = 'mediawiki.feedlink';
+ }
+
return $modules;
}
/**
* @param array $data
- * @return string
+ * @param string $nonce OutputPage::getCSPNonce()
+ * @return string|WrappedString HTML
*/
- static function makeVariablesScript( $data ) {
+ static function makeVariablesScript( $data, $nonce = null ) {
if ( $data ) {
return ResourceLoader::makeInlineScript(
- ResourceLoader::makeConfigSetScript( $data )
+ ResourceLoader::makeConfigSetScript( $data ),
+ $nonce
);
} else {
return '';
}
/**
- * Add skin specific stylesheets
- * Calling this method with an $out of anything but the same OutputPage
- * inside ->getOutput() is deprecated. The $out arg is kept
- * for compatibility purposes with skins.
- * @param OutputPage $out
- * @todo delete
+ * Hook point for adding style modules to OutputPage.
+ *
+ * @deprecated since 1.32 Use getDefaultModules() instead.
+ * @param OutputPage $out Legacy parameter, identical to $this->getOutput()
*/
- abstract function setupSkinUserCss( OutputPage $out );
+ public function setupSkinUserCss( OutputPage $out ) {
+ // Stub.
+ }
/**
* TODO: document
/**
* This gets called shortly before the "</body>" tag.
*
- * @return string HTML-wrapped JS code to be put before "</body>"
+ * @return string|WrappedStringList HTML containing scripts to put before `</body>`
*/
function bottomScripts() {
// TODO and the suckage continues. This function is really just a wrapper around
// OutputPage::getBottomScripts() which takes a Skin param. This should be cleaned
// up at some point
- $bottomScriptText = $this->getOutput()->getBottomScripts();
- Hooks::run( 'SkinAfterBottomScripts', [ $this, &$bottomScriptText ] );
-
- return $bottomScriptText;
+ $chunks = [ $this->getOutput()->getBottomScripts() ];
+
+ // Keep the hook appendage separate to preserve WrappedString objects.
+ // This enables BaseTemplate::getTrail() to merge them where possible.
+ $extraHtml = '';
+ Hooks::run( 'SkinAfterBottomScripts', [ $this, &$extraHtml ] );
+ if ( $extraHtml !== '' ) {
+ $chunks[] = $extraHtml;
+ }
+ return WrappedString::join( "\n", $chunks );
}
/**
if ( is_string( $icon ) ) {
$html = $icon;
} else { // Assuming array
- $url = isset( $icon["url"] ) ? $icon["url"] : null;
+ $url = $icon["url"] ?? null;
unset( $icon["url"] );
if ( isset( $icon["src"] ) && $withImage === 'withImage' ) {
// do this the lazy way, just pass icon data as an attribute array
}
/**
- * Return a fully resolved style path url to images or styles stored in the current skins's folder.
- * This method returns a url resolved using the configured skin style path
- * and includes the style version inside of the url.
+ * Return a fully resolved style path URL to images or styles stored in the
+ * current skin's folder. This method returns a URL resolved using the
+ * configured skin style path.
*
* Requires $stylename to be set, otherwise throws MWException.
*
* @param string $name The name or path of a skin resource file
- * @return string The fully resolved style path url including styleversion
+ * @return string The fully resolved style path URL
* @throws MWException
*/
function getSkinStylePath( $name ) {
- global $wgStylePath, $wgStyleVersion;
+ global $wgStylePath;
if ( $this->stylename === null ) {
$class = static::class;
throw new MWException( "$class::\$stylename must be set to use getSkinStylePath()" );
}
- return "$wgStylePath/{$this->stylename}/$name?$wgStyleVersion";
+ return "$wgStylePath/{$this->stylename}/$name";
}
/* these are used extensively in SkinTemplate, but also some other places */
if ( count( $newtalks ) == 1 && $newtalks[0]['wiki'] === wfWikiID() ) {
$uTalkTitle = $user->getTalkPage();
- $lastSeenRev = isset( $newtalks[0]['rev'] ) ? $newtalks[0]['rev'] : null;
+ $lastSeenRev = $newtalks[0]['rev'] ?? null;
$nofAuthors = 0;
if ( $lastSeenRev !== null ) {
$plural = true; // Default if we have a last seen revision: if unknown, use plural