Merge "(bug 36329) Fix accesskey tooltip for Firefox 14 on Mac"
authorKrinkle <ttijhof@wikimedia.org>
Thu, 30 Aug 2012 19:36:15 +0000 (19:36 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 30 Aug 2012 19:36:15 +0000 (19:36 +0000)
20 files changed:
.gitignore
RELEASE-NOTES-1.20
includes/Title.php
includes/api/ApiEditPage.php
includes/cache/MessageCache.php
includes/filebackend/FSFileBackend.php
includes/filebackend/FileBackendMultiWrite.php
includes/filebackend/SwiftFileBackend.php
includes/filebackend/TempFSFile.php
includes/job/DoubleRedirectJob.php
includes/objectcache/APCBagOStuff.php
includes/objectcache/BagOStuff.php
includes/objectcache/DBABagOStuff.php
includes/objectcache/XCacheBagOStuff.php
includes/resourceloader/ResourceLoaderWikiModule.php
languages/data/plurals-mediawiki.xml
skins/common/preview.js
tests/phpunit/includes/ExtraParserTest.php
tests/phpunit/includes/HtmlTest.php
tests/phpunit/includes/libs/GenericArrayObjectTest.php

index e057d36..ff3ced3 100644 (file)
@@ -13,7 +13,7 @@ nbproject*
 project.index
 
 # MediaWiki install & usage
-cache/*.cdb
+cache
 images/[0-9a-f]
 images/archive
 images/deleted
index 5a2d9a3..eaf8b7c 100644 (file)
@@ -134,6 +134,7 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * SVG files will now show the actual width in the SVG's specified units
   in the metadata box.
 * Added ResourceLoader module "jquery.jStorage".
+* (bug 39273) Added AJAX support for "Show changes" (diff) in LivePreview.
 
 === Bug fixes in 1.20 ===
 * (bug 30245) Use the correct way to construct a log page title.
@@ -225,6 +226,7 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * (bug 27111) Cascading foreign file repos now fetch shared descriptions properly.
 * EXIF below sea level GPS altitude data is now shown correctly.
 * (bug 39284) jquery.tablesorter should not consider "."" or "?"" to be a currency.
+* (bug 39273) "Show changes" should not be incorrectly displayed in the Live Preview state.
 
 === API changes in 1.20 ===
 * (bug 34316) Add ability to retrieve maximum upload size from MediaWiki API.
index b01c00b..94ae062 100644 (file)
@@ -3820,7 +3820,7 @@ class Title {
                        return false;
                }
                # Get the article text
-               $rev = Revision::newFromTitle( $nt );
+               $rev = Revision::newFromTitle( $nt, false, Revision::READ_LATEST );
                if( !is_object( $rev ) ){
                        return false;
                }
@@ -4113,11 +4113,11 @@ class Title {
                if ( in_array( 'include_old', $options ) ) {
                        $old_cmp = '>=';
                }
-               if ( in_array( 'include_new', $options ) ) {\r
-                       $new_cmp = '<=';\r
-               }\r
-               if ( in_array( 'include_both', $options ) ) {\r
-                       $old_cmp = '>=';\r
+               if ( in_array( 'include_new', $options ) ) {
+                       $new_cmp = '<=';
+               }
+               if ( in_array( 'include_both', $options ) ) {
+                       $old_cmp = '>=';
                        $new_cmp = '<=';
                }
                // No DB query needed if $old and $new are the same or successive revisions:
@@ -4128,7 +4128,7 @@ class Title {
                                return ( $old_cmp === '>' && $new_cmp === '<' ) ? 0 : 1;
                        }
                        return ( $old->getRawUserText() === $new->getRawUserText() ) ? 1 : 2;
-               }\r
+               }
                $dbr = wfGetDB( DB_SLAVE );
                $res = $dbr->select( 'revision', 'DISTINCT rev_user_text',
                        array(
index 3be4b00..0963fe7 100644 (file)
@@ -60,7 +60,11 @@ class ApiEditPage extends ApiBase {
                        if ( $titleObj->isRedirect() ) {
                                $oldTitle = $titleObj;
 
-                               $titles = Title::newFromRedirectArray( Revision::newFromTitle( $oldTitle )->getText( Revision::FOR_THIS_USER ) );
+                               $titles = Title::newFromRedirectArray(
+                                       Revision::newFromTitle(
+                                               $oldTitle, false, Revision::READ_LATEST
+                                       )->getText( Revision::FOR_THIS_USER )
+                               );
                                // array_shift( $titles );
 
                                $redirValues = array();
@@ -182,7 +186,7 @@ class ApiEditPage extends ApiBase {
                if ( !is_null( $params['summary'] ) ) {
                        $requestArray['wpSummary'] = $params['summary'];
                }
-               
+
                if ( !is_null( $params['sectiontitle'] ) ) {
                        $requestArray['wpSectionTitle'] = $params['sectiontitle'];
                }
index 24f32d6..b854a2e 100644 (file)
@@ -766,7 +766,9 @@ class MessageCache {
                }
 
                # Try loading it from the database
-               $revision = Revision::newFromTitle( Title::makeTitle( NS_MEDIAWIKI, $title ) );
+               $revision = Revision::newFromTitle(
+                       Title::makeTitle( NS_MEDIAWIKI, $title ), false, Revision::READ_LATEST
+               );
                if ( $revision ) {
                        $message = $revision->getText();
                        if ($message === false) {
index a0befd6..9349534 100644 (file)
@@ -685,7 +685,7 @@ class FSFileBackend extends FileBackendStore {
 
                // Create a new temporary file with the same extension...
                $ext = FileBackend::extensionFromPath( $params['src'] );
-               $tmpFile = TempFSFile::factory( wfBaseName( $source ) . '_', $ext );
+               $tmpFile = TempFSFile::factory( 'localcopy_', $ext );
                if ( !$tmpFile ) {
                        return null;
                }
index 59392f6..9efa0db 100644 (file)
@@ -160,11 +160,14 @@ class FileBackendMultiWrite extends FileBackend {
                // Actually attempt the operation batch on the master backend...
                $masterStatus = $mbe->doOperations( $realOps, $opts );
                $status->merge( $masterStatus );
-               // Propagate the operations to the clone backends...
-               foreach ( $this->backends as $index => $backend ) {
-                       if ( $index !== $this->masterIndex ) { // not done already
-                               $realOps = $this->substOpBatchPaths( $ops, $backend );
-                               $status->merge( $backend->doOperations( $realOps, $opts ) );
+               // Propagate the operations to the clone backends if there were no fatal errors.
+               // If $ops only had one operation, this might avoid backend inconsistencies.
+               if ( !count( $masterStatus->getErrorsArray() ) ) {
+                       foreach ( $this->backends as $index => $backend ) {
+                               if ( $index !== $this->masterIndex ) { // not done already
+                                       $realOps = $this->substOpBatchPaths( $ops, $backend );
+                                       $status->merge( $backend->doOperations( $realOps, $opts ) );
+                               }
                        }
                }
                // Make 'success', 'successCount', and 'failCount' fields reflect
index 9c111c9..9081e82 100644 (file)
@@ -989,11 +989,8 @@ class SwiftFileBackend extends FileBackendStore {
                        return null;
                }
 
-               # Check the recursion guard to avoid loops when filling metadata
-               if ( empty( $params['nostat'] ) && !$this->fileExists( $params ) ) {
-                       return null;
-               }
-
+               // Blindly create a tmp file and stream to it, catching any exception if the file does
+               // not exist. Also, doing a stat here will cause infinite loops when filling metadata.
                $tmpFile = null;
                try {
                        $sContObj = $this->getContainer( $srcCont );
@@ -1001,7 +998,7 @@ class SwiftFileBackend extends FileBackendStore {
                        // Get source file extension
                        $ext = FileBackend::extensionFromPath( $srcRel );
                        // Create a new temporary file...
-                       $tmpFile = TempFSFile::factory( wfBaseName( $srcRel ) . '_', $ext );
+                       $tmpFile = TempFSFile::factory( 'localcopy_', $ext );
                        if ( $tmpFile ) {
                                $handle = fopen( $tmpFile->getPath(), 'wb' );
                                if ( $handle ) {
@@ -1013,6 +1010,8 @@ class SwiftFileBackend extends FileBackendStore {
                        }
                } catch ( NoSuchContainerException $e ) {
                        $tmpFile = null;
+               } catch ( NoSuchObjectException $e ) {
+                       $tmpFile = null;
                } catch ( CloudFilesException $e ) { // some other exception?
                        $tmpFile = null;
                        $this->handleException( $e, null, __METHOD__, $params );
index ed6bf2f..b738898 100644 (file)
@@ -43,7 +43,7 @@ class TempFSFile extends FSFile {
         */
        public static function factory( $prefix, $extension = '' ) {
                wfProfileIn( __METHOD__ );
-               $base = wfTempDir() . '/' . $prefix . dechex( mt_rand( 0, 99999999 ) );
+               $base = wfTempDir() . '/' . $prefix . wfRandomString( 12 );
                $ext = ( $extension != '' ) ? ".{$extension}" : "";
                for ( $attempt = 1; true; $attempt++ ) {
                        $path = "{$base}-{$attempt}{$ext}";
index 5b86a90..08af997 100644 (file)
@@ -89,7 +89,7 @@ class DoubleRedirectJob extends Job {
                        return false;
                }
 
-               $targetRev = Revision::newFromTitle( $this->title );
+               $targetRev = Revision::newFromTitle( $this->title, false, Revision::READ_LATEST );
                if ( !$targetRev ) {
                        wfDebug( __METHOD__.": target redirect already deleted, ignoring\n" );
                        return true;
index 5a7729b..1a0de21 100644 (file)
@@ -27,7 +27,6 @@
  * @ingroup Cache
  */
 class APCBagOStuff extends BagOStuff {
-
        /**
         * @param $key string
         * @return mixed
@@ -36,7 +35,11 @@ class APCBagOStuff extends BagOStuff {
                $val = apc_fetch( $key );
 
                if ( is_string( $val ) ) {
-                       $val = unserialize( $val );
+                       if ( $this->isInteger( $val ) ) {
+                               $val = intval( $val );
+                       } else {
+                               $val = unserialize( $val );
+                       }
                }
 
                return $val;
@@ -49,7 +52,11 @@ class APCBagOStuff extends BagOStuff {
         * @return bool
         */
        public function set( $key, $value, $exptime = 0 ) {
-               apc_store( $key, serialize( $value ), $exptime );
+               if ( !$this->isInteger( $value ) ) {
+                       $value = serialize( $value );
+               }
+
+               apc_store( $key, $value, $exptime );
 
                return true;
        }
@@ -65,6 +72,14 @@ class APCBagOStuff extends BagOStuff {
                return true;
        }
 
+       public function incr( $key, $value = 1 ) {
+               return apc_inc( $key, $value );
+       }
+
+       public function decr( $key, $value = 1 ) {
+               return apc_dec( $key, $value );
+       }
+
        /**
         * @return Array
         */
@@ -80,4 +95,3 @@ class APCBagOStuff extends BagOStuff {
                return $keys;
        }
 }
-
index fcc3aa9..57029a8 100644 (file)
@@ -164,10 +164,11 @@ abstract class BagOStuff {
        }
 
        /**
+        * Increase stored value of $key by $value while preserving its TTL
         * @param $key String: Key to increase
         * @param $value Integer: Value to add to $key (Default 1)
         * @return null if lock is not possible else $key value increased by $value
-        * @return bool success
+        * @return integer
         */
        public function incr( $key, $value = 1 ) {
                if ( !$this->lock( $key ) ) {
@@ -186,9 +187,10 @@ abstract class BagOStuff {
        }
 
        /**
+        * Decrease stored value of $key by $value while preserving its TTL
         * @param $key String
         * @param $value Integer
-        * @return bool success
+        * @return integer
         */
        public function decr( $key, $value = 1 ) {
                return $this->incr( $key, - $value );
@@ -235,4 +237,14 @@ abstract class BagOStuff {
                        return $exptime;
                }
        }
+
+       /**
+        * Check if a value is an integer
+        *
+        * @param $value mixed
+        * @return bool
+        */
+       protected function isInteger( $value ) {
+               return ( is_int( $value ) || ctype_digit( $value ) );
+       }
 }
index 8483d7e..264aed7 100644 (file)
@@ -45,8 +45,7 @@ class DBABagOStuff extends BagOStuff {
                        $params['dir'] = wfTempDir();
                }
 
-               $this->mFile = $params['dir']."/mw-cache-" . wfWikiID();
-               $this->mFile .= '.db';
+               $this->mFile = $params['dir'] . '/mw-cache-' . wfWikiID() . '.db';
                wfDebug( __CLASS__ . ": using cache file {$this->mFile}\n" );
                $this->mHandler = $wgDBAhandler;
        }
@@ -58,7 +57,7 @@ class DBABagOStuff extends BagOStuff {
         *
         * @return string
         */
-       function encode( $value, $expiry ) {
+       protected function encode( $value, $expiry ) {
                # Convert to absolute time
                $expiry = $this->convertExpiry( $expiry );
 
@@ -69,7 +68,7 @@ class DBABagOStuff extends BagOStuff {
         * @param $blob string
         * @return array list containing value first and expiry second
         */
-       function decode( $blob ) {
+       protected function decode( $blob ) {
                if ( !is_string( $blob ) ) {
                        return array( null, 0 );
                } else {
@@ -83,7 +82,7 @@ class DBABagOStuff extends BagOStuff {
        /**
         * @return resource
         */
-       function getReader() {
+       protected function getReader() {
                if ( file_exists( $this->mFile ) ) {
                        $handle = dba_open( $this->mFile, 'rl', $this->mHandler );
                } else {
@@ -100,7 +99,7 @@ class DBABagOStuff extends BagOStuff {
        /**
         * @return resource
         */
-       function getWriter() {
+       protected function getWriter() {
                $handle = dba_open( $this->mFile, 'cl', $this->mHandler );
 
                if ( !$handle ) {
@@ -114,7 +113,7 @@ class DBABagOStuff extends BagOStuff {
         * @param $key string
         * @return mixed|null|string
         */
-       function get( $key ) {
+       public function get( $key ) {
                wfProfileIn( __METHOD__ );
                wfDebug( __METHOD__ . "($key)\n" );
 
@@ -149,7 +148,7 @@ class DBABagOStuff extends BagOStuff {
         * @param $exptime int
         * @return bool
         */
-       function set( $key, $value, $exptime = 0 ) {
+       public function set( $key, $value, $exptime = 0 ) {
                wfProfileIn( __METHOD__ );
                wfDebug( __METHOD__ . "($key)\n" );
 
@@ -173,7 +172,7 @@ class DBABagOStuff extends BagOStuff {
         * @param $time int
         * @return bool
         */
-       function delete( $key, $time = 0 ) {
+       public function delete( $key, $time = 0 ) {
                wfProfileIn( __METHOD__ );
                wfDebug( __METHOD__ . "($key)\n" );
 
@@ -196,7 +195,7 @@ class DBABagOStuff extends BagOStuff {
         * @param $exptime int
         * @return bool
         */
-       function add( $key, $value, $exptime = 0 ) {
+       public function add( $key, $value, $exptime = 0 ) {
                wfProfileIn( __METHOD__ );
 
                $blob = $this->encode( $value, $exptime );
@@ -214,7 +213,7 @@ class DBABagOStuff extends BagOStuff {
                if ( !$ret ) {
                        list( $value, $expiry ) = $this->decode( dba_fetch( $key, $handle ) );
 
-                       if ( $expiry < time() ) {
+                       if ( $expiry && $expiry < time() ) {
                                # Yes expired, delete and try again
                                dba_delete( $key, $handle );
                                $ret = dba_insert( $key, $blob, $handle );
@@ -229,8 +228,43 @@ class DBABagOStuff extends BagOStuff {
        }
 
        /**
-        * @return Array
+        * @param $key string
+        * @param $step integer
+        * @return integer|bool
         */
+       public function incr( $key, $step = 1 ) {
+               wfProfileIn( __METHOD__ );
+
+               $handle = $this->getWriter();
+
+               if ( !$handle ) {
+                       wfProfileOut( __METHOD__ );
+                       return false;
+               }
+
+               list( $value, $expiry ) = $this->decode( dba_fetch( $key, $handle ) );
+               if ( !is_null( $value ) ) {
+                       if ( $expiry && $expiry < time() ) {
+                               # Key is expired, delete it
+                               dba_delete( $key, $handle );
+                               wfDebug( __METHOD__ . ": $key expired\n" );
+                               $value = null;
+                       } else {
+                               $value += $step;
+                               $blob = $this->encode( $value, $expiry );
+
+                               $ret = dba_replace( $key, $blob, $handle );
+                               $value = $ret ? $value : null;
+                       }
+               }
+
+               dba_close( $handle );
+
+               wfProfileOut( __METHOD__ );
+
+               return is_null( $value ) ? false : (int)$value;
+       }
+
        function keys() {
                $reader = $this->getReader();
                $k1 = dba_firstkey( $reader );
@@ -250,4 +284,3 @@ class DBABagOStuff extends BagOStuff {
                return $result;
        }
 }
-
index 08f52b7..6c88289 100644 (file)
@@ -38,7 +38,11 @@ class XCacheBagOStuff extends BagOStuff {
                $val = xcache_get( $key );
 
                if ( is_string( $val ) ) {
-                       $val = unserialize( $val );
+                       if ( $this->isInteger( $val ) ) {
+                               $val = intval( $val );
+                       } else {
+                               $val = unserialize( $val );
+                       }
                }
 
                return $val;
@@ -53,7 +57,11 @@ class XCacheBagOStuff extends BagOStuff {
         * @return bool
         */
        public function set( $key, $value, $expire = 0 ) {
-               xcache_set( $key, serialize( $value ), $expire );
+               if ( !$this->isInteger( $value ) ) {
+                       $value = serialize( $value );
+               }
+
+               xcache_set( $key, $value, $expire );
                return true;
        }
 
@@ -68,5 +76,12 @@ class XCacheBagOStuff extends BagOStuff {
                xcache_unset( $key );
                return true;
        }
-}
 
+       public function incr( $key, $value = 1 ) {
+               return xcache_inc( $key, $value );
+       }
+
+       public function decr( $key, $value = 1 ) {
+               return xcache_dec( $key, $value );
+       }
+}
index 9dd6939..623a269 100644 (file)
@@ -77,7 +77,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
                if ( !$title->isCssJsSubpage() && !$title->isCssOrJsPage() ) {
                        return null;
                }
-               $revision = Revision::newFromTitle( $title );
+               $revision = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
                if ( !$revision ) {
                        return null;
                }
@@ -182,7 +182,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
                        // We're dealing with a subclass that doesn't have a DB
                        return array();
                }
-               
+
                $hash = $context->getHash();
                if ( isset( $this->titleMtimes[$hash] ) ) {
                        return $this->titleMtimes[$hash];
index fe9e031..54f23dc 100644 (file)
@@ -6,30 +6,30 @@
                        <pluralRule count="one">n is 1</pluralRule>
                        <pluralRule count="two">n is 2</pluralRule>
                </pluralRules>
+               <pluralRules locales="dsb">
+                       <pluralRule count="one">n mod 100 is 1</pluralRule>
+                       <pluralRule count="two">n mod 100 is 2</pluralRule>
+                       <pluralRule count="few">n mod 100 in 3..4</pluralRule>
+               </pluralRules>
+               <pluralRules locales="cu">
+                       <pluralRule count="one">n mod 10 is 1</pluralRule>
+                       <pluralRule count="two">n mod 10 is 2</pluralRule>
+                       <pluralRule count="few">n mod 10 in 3..4</pluralRule>
+               </pluralRules>
+               <!-- Plural form transformations
+               Based on this discussion: http://translatewiki.net/wiki/Thread:Support/New_plural_rules_for_Scots_Gaelic_(gd)
+               $forms[0] - 1
+               $forms[1] - 2
+               $forms[2] - 11
+               $forms[3] - 12
+               $forms[4] - 3-10, 13-19
+               $forms[5] - 0, 20, rest -->
+               <pluralRules locales="gd">
+                       <pluralRule count="one">n is 1</pluralRule>
+                       <pluralRule count="two">n is 2</pluralRule>
+                       <pluralRule count="elevan">n is 11</pluralRule>
+                       <pluralRule count="twelve">n is 12</pluralRule>
+                       <pluralRule count="few">n in 3..10 or n in 13..19</pluralRule>
+               </pluralRules>
        </plurals>
-       <pluralRules locales="dsb">
-               <pluralRule count="one">n mod 100 is 1</pluralRule>
-               <pluralRule count="two">n mod 100 is 2</pluralRule>
-               <pluralRule count="few">n mod 100 in 3..4</pluralRule>
-       </pluralRules>
-       <pluralRules locales="cu">
-               <pluralRule count="one">n mod 10 is 1</pluralRule>
-               <pluralRule count="two">n mod 10 is 2</pluralRule>
-               <pluralRule count="few">n mod 10 in 3..4</pluralRule>
-       </pluralRules>
-       <!-- Plural form transformations
-       Based on this discussion: http://translatewiki.net/wiki/Thread:Support/New_plural_rules_for_Scots_Gaelic_(gd)
-       $forms[0] - 1
-       $forms[1] - 2
-       $forms[2] - 11
-       $forms[3] - 12
-       $forms[4] - 3-10, 13-19
-       $forms[5] - 0, 20, rest -->
-       <pluralRules locales="gd">
-               <pluralRule count="one">n is 1</pluralRule>
-               <pluralRule count="two">n is 2</pluralRule>
-               <pluralRule count="elevan">n is 11</pluralRule>
-               <pluralRule count="twelve">n is 12</pluralRule>
-               <pluralRule count="few">n in 3..10 or n in 13..19</pluralRule>
-       </pluralRules>
 </supplementalData>
index a332a8e..823d467 100644 (file)
@@ -8,10 +8,10 @@
                $( mw ).trigger( 'LivePreviewPrepare' );
 
                var postData = $('#editform').formToArray();
-               postData.push( { 'name' : 'wpPreview', 'value' : '1' } );
+               postData.push( { 'name' : e.target.name, 'value' : '1' } );
 
                // Hide active diff, used templates, old preview if shown
-               var copyElements = ['#wikiPreview', '.templatesUsed', '.hiddencats',
+               var copyElements = ['#wikiPreview', '#wikiDiff', '.templatesUsed', '.hiddencats',
                                                        '#catlinks', '#p-lang', '.mw-summary-preview'];
                var copySelector = copyElements.join(',');
 
                        $( '.editCheckboxes' ).before( $( '<div>' ).addClass( 'mw-summary-preview' ) );
                }
 
-               $( '#wpPreview' ).click( doLivePreview );
+               // construct space for diff if missing. also load diff styles.
+               if ( !document.getElementById( 'wikiDiff' ) && document.getElementById( 'wikiPreview' ) ) {
+                       $( '#wikiPreview' ).after( $( '<div>' ).attr( 'id', 'wikiDiff' ) );
+                       // diff styles are by default only loaded when needed
+                       // if there was no diff container, we can expect the styles not to be there either
+                       mw.loader.load( 'mediawiki.action.history.diff' );
+               }
+
+               $( '#wpPreview, #wpDiff' ).click( doLivePreview );
        } );
 }) ( jQuery );
index 0413b5a..903a6d2 100644 (file)
@@ -21,6 +21,8 @@ class ExtraParserTest extends MediaWikiTestCase {
                $this->options = new ParserOptions;
                $this->options->setTemplateCallback( array( __CLASS__, 'statelessFetchTemplate' ) );
                $this->parser = new Parser;
+
+               MagicWord::clearCache();
        }
 
        // Bug 8689 - Long numeric lines kill the parser
index 8b019d7..0dd85c1 100644 (file)
@@ -6,15 +6,18 @@ class HtmlTest extends MediaWikiTestCase {
        private static $oldContLang;
        private static $oldLanguageCode;
        private static $oldNamespaces;
+       private static $oldHTML5;
 
        public function setUp() {
-               global $wgLang, $wgContLang, $wgLanguageCode;
-               
+               global $wgLang, $wgContLang, $wgLanguageCode, $wgHTML5;
+
+               // Save globals
                self::$oldLang = $wgLang;
                self::$oldContLang = $wgContLang;
                self::$oldNamespaces = $wgContLang->getNamespaces();
                self::$oldLanguageCode = $wgLanguageCode;
-               
+               self::$oldHTML5 = $wgHTML5;
+
                $wgLanguageCode = 'en';
                $wgContLang = $wgLang = Language::factory( $wgLanguageCode );
 
@@ -42,14 +45,35 @@ class HtmlTest extends MediaWikiTestCase {
                        101  => 'Custom_talk',
                ) );
        }
-       
+
        public function tearDown() {
-               global $wgLang, $wgContLang, $wgLanguageCode;
+               global $wgLang, $wgContLang, $wgLanguageCode, $wgHTML5;
 
+               // Restore globals
                $wgContLang->setNamespaces( self::$oldNamespaces );
                $wgLang = self::$oldLang;
                $wgContLang = self::$oldContLang;
                $wgLanguageCode = self::$oldLanguageCode;
+               $wgHTML5 = self::$oldHTML5;
+       }
+
+       /**
+        * Wrapper to easily set $wgHTML5 = true.
+        * Original value will be restored after test completion.
+        * @todo Move to MediaWikiTestCase
+        */
+       public function enableHTML5() {
+               global $wgHTML5;
+               $wgHTML5 = true;
+       }
+       /**
+        * Wrapper to easily set $wgHTML5 = false
+        * Original value will be restored after test completion.
+        * @todo Move to MediaWikiTestCase
+        */
+       public function disableHTML5() {
+               global $wgHTML5;
+               $wgHTML5 = false;
        }
 
        public function testExpandAttributesSkipsNullAndFalse() {
index 8a2fb55..70fce11 100644 (file)
@@ -39,22 +39,30 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
        public abstract function elementInstancesProvider();
 
        /**
-        * Provides instances of the concrete class being tested.
+        * Returns the name of the concrete class being tested.
         *
         * @since 1.20
         *
-        * @return array
+        * @return string
         */
-       public abstract function instanceProvider();
+       public abstract function getInstanceClass();
 
        /**
-        * Returns the name of the concrete class being tested.
+        * Provides instances of the concrete class being tested.
         *
         * @since 1.20
         *
-        * @return string
+        * @return array
         */
-       public abstract function getInstanceClass();
+       public function instanceProvider() {
+               $instances = array();
+
+               foreach ( $this->elementInstancesProvider() as $elementInstances ) {
+                       $instances[] = $this->getNew( $elementInstances );
+               }
+
+               return $this->arrayWrap( $instances );
+       }
 
        /**
         * @since 1.20