+ # Class bloat
+ $dir = wfUILang()->getDir();
+ $bodyAttrs['class'] = "mediawiki $dir";
+
+ if ( $wgLang->capitalizeAllNouns() ) {
+ # A <body> class is probably not the best way to do this . . .
+ $bodyAttrs['class'] .= ' capitalize-all-nouns';
+ }
+ $bodyAttrs['class'] .= ' ns-' . $this->getTitle()->getNamespace();
+ if ( $this->getTitle()->getNamespace() == NS_SPECIAL ) {
+ $bodyAttrs['class'] .= ' ns-special';
+ } elseif ( $this->getTitle()->isTalkPage() ) {
+ $bodyAttrs['class'] .= ' ns-talk';
+ } else {
+ $bodyAttrs['class'] .= ' ns-subject';
+ }
+ $bodyAttrs['class'] .= ' ' . Sanitizer::escapeClass( 'page-' . $this->getTitle()->getPrefixedText() );
+ $bodyAttrs['class'] .= ' skin-' . Sanitizer::escapeClass( $wgUser->getSkin()->getSkinName() );
+
+ $ret .= Html::openElement( 'body', $bodyAttrs ) . "\n";
+
+ return $ret;
+ }
+
+ static function makeResourceLoaderLink( $skin, $modules, $only ) {
+ global $wgUser, $wgLang, $wgRequest, $wgLoadScript;
+ // TODO: Should this be a static function of ResourceLoader instead?
+ // TODO: Divide off modules starting with "user", and add the user parameter to them
+ $query = array(
+ 'lang' => $wgLang->getCode(),
+ 'debug' => ( $wgRequest->getBool( 'debug' ) && $wgRequest->getVal( 'debug' ) == 'true' ) ? 'true' : 'false',
+ 'skin' => $wgUser->getSkin()->getSkinName(),
+ 'only' => $only,
+ );
+ $moduleGroups = array( null => array(), 'user' => array() );
+ foreach ( (array) $modules as $name ) {
+ $moduleGroups[strpos( $name, 'user' ) === 0 ? 'user' : null][] = $name;
+ }
+ $links = '';
+ foreach ( $moduleGroups as $group => $modules ) {
+ if ( count( $modules ) ) {
+ sort( $modules );
+ $query['modules'] = implode( '|', array_unique( (array) $modules ) );
+ if ( $group === 'user' && $wgUser->isLoggedIn() ) {
+ $query['user'] = $wgUser->getName();
+ }
+ // Users might change their stuff on-wiki like site or user pages, or user preferences; we need to find
+ // the highest timestamp of these user-changable modules so we can ensure cache misses upon change
+ $timestamp = 0;
+ foreach ( $modules as $name ) {
+ $module = ResourceLoader::getModule( $name );
+ if (
+ $module instanceof ResourceLoaderWikiModule ||
+ $module instanceof ResourceLoaderUserPreferencesModule
+ ) {
+ $timestamp = max(
+ $timestamp,
+ $module->getModifiedTime( new ResourceLoaderContext( new FauxRequest( $query ) ) )
+ );
+ }
+ }
+ // Add a version parameter if any of the modules were user-changable
+ if ( $timestamp ) {
+ $query['version'] = wfTimestamp( TS_ISO_8601, round( $timestamp, -2 ) );
+ }
+ // Make queries uniform in order
+ ksort( $query );
+ // Automatically select style/script elements
+ if ( $only === 'styles' ) {
+ $links .= Html::linkedStyle( wfAppendQuery( $wgLoadScript, $query ) );
+ } else {
+ $links .= Html::linkedScript( wfAppendQuery( $wgLoadScript, $query ) );
+ }
+ }
+ }
+ return $links;
+ }
+
+ /**
+ * Gets the global variables and mScripts; also adds userjs to the end if
+ * enabled. Despite the name, these scripts are no longer put in the
+ * <head> but at the bottom of the <body>
+ *
+ * @param $sk Skin object to use
+ * @return String: HTML fragment
+ */
+ function getHeadScripts( Skin $sk ) {
+ global $wgUser, $wgRequest;
+ global $wgUseSiteJs;
+
+ // Statup - this will immediately load jquery and mediawiki modules
+ $scripts = self::makeResourceLoaderLink( $sk, 'startup', 'scripts' );
+
+ // Configuration -- This could be merged together with the load and go, but makeGlobalVariablesScript returns a
+ // whole script tag -- grumble grumble...
+ $scripts .= Skin::makeGlobalVariablesScript( $sk->getSkinName() ) . "\n";
+
+ // Script and Messages "only"
+ if ( $wgRequest->getBool( 'debug' ) && $wgRequest->getVal( 'debug' ) !== 'false' ) {
+ // Scripts
+ foreach ( $this->getModuleScripts() as $name ) {
+ $scripts .= self::makeResourceLoaderLink( $sk, $name, 'scripts' );
+ }
+ // Messages
+ foreach ( $this->getModuleMessages() as $name ) {
+ $scripts .= self::makeResourceLoaderLink( $sk, $name, 'messages' );
+ }
+ } else {
+ // Scripts
+ if ( count( $this->getModuleScripts() ) ) {
+ $scripts .= self::makeResourceLoaderLink( $sk, $this->getModuleScripts(), 'scripts' );
+ }
+ // Messages
+ if ( count( $this->getModuleMessages() ) ) {
+ $scripts .= self::makeResourceLoaderLink( $sk, $this->getModuleMessages(), 'messages' );
+ }
+ }
+
+ // Modules - let the client calculate dependencies and batch requests as it likes
+ if ( $this->getModules() ) {
+ $modules = FormatJson::encode( $this->getModules() );
+ $scripts .= Html::inlineScript(
+ "if ( mediaWiki !== undefined ) { mediaWiki.loader.load( {$modules} ); mediaWiki.loader.go(); }"
+ );
+ }
+
+ // Add user JS if enabled - trying to load user.options as a bundle if possible
+ $userOptionsAdded = false;
+ if ( $this->isUserJsAllowed() && $wgUser->isLoggedIn() ) {