r111175 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r111174‎ | r111175 | r111176 >
Date:18:37, 10 February 2012
Author:reedy
Status:ok
Tags:
Comment:
Modified paths:
  • /branches/REL1_19/phase3 (modified) (history)
  • /branches/REL1_19/phase3/RELEASE-NOTES-1.19 (modified) (history)
  • /branches/REL1_19/phase3/includes (modified) (history)
  • /branches/REL1_19/phase3/includes/AutoLoader.php (modified) (history)
  • /branches/REL1_19/phase3/includes/OutputPage.php (modified) (history)
  • /branches/REL1_19/phase3/includes/User.php (modified) (history)
  • /branches/REL1_19/phase3/includes/filerepo/backend/TempFSFile.php (modified) (history)
  • /branches/REL1_19/phase3/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php (added) (history)
  • /branches/REL1_19/phase3/includes/resourceloader/ResourceLoaderUserOptionsModule.php (modified) (history)
  • /branches/REL1_19/phase3/includes/specials (modified) (history)
  • /branches/REL1_19/phase3/includes/specials/SpecialEditWatchlist.php (modified) (history)
  • /branches/REL1_19/phase3/resources/Resources.php (modified) (history)
  • /branches/REL1_19/phase3/resources/mediawiki/mediawiki.js (modified) (history)
  • /branches/REL1_19/phase3/thumb.php (modified) (history)

Diff [purge]

Index: branches/REL1_19/phase3/RELEASE-NOTES-1.19
@@ -246,6 +246,7 @@
247247 getText() on a non-object
248248 * (bug 31676) Group dynamically inserted CSS into a single <style> tag, to work
249249 around a bug where not all styles were applied in Internet Explorer
 250+* (bug 28936, bug 5280) Broken or invalid titles can't be removed from watchlist.
250251
251252 === API changes in 1.19 ===
252253 * Made action=edit less likely to return "unknownerror", by returning the actual error
Index: branches/REL1_19/phase3/includes/User.php
@@ -2602,14 +2602,6 @@
26032603 }
26042604
26052605 /**
2606 - * Cleans up watchlist by removing invalid entries from it
2607 - */
2608 - public function cleanupWatchlist() {
2609 - $dbw = wfGetDB( DB_MASTER );
2610 - $dbw->delete( 'watchlist', array( 'wl_namespace < 0', 'wl_user' => $this->getId() ), __METHOD__ );
2611 - }
2612 -
2613 - /**
26142606 * Clear the user's notification timestamp for the given title.
26152607 * If e-notif e-mails are on, they will receive notification mails on
26162608 * the next change of the page if it's watched etc.
Index: branches/REL1_19/phase3/includes/filerepo/backend/TempFSFile.php
@@ -41,9 +41,6 @@
4242 }
4343 }
4444 $tmpFile = new self( $path );
45 - if ( php_sapi_name() != 'cli' ) {
46 - self::$instances[] = $tmpFile; // defer purge till shutdown
47 - }
4845 return $tmpFile;
4946 }
5047
Index: branches/REL1_19/phase3/includes/OutputPage.php
@@ -2681,6 +2681,8 @@
26822682 );
26832683
26842684 // Load embeddable private modules before any loader links
 2685+ // This needs to be TYPE_COMBINED so these modules are properly wrapped
 2686+ // in mw.loader.implement() calls and deferred until mw.user is available
26852687 $embedScripts = array( 'user.options', 'user.tokens' );
26862688 $scripts .= $this->makeResourceLoaderLink( $embedScripts, ResourceLoaderModule::TYPE_COMBINED );
26872689
@@ -3268,7 +3270,7 @@
32693271
32703272 // Per-user preference styles
32713273 if ( $wgAllowUserCssPrefs ) {
3272 - $moduleStyles[] = 'user.options';
 3274+ $moduleStyles[] = 'user.cssprefs';
32733275 }
32743276
32753277 foreach ( $moduleStyles as $name ) {
Property changes on: branches/REL1_19/phase3/includes/OutputPage.php
___________________________________________________________________
Modified: svn:mergeinfo
32763278 Merged /trunk/phase3/includes/OutputPage.php:r111029,111034,111067,111085,111128,111144
Index: branches/REL1_19/phase3/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php
@@ -0,0 +1,136 @@
 2+<?php
 3+/**
 4+ * This program is free software; you can redistribute it and/or modify
 5+ * it under the terms of the GNU General Public License as published by
 6+ * the Free Software Foundation; either version 2 of the License, or
 7+ * (at your option) any later version.
 8+ *
 9+ * This program is distributed in the hope that it will be useful,
 10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 12+ * GNU General Public License for more details.
 13+ *
 14+ * You should have received a copy of the GNU General Public License along
 15+ * with this program; if not, write to the Free Software Foundation, Inc.,
 16+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 17+ * http://www.gnu.org/copyleft/gpl.html
 18+ *
 19+ * @file
 20+ * @author Trevor Parscal
 21+ * @author Roan Kattouw
 22+ */
 23+
 24+/**
 25+ * Module for user preference customizations
 26+ */
 27+class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule {
 28+
 29+ /* Protected Members */
 30+
 31+ protected $modifiedTime = array();
 32+
 33+ protected $origin = self::ORIGIN_CORE_INDIVIDUAL;
 34+
 35+ /* Methods */
 36+
 37+ /**
 38+ * @param $context ResourceLoaderContext
 39+ * @return array|int|Mixed
 40+ */
 41+ public function getModifiedTime( ResourceLoaderContext $context ) {
 42+ $hash = $context->getHash();
 43+ if ( isset( $this->modifiedTime[$hash] ) ) {
 44+ return $this->modifiedTime[$hash];
 45+ }
 46+
 47+ global $wgUser;
 48+
 49+ if ( $context->getUser() === $wgUser->getName() ) {
 50+ return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() );
 51+ } else {
 52+ return 1;
 53+ }
 54+ }
 55+
 56+ /**
 57+ * Fetch the context's user options, or if it doesn't match current user,
 58+ * the default options.
 59+ *
 60+ * @param $context ResourceLoaderContext: Context object
 61+ * @return Array: List of user options keyed by option name
 62+ */
 63+ protected function contextUserOptions( ResourceLoaderContext $context ) {
 64+ global $wgUser;
 65+
 66+ // Verify identity -- this is a private module
 67+ if ( $context->getUser() === $wgUser->getName() ) {
 68+ return $wgUser->getOptions();
 69+ } else {
 70+ return User::getDefaultOptions();
 71+ }
 72+ }
 73+
 74+ /**
 75+ * @param $context ResourceLoaderContext
 76+ * @return array
 77+ */
 78+ public function getStyles( ResourceLoaderContext $context ) {
 79+ global $wgAllowUserCssPrefs;
 80+
 81+ if ( $wgAllowUserCssPrefs ) {
 82+ $options = $this->contextUserOptions( $context );
 83+
 84+ // Build CSS rules
 85+ $rules = array();
 86+
 87+ // Underline: 2 = browser default, 1 = always, 0 = never
 88+ if ( $options['underline'] < 2 ) {
 89+ $rules[] = "a { text-decoration: " .
 90+ ( $options['underline'] ? 'underline' : 'none' ) . "; }";
 91+ } else {
 92+ # The scripts of these languages are very hard to read with underlines
 93+ $rules[] = 'a:lang(ar), a:lang(ckb), a:lang(fa),a:lang(kk-arab), ' .
 94+ 'a:lang(mzn), a:lang(ps), a:lang(ur) { text-decoration: none; }';
 95+ }
 96+ if ( $options['highlightbroken'] ) {
 97+ $rules[] = "a.new, #quickbar a.new { color: #ba0000; }\n";
 98+ } else {
 99+ $rules[] = "a.new, #quickbar a.new, a.stub, #quickbar a.stub { color: inherit; }";
 100+ $rules[] = "a.new:after, #quickbar a.new:after { content: '?'; color: #ba0000; }";
 101+ $rules[] = "a.stub:after, #quickbar a.stub:after { content: '!'; color: #772233; }";
 102+ }
 103+ if ( $options['justify'] ) {
 104+ $rules[] = "#article, #bodyContent, #mw_content { text-align: justify; }\n";
 105+ }
 106+ if ( !$options['showtoc'] ) {
 107+ $rules[] = "#toc { display: none; }\n";
 108+ }
 109+ if ( !$options['editsection'] ) {
 110+ $rules[] = ".editsection { display: none; }\n";
 111+ }
 112+ if ( $options['editfont'] !== 'default' ) {
 113+ $rules[] = "textarea { font-family: {$options['editfont']}; }\n";
 114+ }
 115+ $style = implode( "\n", $rules );
 116+ if ( $this->getFlip( $context ) ) {
 117+ $style = CSSJanus::transform( $style, true, false );
 118+ }
 119+ return array( 'all' => $style );
 120+ }
 121+ return array();
 122+ }
 123+
 124+ /**
 125+ * @return string
 126+ */
 127+ public function getGroup() {
 128+ return 'private';
 129+ }
 130+
 131+ /**
 132+ * @return array
 133+ */
 134+ public function getDependencies() {
 135+ return array( 'mediawiki.user' );
 136+ }
 137+}
Property changes on: branches/REL1_19/phase3/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php
___________________________________________________________________
Added: svn:eol-style
1138 + native
Index: branches/REL1_19/phase3/includes/resourceloader/ResourceLoaderUserOptionsModule.php
@@ -80,58 +80,6 @@
8181 }
8282
8383 /**
84 - * @param $context ResourceLoaderContext
85 - * @return array
86 - */
87 - public function getStyles( ResourceLoaderContext $context ) {
88 - // FIXME: This stuff should really be in its own module, because it gets double-loaded otherwise
89 - // (once through a <link>, once when embedded as JS)
90 - global $wgAllowUserCssPrefs;
91 -
92 - if ( $wgAllowUserCssPrefs ) {
93 - $options = $this->contextUserOptions( $context );
94 -
95 - // Build CSS rules
96 - $rules = array();
97 -
98 - // Underline: 2 = browser default, 1 = always, 0 = never
99 - if ( $options['underline'] < 2 ) {
100 - $rules[] = "a { text-decoration: " .
101 - ( $options['underline'] ? 'underline' : 'none' ) . "; }";
102 - } else {
103 - # The scripts of these languages are very hard to read with underlines
104 - $rules[] = 'a:lang(ar), a:lang(ckb), a:lang(fa),a:lang(kk-arab), ' .
105 - 'a:lang(mzn), a:lang(ps), a:lang(ur) { text-decoration: none; }';
106 - }
107 - if ( $options['highlightbroken'] ) {
108 - $rules[] = "a.new, #quickbar a.new { color: #ba0000; }\n";
109 - } else {
110 - $rules[] = "a.new, #quickbar a.new, a.stub, #quickbar a.stub { color: inherit; }";
111 - $rules[] = "a.new:after, #quickbar a.new:after { content: '?'; color: #ba0000; }";
112 - $rules[] = "a.stub:after, #quickbar a.stub:after { content: '!'; color: #772233; }";
113 - }
114 - if ( $options['justify'] ) {
115 - $rules[] = "#article, #bodyContent, #mw_content { text-align: justify; }\n";
116 - }
117 - if ( !$options['showtoc'] ) {
118 - $rules[] = "#toc { display: none; }\n";
119 - }
120 - if ( !$options['editsection'] ) {
121 - $rules[] = ".editsection { display: none; }\n";
122 - }
123 - if ( $options['editfont'] !== 'default' ) {
124 - $rules[] = "textarea { font-family: {$options['editfont']}; }\n";
125 - }
126 - $style = implode( "\n", $rules );
127 - if ( $this->getFlip( $context ) ) {
128 - $style = CSSJanus::transform( $style, true, false );
129 - }
130 - return array( 'all' => $style );
131 - }
132 - return array();
133 - }
134 -
135 - /**
13684 * @return string
13785 */
13886 public function getGroup() {
Index: branches/REL1_19/phase3/includes/AutoLoader.php
@@ -720,6 +720,7 @@
721721 'ResourceLoaderNoscriptModule' => 'includes/resourceloader/ResourceLoaderNoscriptModule.php',
722722 'ResourceLoaderSiteModule' => 'includes/resourceloader/ResourceLoaderSiteModule.php',
723723 'ResourceLoaderStartUpModule' => 'includes/resourceloader/ResourceLoaderStartUpModule.php',
 724+ 'ResourceLoaderUserCSSPrefsModule' => 'includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php',
724725 'ResourceLoaderUserGroupsModule' => 'includes/resourceloader/ResourceLoaderUserGroupsModule.php',
725726 'ResourceLoaderUserModule' => 'includes/resourceloader/ResourceLoaderUserModule.php',
726727 'ResourceLoaderUserOptionsModule' => 'includes/resourceloader/ResourceLoaderUserOptionsModule.php',
Property changes on: branches/REL1_19/phase3/includes/AutoLoader.php
___________________________________________________________________
Modified: svn:mergeinfo
727728 Merged /trunk/phase3/includes/AutoLoader.php:r111029,111034,111067,111085,111128,111144
Index: branches/REL1_19/phase3/includes/specials/SpecialEditWatchlist.php
@@ -20,6 +20,8 @@
2121
2222 protected $toc;
2323
 24+ private $badItems = array();
 25+
2426 public function __construct(){
2527 parent::__construct( 'EditWatchlist' );
2628 }
@@ -221,11 +223,15 @@
222224 if( $res->numRows() > 0 ) {
223225 foreach ( $res as $row ) {
224226 $title = Title::makeTitleSafe( $row->wl_namespace, $row->wl_title );
225 - if( $title instanceof Title && !$title->isTalkPage() )
 227+ if ( $this->checkTitle( $title, $row->wl_namespace, $row->wl_title )
 228+ && !$title->isTalkPage()
 229+ ) {
226230 $list[] = $title->getPrefixedText();
 231+ }
227232 }
228233 $res->free();
229234 }
 235+ $this->cleanupWatchlist();
230236 return $list;
231237 }
232238
@@ -260,6 +266,60 @@
261267 }
262268
263269 /**
 270+ * Validates watchlist entry
 271+ *
 272+ * @param Title $title
 273+ * @param int $namespace
 274+ * @param String $dbKey
 275+ * @return bool: Whether this item is valid
 276+ */
 277+ private function checkTitle( $title, $namespace, $dbKey ) {
 278+ if ( $title
 279+ && ( $title->isExternal()
 280+ || $title->getNamespace() < 0
 281+ )
 282+ ) {
 283+ $title = false; // unrecoverable
 284+ }
 285+ if ( !$title
 286+ || $title->getNamespace() != $namespace
 287+ || $title->getDBkey() != $dbKey
 288+ ) {
 289+ $this->badItems[] = array( $title, $namespace, $dbKey );
 290+ }
 291+ return (bool)$title;
 292+ }
 293+
 294+ /**
 295+ * Attempts to clean up broken items
 296+ */
 297+ private function cleanupWatchlist() {
 298+ if ( count( $this->badItems ) ) {
 299+ $dbw = wfGetDB( DB_MASTER );
 300+ }
 301+ foreach ( $this->badItems as $row ) {
 302+ list( $title, $namespace, $dbKey ) = $row;
 303+ wfDebug( "User {$this->getUser()} has broken watchlist item ns($namespace):$dbKey, "
 304+ . ( $title ? 'cleaning up' : 'deleting' ) . ".\n"
 305+ );
 306+
 307+ $dbw->delete( 'watchlist',
 308+ array(
 309+ 'wl_user' => $this->getUser()->getId(),
 310+ 'wl_namespace' => $namespace,
 311+ 'wl_title' => $dbKey,
 312+ ),
 313+ __METHOD__
 314+ );
 315+
 316+ // Can't just do an UPDATE instead of DELETE/INSERT due to unique index
 317+ if ( $title ) {
 318+ $this->getUser()->addWatch( $title );
 319+ }
 320+ }
 321+ }
 322+
 323+ /**
264324 * Remove all titles from a user's watchlist
265325 */
266326 private function clearWatchlist() {
@@ -372,30 +432,25 @@
373433 $fields = array();
374434 $count = 0;
375435
376 - $haveInvalidNamespaces = false;
377436 foreach( $this->getWatchlistInfo() as $namespace => $pages ){
378 - if ( $namespace < 0 ) {
379 - $haveInvalidNamespaces = true;
380 - continue;
 437+ if ( $namespace >= 0 ) {
 438+ $fields['TitlesNs'.$namespace] = array(
 439+ 'class' => 'EditWatchlistCheckboxSeriesField',
 440+ 'options' => array(),
 441+ 'section' => "ns$namespace",
 442+ );
381443 }
382444
383 - $fields['TitlesNs'.$namespace] = array(
384 - 'class' => 'EditWatchlistCheckboxSeriesField',
385 - 'options' => array(),
386 - 'section' => "ns$namespace",
387 - );
388 -
389445 foreach( array_keys( $pages ) as $dbkey ){
390446 $title = Title::makeTitleSafe( $namespace, $dbkey );
391 - $text = $this->buildRemoveLine( $title );
392 - $fields['TitlesNs'.$namespace]['options'][$text] = $title->getEscapedText();
393 - $count++;
 447+ if ( $this->checkTitle( $title, $namespace, $dbkey ) ) {
 448+ $text = $this->buildRemoveLine( $title );
 449+ $fields['TitlesNs'.$namespace]['options'][$text] = $title->getEscapedText();
 450+ $count++;
 451+ }
394452 }
395453 }
396 - if ( $haveInvalidNamespaces ) {
397 - wfDebug( "User {$this->getContext()->getUser()->getId()} has invalid watchlist entries, cleaning up...\n" );
398 - $this->getContext()->getUser()->cleanupWatchlist();
399 - }
 454+ $this->cleanupWatchlist();
400455
401456 if ( count( $fields ) > 1 && $count > 30 ) {
402457 $this->toc = Linker::tocIndent();
Property changes on: branches/REL1_19/phase3/includes/specials
___________________________________________________________________
Modified: svn:mergeinfo
403458 Merged /trunk/phase3/includes/specials:r111085,111128,111144
Property changes on: branches/REL1_19/phase3/includes
___________________________________________________________________
Modified: svn:mergeinfo
404459 Merged /trunk/phase3/includes:r111029,111034,111067,111085,111128,111144
Index: branches/REL1_19/phase3/thumb.php
@@ -173,6 +173,17 @@
174174 try {
175175 $thumbName = $img->thumbName( $params );
176176 if ( strlen( $thumbName ) ) { // valid params?
 177+ // For 404 handled thumbnails, we only use the the base name of the URI
 178+ // for the thumb params and the parent directory for the source file name.
 179+ // Check that the zone relative path matches up so squid caches won't pick
 180+ // up thumbs that would not be purged on source file deletion (bug 34231).
 181+ if ( isset( $params['rel404'] ) // thumbnail was handled via 404
 182+ && urldecode( $params['rel404'] ) !== $img->getThumbRel( $thumbName ) )
 183+ {
 184+ wfThumbError( 404, 'The source file for the specified thumbnail does not exist.' );
 185+ wfProfileOut( __METHOD__ );
 186+ return;
 187+ }
177188 $thumbPath = $img->getThumbPath( $thumbName );
178189 if ( $img->getRepo()->fileExists( $thumbPath ) ) {
179190 $img->getRepo()->streamFile( $thumbPath, $headers );
@@ -244,18 +255,18 @@
245256 $hashDirRegex .= "$subdirRegex/";
246257 }
247258
248 - $thumbUrlRegex = "!^$zoneUrlRegex(/archive|/temp|)/$hashDirRegex([^/]*)/([^/]*)$!";
 259+ $thumbUrlRegex = "!^$zoneUrlRegex/((archive/|temp/)?$hashDirRegex([^/]*)/([^/]*))$!";
249260
250261 // Check if this is a valid looking thumbnail request...
251262 if ( preg_match( $thumbUrlRegex, $uri, $matches ) ) {
252 - list( /* all */, $archOrTemp, $filename, $thumbname ) = $matches;
 263+ list( /* all */, $rel, $archOrTemp, $filename, $thumbname ) = $matches;
253264 $filename = urldecode( $filename );
254265 $thumbname = urldecode( $thumbname );
255266
256 - $params = array( 'f' => $filename );
257 - if ( $archOrTemp == '/archive' ) {
 267+ $params = array( 'f' => $filename, 'rel404' => $rel );
 268+ if ( $archOrTemp == 'archive/' ) {
258269 $params['archived'] = 1;
259 - } elseif ( $archOrTemp == '/temp' ) {
 270+ } elseif ( $archOrTemp == 'temp/' ) {
260271 $params['temp'] = 1;
261272 }
262273
Property changes on: branches/REL1_19/phase3/thumb.php
___________________________________________________________________
Modified: svn:mergeinfo
263274 Merged /trunk/phase3/thumb.php:r111076,111144
Index: branches/REL1_19/phase3/resources/Resources.php
@@ -10,6 +10,7 @@
1111 'user' => array( 'class' => 'ResourceLoaderUserModule' ),
1212 'user.groups' => array( 'class' => 'ResourceLoaderUserGroupsModule' ),
1313 'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ),
 14+ 'user.cssprefs' => array( 'class' => 'ResourceLoaderUserCSSPrefsModule' ),
1415 'user.tokens' => array( 'class' => 'ResourceLoaderUserTokensModule' ),
1516 'filepage' => array( 'class' => 'ResourceLoaderFilePageModule' ),
1617
@@ -824,6 +825,7 @@
825826 'mediawiki.util',
826827 'mediawiki.legacy.wikibits',
827828 ),
 829+ 'position' => 'top', // Temporary hack for legacy support
828830 ),
829831 'mediawiki.legacy.commonPrint' => array(
830832 'styles' => array( 'common/commonPrint.css' => array( 'media' => 'print' ) ),
Index: branches/REL1_19/phase3/resources/mediawiki/mediawiki.js
@@ -391,21 +391,34 @@
392392 }
393393
394394 function addInlineCSS( css, media ) {
395 - var $style = getMarker().prev();
 395+ var $style = getMarker().prev(),
 396+ $newStyle,
 397+ attrs = { 'type': 'text/css', 'media': media };
396398 if ( $style.is( 'style' ) && $style.data( 'ResourceLoaderDynamicStyleTag' ) === true ) {
397399 // There's already a dynamic <style> tag present, append to it
398400 // This recycling of <style> tags is for bug 31676 (can't have
399401 // more than 32 <style> tags in IE)
400402
401 - // Do cdata sanitization on the provided CSS, and prepend a double newline
402 - css = $( mw.html.element( 'style', {}, new mw.html.Cdata( "\n\n" + css ) ) ).html();
403 - $style.append( css );
 403+ // Also, calling .append() on a <style> tag explodes with a JS error in IE,
 404+ // so if the .append() fails we fall back to building a new <style> tag and
 405+ // replacing the existing one
 406+ try {
 407+ // Do cdata sanitization on the provided CSS, and prepend a double newline
 408+ css = $( mw.html.element( 'style', {}, new mw.html.Cdata( "\n\n" + css ) ) ).html();
 409+ $style.append( css );
 410+ } catch ( e ) {
 411+ // Generate a new tag with the combined CSS
 412+ css = $style.html() + "\n\n" + css;
 413+ $newStyle = $( mw.html.element( 'style', attrs, new mw.html.Cdata( css ) ) )
 414+ .data( 'ResourceLoaderDynamicStyleTag', true );
 415+ // Prevent a flash of unstyled content by inserting the new tag
 416+ // before removing the old one
 417+ $style.after( $newStyle );
 418+ $style.remove();
 419+ }
404420 } else {
405421 // Create a new <style> tag and insert it
406 - $style = $( mw.html.element( 'style', {
407 - 'type': 'text/css',
408 - 'media': media
409 - }, new mw.html.Cdata( css ) ) );
 422+ $style = $( mw.html.element( 'style', attrs, new mw.html.Cdata( css ) ) );
410423 $style.data( 'ResourceLoaderDynamicStyleTag', true );
411424 getMarker().before( $style );
412425 }
Property changes on: branches/REL1_19/phase3
___________________________________________________________________
Modified: svn:mergeinfo
413426 Merged /trunk/phase3:r111029,111034,111067,111076,111085,111128,111144

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r111029(bug 34289) user.options CSS loaded twice. Fixed by splitting off the CSS par...catrope11:04, 9 February 2012
r111034Make mediawiki.legacy.ajax top-loading too, apparently some people are still ...catrope14:14, 9 February 2012
r111067Followup r110988: IE8 throws JS errors if you try to call .append() on a <sty...catrope19:02, 9 February 2012
r111076(bug 34231) - 'Make thumb.php error or redirect for urls with bogus paths but...aaron19:45, 9 February 2012
r111085(bug 28936, bug 5280) Broken or invalid titles can't be removed from watchlis...maxsem20:39, 9 February 2012
r111128Fix for r106752: let TempFSFile deletions happen when the object goes out of ...tstarling23:56, 9 February 2012
r111144r111076: url decode the 'rel404' path...*ahem*. Archived files and files with...aaron01:35, 10 February 2012

Status & tagging log