From 57310ab838072148455c805a0a5c8bb64b6b0aba Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Thu, 9 Feb 2012 11:04:24 +0000 Subject: [PATCH] (bug 34289) user.options CSS loaded twice. Fixed by splitting off the CSS part of user.options into a separate module (user.cssprefs), as per the fixme comment added in r93363. No RELEASE-NOTEs because this is a regression fix that I'm gonna tag for backporting to 1.19 --- includes/AutoLoader.php | 1 + includes/OutputPage.php | 4 +- .../ResourceLoaderUserCSSPrefsModule.php | 136 ++++++++++++++++++ .../ResourceLoaderUserOptionsModule.php | 52 ------- resources/Resources.php | 1 + 5 files changed, 141 insertions(+), 53 deletions(-) create mode 100644 includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 9e9befde89..a55dd1e3b6 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -724,6 +724,7 @@ $wgAutoloadLocalClasses = array( 'ResourceLoaderNoscriptModule' => 'includes/resourceloader/ResourceLoaderNoscriptModule.php', 'ResourceLoaderSiteModule' => 'includes/resourceloader/ResourceLoaderSiteModule.php', 'ResourceLoaderStartUpModule' => 'includes/resourceloader/ResourceLoaderStartUpModule.php', + 'ResourceLoaderUserCSSPrefsModule' => 'includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php', 'ResourceLoaderUserGroupsModule' => 'includes/resourceloader/ResourceLoaderUserGroupsModule.php', 'ResourceLoaderUserModule' => 'includes/resourceloader/ResourceLoaderUserModule.php', 'ResourceLoaderUserOptionsModule' => 'includes/resourceloader/ResourceLoaderUserOptionsModule.php', diff --git a/includes/OutputPage.php b/includes/OutputPage.php index cc9118af52..b42732b558 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -2681,6 +2681,8 @@ $templates ); // Load embeddable private modules before any loader links + // This needs to be TYPE_COMBINED so these modules are properly wrapped + // in mw.loader.implement() calls and deferred until mw.user is available $embedScripts = array( 'user.options', 'user.tokens' ); $scripts .= $this->makeResourceLoaderLink( $embedScripts, ResourceLoaderModule::TYPE_COMBINED ); @@ -3268,7 +3270,7 @@ $templates // Per-user preference styles if ( $wgAllowUserCssPrefs ) { - $moduleStyles[] = 'user.options'; + $moduleStyles[] = 'user.cssprefs'; } foreach ( $moduleStyles as $name ) { diff --git a/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php b/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php new file mode 100644 index 0000000000..b5a24354e0 --- /dev/null +++ b/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php @@ -0,0 +1,136 @@ +getHash(); + if ( isset( $this->modifiedTime[$hash] ) ) { + return $this->modifiedTime[$hash]; + } + + global $wgUser; + + if ( $context->getUser() === $wgUser->getName() ) { + return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() ); + } else { + return 1; + } + } + + /** + * Fetch the context's user options, or if it doesn't match current user, + * the default options. + * + * @param $context ResourceLoaderContext: Context object + * @return Array: List of user options keyed by option name + */ + protected function contextUserOptions( ResourceLoaderContext $context ) { + global $wgUser; + + // Verify identity -- this is a private module + if ( $context->getUser() === $wgUser->getName() ) { + return $wgUser->getOptions(); + } else { + return User::getDefaultOptions(); + } + } + + /** + * @param $context ResourceLoaderContext + * @return array + */ + public function getStyles( ResourceLoaderContext $context ) { + global $wgAllowUserCssPrefs; + + if ( $wgAllowUserCssPrefs ) { + $options = $this->contextUserOptions( $context ); + + // Build CSS rules + $rules = array(); + + // Underline: 2 = browser default, 1 = always, 0 = never + if ( $options['underline'] < 2 ) { + $rules[] = "a { text-decoration: " . + ( $options['underline'] ? 'underline' : 'none' ) . "; }"; + } else { + # The scripts of these languages are very hard to read with underlines + $rules[] = 'a:lang(ar), a:lang(ckb), a:lang(fa),a:lang(kk-arab), ' . + 'a:lang(mzn), a:lang(ps), a:lang(ur) { text-decoration: none; }'; + } + if ( $options['highlightbroken'] ) { + $rules[] = "a.new, #quickbar a.new { color: #ba0000; }\n"; + } else { + $rules[] = "a.new, #quickbar a.new, a.stub, #quickbar a.stub { color: inherit; }"; + $rules[] = "a.new:after, #quickbar a.new:after { content: '?'; color: #ba0000; }"; + $rules[] = "a.stub:after, #quickbar a.stub:after { content: '!'; color: #772233; }"; + } + if ( $options['justify'] ) { + $rules[] = "#article, #bodyContent, #mw_content { text-align: justify; }\n"; + } + if ( !$options['showtoc'] ) { + $rules[] = "#toc { display: none; }\n"; + } + if ( !$options['editsection'] ) { + $rules[] = ".editsection { display: none; }\n"; + } + if ( $options['editfont'] !== 'default' ) { + $rules[] = "textarea { font-family: {$options['editfont']}; }\n"; + } + $style = implode( "\n", $rules ); + if ( $this->getFlip( $context ) ) { + $style = CSSJanus::transform( $style, true, false ); + } + return array( 'all' => $style ); + } + return array(); + } + + /** + * @return string + */ + public function getGroup() { + return 'private'; + } + + /** + * @return array + */ + public function getDependencies() { + return array( 'mediawiki.user' ); + } +} diff --git a/includes/resourceloader/ResourceLoaderUserOptionsModule.php b/includes/resourceloader/ResourceLoaderUserOptionsModule.php index 4462abead1..0752fd6b98 100644 --- a/includes/resourceloader/ResourceLoaderUserOptionsModule.php +++ b/includes/resourceloader/ResourceLoaderUserOptionsModule.php @@ -79,58 +79,6 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule { array( $this->contextUserOptions( $context ) ) ); } - /** - * @param $context ResourceLoaderContext - * @return array - */ - public function getStyles( ResourceLoaderContext $context ) { - // FIXME: This stuff should really be in its own module, because it gets double-loaded otherwise - // (once through a , once when embedded as JS) - global $wgAllowUserCssPrefs; - - if ( $wgAllowUserCssPrefs ) { - $options = $this->contextUserOptions( $context ); - - // Build CSS rules - $rules = array(); - - // Underline: 2 = browser default, 1 = always, 0 = never - if ( $options['underline'] < 2 ) { - $rules[] = "a { text-decoration: " . - ( $options['underline'] ? 'underline' : 'none' ) . "; }"; - } else { - # The scripts of these languages are very hard to read with underlines - $rules[] = 'a:lang(ar), a:lang(ckb), a:lang(fa),a:lang(kk-arab), ' . - 'a:lang(mzn), a:lang(ps), a:lang(ur) { text-decoration: none; }'; - } - if ( $options['highlightbroken'] ) { - $rules[] = "a.new, #quickbar a.new { color: #ba0000; }\n"; - } else { - $rules[] = "a.new, #quickbar a.new, a.stub, #quickbar a.stub { color: inherit; }"; - $rules[] = "a.new:after, #quickbar a.new:after { content: '?'; color: #ba0000; }"; - $rules[] = "a.stub:after, #quickbar a.stub:after { content: '!'; color: #772233; }"; - } - if ( $options['justify'] ) { - $rules[] = "#article, #bodyContent, #mw_content { text-align: justify; }\n"; - } - if ( !$options['showtoc'] ) { - $rules[] = "#toc { display: none; }\n"; - } - if ( !$options['editsection'] ) { - $rules[] = ".editsection { display: none; }\n"; - } - if ( $options['editfont'] !== 'default' ) { - $rules[] = "textarea { font-family: {$options['editfont']}; }\n"; - } - $style = implode( "\n", $rules ); - if ( $this->getFlip( $context ) ) { - $style = CSSJanus::transform( $style, true, false ); - } - return array( 'all' => $style ); - } - return array(); - } - /** * @return string */ diff --git a/resources/Resources.php b/resources/Resources.php index 464f75149e..4f3f3c509d 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -10,6 +10,7 @@ return array( 'user' => array( 'class' => 'ResourceLoaderUserModule' ), 'user.groups' => array( 'class' => 'ResourceLoaderUserGroupsModule' ), 'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ), + 'user.cssprefs' => array( 'class' => 'ResourceLoaderUserCSSPrefsModule' ), 'user.tokens' => array( 'class' => 'ResourceLoaderUserTokensModule' ), 'filepage' => array( 'class' => 'ResourceLoaderFilePageModule' ), -- 2.20.1