Merge "registration: Improve error message if a non-array attribute is set"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 18 Jun 2015 17:29:15 +0000 (17:29 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 18 Jun 2015 17:29:15 +0000 (17:29 +0000)
91 files changed:
RELEASE-NOTES-1.26
autoload.php
composer.json
includes/Import.php
includes/MimeMagic.php
includes/OutputPage.php
includes/Setup.php
includes/api/ApiBlock.php
includes/api/ApiCreateAccount.php
includes/api/ApiEditPage.php
includes/api/ApiFormatXml.php
includes/api/ApiLogin.php
includes/api/ApiParamInfo.php
includes/api/ApiQueryUserInfo.php
includes/api/ApiUnblock.php
includes/api/ApiUndelete.php
includes/cache/LCStoreStaticArray.php
includes/changetags/ChangeTags.php
includes/db/DatabaseMssql.php
includes/db/DatabasePostgres.php
includes/htmlform/HTMLCheckField.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/HTMLFormFieldWithButton.php [new file with mode: 0644]
includes/htmlform/HTMLSelectNamespaceWithButton.php [new file with mode: 0644]
includes/htmlform/HTMLTextFieldWithButton.php [new file with mode: 0644]
includes/libs/eventrelayer/EventRelayer.php
includes/media/MediaTransformInvalidParametersException.php
includes/objectcache/SqlBagOStuff.php
includes/page/Article.php
includes/profiler/ProfileSection.php
includes/profiler/Profiler.php
includes/registration/ExtensionRegistry.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderImage.php
includes/resourceloader/ResourceLoaderImageModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderOOUIImageModule.php
includes/resourceloader/ResourceLoaderSkinModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/skins/Skin.php
includes/skins/SkinFallbackTemplate.php
includes/specials/SpecialExport.php
includes/specials/SpecialUserlogin.php
includes/upload/UploadFromUrl.php
languages/i18n/en.json
languages/i18n/qqq.json
languages/messages/MessagesGom.php
languages/messages/MessagesGom_deva.php
languages/messages/MessagesPnt.php
maintenance/convertExtensionToRegistration.php
maintenance/exportSites.php
maintenance/importSites.php
resources/ResourcesOOUI.php
resources/lib/oojs-ui/i18n/ar.json
resources/lib/oojs-ui/i18n/hu.json
resources/lib/oojs-ui/i18n/it.json
resources/lib/oojs-ui/i18n/krc.json
resources/lib/oojs-ui/i18n/nl.json
resources/lib/oojs-ui/i18n/zh-hant.json
resources/lib/oojs-ui/oojs-ui-apex-noimages.css
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui.js
resources/lib/oojs-ui/themes/mediawiki/icons-moderation.json
resources/lib/oojs-ui/themes/mediawiki/icons.json
resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl.svg [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.stash.js
tests/phpunit/ResourceLoaderTestCase.php
tests/phpunit/includes/api/ApiMainTest.php
tests/phpunit/includes/api/ApiResultTest.php
tests/phpunit/includes/api/query/ApiQueryTest.php
tests/phpunit/includes/libs/ObjectFactoryTest.php
tests/phpunit/includes/objectcache/WANObjectCacheTest.php
tests/phpunit/includes/site/HashSiteStoreTest.php
tests/phpunit/includes/site/SiteExporterTest.php
tests/phpunit/includes/site/SiteImporterTest.php
tests/phpunit/includes/utils/IPTest.php
tests/phpunit/structure/AvailableRightsTest.php
thumb.php

index db560c6..419525b 100644 (file)
@@ -45,6 +45,8 @@ production.
   with formatversion=2.
 * Various other output from meta=siteinfo will now always be arrays instead of
   sometimes being numerically-indexed objects with formatversion=2.
+* When errors about users being blocked are returned, they now include
+  information about the relevant block.
 
 === Action API internal changes in 1.26 ===
 
index 26d954a..504eaf2 100644 (file)
@@ -489,6 +489,7 @@ $wgAutoloadLocalClasses = array(
        'HTMLFileCache' => __DIR__ . '/includes/cache/HTMLFileCache.php',
        'HTMLFloatField' => __DIR__ . '/includes/htmlform/HTMLFloatField.php',
        'HTMLForm' => __DIR__ . '/includes/htmlform/HTMLForm.php',
+       'HTMLFormFieldWithButton' => __DIR__ . '/includes/htmlform/HTMLFormFieldWithButton.php',
        'HTMLFormField' => __DIR__ . '/includes/htmlform/HTMLFormField.php',
        'HTMLFormFieldCloner' => __DIR__ . '/includes/htmlform/HTMLFormFieldCloner.php',
        'HTMLFormFieldRequiredOptionsException' => __DIR__ . '/includes/htmlform/HTMLFormFieldRequiredOptionsException.php',
@@ -502,11 +503,13 @@ $wgAutoloadLocalClasses = array(
        'HTMLSelectField' => __DIR__ . '/includes/htmlform/HTMLSelectField.php',
        'HTMLSelectLimitField' => __DIR__ . '/includes/htmlform/HTMLSelectLimitField.php',
        'HTMLSelectNamespace' => __DIR__ . '/includes/htmlform/HTMLSelectNamespace.php',
+       'HTMLSelectNamespaceWithButton' => __DIR__ . '/includes/htmlform/HTMLSelectNamespaceWithButton.php',
        'HTMLSelectOrOtherField' => __DIR__ . '/includes/htmlform/HTMLSelectOrOtherField.php',
        'HTMLSubmitField' => __DIR__ . '/includes/htmlform/HTMLSubmitField.php',
        'HTMLTagFilter' => __DIR__ . '/includes/htmlform/HTMLTagFilter.php',
        'HTMLTextAreaField' => __DIR__ . '/includes/htmlform/HTMLTextAreaField.php',
        'HTMLTextField' => __DIR__ . '/includes/htmlform/HTMLTextField.php',
+       'HTMLTextFieldWithButton' => __DIR__ . '/includes/htmlform/HTMLTextFieldWithButton.php',
        'HWLDFWordAccumulator' => __DIR__ . '/includes/diff/DairikiDiff.php',
        'HashBagOStuff' => __DIR__ . '/includes/libs/objectcache/HashBagOStuff.php',
        'HashConfig' => __DIR__ . '/includes/config/HashConfig.php',
index ad6399c..257c195 100644 (file)
@@ -21,7 +21,7 @@
                "leafo/lessphp": "0.5.0",
                "liuggio/statsd-php-client": "1.0.12",
                "mediawiki/at-ease": "1.0.0",
-               "oojs/oojs-ui": "0.11.4",
+               "oojs/oojs-ui": "0.11.5",
                "php": ">=5.3.3",
                "psr/log": "1.0.0",
                "wikimedia/cdb": "1.0.1",
index 214bc4e..6a0bfd0 100644 (file)
@@ -394,9 +394,9 @@ class WikiImporter {
                        $countKey = 'title_' . $title->getPrefixedText();
                        $countable = $page->isCountable( $editInfo );
                        if ( array_key_exists( $countKey, $this->countableCache ) &&
-                               $countable != $this->countableCache[ $countKey ] ) {
+                               $countable != $this->countableCache[$countKey] ) {
                                DeferredUpdates::addUpdate( SiteStatsUpdate::factory( array(
-                                       'articles' => ( (int)$countable - (int)$this->countableCache[ $countKey ] )
+                                       'articles' => ( (int)$countable - (int)$this->countableCache[$countKey] )
                                ) ) );
                        }
                }
@@ -611,7 +611,7 @@ class WikiImporter {
                        $tag = $this->reader->localName;
 
                        if ( $tag == 'namespace' ) {
-                               $this->foreignNamespaces[ $this->nodeAttribute( 'key' ) ] =
+                               $this->foreignNamespaces[$this->nodeAttribute( 'key' )] =
                                        $this->nodeContents();
                        } elseif ( in_array( $tag, $normalFields ) ) {
                                $siteInfo[$tag] = $this->nodeContents();
index 0d907b7..3b06525 100644 (file)
@@ -617,12 +617,14 @@ class MimeMagic {
        /**
         * Guess the MIME type from the file contents.
         *
+        * @todo Remove $ext param
+        *
         * @param string $file
         * @param mixed $ext
         * @return bool|string
         * @throws MWException
         */
-       private function doGuessMimeType( $file, $ext ) { // TODO: remove $ext param
+       private function doGuessMimeType( $file, $ext ) {
                // Read a chunk of the file
                MediaWiki\suppressWarnings();
                $f = fopen( $file, 'rb' );
index b3720a4..7322404 100644 (file)
@@ -617,7 +617,8 @@ class OutputPage extends ContextSource {
                        $module = $resourceLoader->getModule( $val );
 
                        if ( $module instanceof ResourceLoaderModule && $module->isPositionDefault() ) {
-                               $warning = __METHOD__ . ': style module should define its position explicitly: ' . $val . ' ' . get_class( $module );
+                               $warning = __METHOD__ . ': style module should define its position explicitly: ' .
+                                       $val . ' ' . get_class( $module );
                                wfDebugLog( 'resourceloader', $warning );
                                wfLogWarning( $warning );
                        }
index 2fa9de1..a97cfa6 100644 (file)
@@ -363,7 +363,7 @@ if ( $wgMetaNamespace === false ) {
 
 // Default value is 2000 or the suhosin limit if it is between 1 and 2000
 if ( $wgResourceLoaderMaxQueryLength === false ) {
-       $suhosinMaxValueLength = (int) ini_get( 'suhosin.get.max_value_length' );
+       $suhosinMaxValueLength = (int)ini_get( 'suhosin.get.max_value_length' );
        if ( $suhosinMaxValueLength > 0 && $suhosinMaxValueLength < 2000 ) {
                $wgResourceLoaderMaxQueryLength = $suhosinMaxValueLength;
        } else {
index 26b5f0e..6adfc1a 100644 (file)
@@ -52,7 +52,13 @@ class ApiBlock extends ApiBase {
                if ( $user->isBlocked() ) {
                        $status = SpecialBlock::checkUnblockSelf( $params['user'], $user );
                        if ( $status !== true ) {
-                               $this->dieUsageMsg( array( $status ) );
+                               $msg = $this->parseMsg( $status );
+                               $this->dieUsage(
+                                       $msg['info'],
+                                       $msg['code'],
+                                       0,
+                                       array( 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) )
+                               );
                        }
                }
 
index 57f96c6..b3a543a 100644 (file)
@@ -48,7 +48,12 @@ class ApiCreateAccount extends ApiBase {
                        );
                }
                if ( $this->getUser()->isBlockedFromCreateAccount() ) {
-                       $this->dieUsage( 'You cannot create a new account because you are blocked', 'blocked' );
+                       $this->dieUsage(
+                               'You cannot create a new account because you are blocked',
+                               'blocked',
+                               0,
+                               array( 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $this->getUser()->getBlock() ) )
+                       );
                }
 
                $params = $this->extractRequestParams();
index 6189f68..e70b8f0 100644 (file)
@@ -130,7 +130,30 @@ class ApiEditPage extends ApiBase {
                        $errors = array_merge( $errors, $titleObj->getUserPermissionsErrors( 'create', $user ) );
                }
                if ( count( $errors ) ) {
-                       $this->dieUsageMsg( $errors[0] );
+                       if ( is_array( $errors[0] ) ) {
+                               switch ( $errors[0][0] ) {
+                                       case 'blockedtext':
+                                               $this->dieUsage(
+                                                       'You have been blocked from editing',
+                                                       'blocked',
+                                                       0,
+                                                       array( 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) )
+                                               );
+                                               break;
+                                       case 'autoblockedtext':
+                                               $this->dieUsage(
+                                                       'Your IP address has been blocked automatically, because it was used by a blocked user',
+                                                       'autoblocked',
+                                                       0,
+                                                       array( 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) )
+                                               );
+                                               break;
+                                       default:
+                                               $this->dieUsageMsg( $errors[0] );
+                               }
+                       } else {
+                               $this->dieUsageMsg( $errors[0] );
+                       }
                }
 
                $toMD5 = $params['text'];
@@ -450,7 +473,12 @@ class ApiEditPage extends ApiBase {
                                $this->dieUsageMsg( array( 'spamdetected', $result['spam'] ) );
 
                        case EditPage::AS_BLOCKED_PAGE_FOR_USER:
-                               $this->dieUsageMsg( 'blockedtext' );
+                               $this->dieUsage(
+                                       'You have been blocked from editing',
+                                       'blocked',
+                                       0,
+                                       array( 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) )
+                               );
 
                        case EditPage::AS_MAX_ARTICLE_SIZE_EXCEEDED:
                        case EditPage::AS_CONTENT_TOO_BIG:
index fa0bac3..4c7d720 100644 (file)
@@ -72,7 +72,7 @@ class ApiFormatXml extends ApiFormatBase {
                        'Custom' => function ( &$data, &$metadata ) {
                                if ( isset( $metadata[ApiResult::META_TYPE] ) ) {
                                        // We want to use non-BC for BCassoc to force outputting of _idx.
-                                       switch( $metadata[ApiResult::META_TYPE] ) {
+                                       switch ( $metadata[ApiResult::META_TYPE] ) {
                                                case 'BCassoc':
                                                        $metadata[ApiResult::META_TYPE] = 'assoc';
                                                        break;
index d8b390c..c4e7022 100644 (file)
@@ -144,6 +144,10 @@ class ApiLogin extends ApiBase {
                        case LoginForm::CREATE_BLOCKED:
                                $result['result'] = 'CreateBlocked';
                                $result['details'] = 'Your IP address is blocked from account creation';
+                               $result = array_merge(
+                                       $result,
+                                       ApiQueryUserInfo::getBlockInfo( $context->getUser()->getBlock() )
+                               );
                                break;
 
                        case LoginForm::THROTTLED:
@@ -154,6 +158,10 @@ class ApiLogin extends ApiBase {
 
                        case LoginForm::USER_BLOCKED:
                                $result['result'] = 'Blocked';
+                               $result = array_merge(
+                                       $result,
+                                       ApiQueryUserInfo::getBlockInfo( User::newFromName( $params['name'] )->getBlock() )
+                               );
                                break;
 
                        case LoginForm::ABORTED:
index 8a4ef49..2ab37ad 100644 (file)
@@ -337,7 +337,7 @@ class ApiParamInfo extends ApiBase {
                                                        ? '' : ( $module->getModulePath() . '+' );
                                                $item['submodules'] = array();
                                                foreach ( $item['type'] as $v ) {
-                                                       $item['submodules'][$v] = $prefix.$v;
+                                                       $item['submodules'][$v] = $prefix . $v;
                                                }
                                        }
                                        if ( isset( $settings[ApiBase::PARAM_SUBMODULE_PARAM_PREFIX] ) ) {
index 4302ef3..e003e31 100644 (file)
@@ -51,9 +51,32 @@ class ApiQueryUserInfo extends ApiQueryBase {
                $result->addValue( 'query', $this->getModuleName(), $r );
        }
 
-       protected function getCurrentUserInfo() {
+       /**
+        * Get basic info about a given block
+        * @param Block $block
+        * @return array Array containing several keys:
+        *  - blockid - ID of the block
+        *  - blockedby - username of the blocker
+        *  - blockedbyid - user ID of the blocker
+        *  - blockreason - reason provided for the block
+        *  - blockedtimestamp - timestamp for when the block was placed/modified
+        *  - blockexpiry - expiry time of the block
+        */
+       public static function getBlockInfo( Block $block ) {
                global $wgContLang;
+               $vals = array();
+               $vals['blockid'] = $block->getId();
+               $vals['blockedby'] = $block->getByName();
+               $vals['blockedbyid'] = $block->getBy();
+               $vals['blockreason'] = $block->mReason;
+               $vals['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $block->mTimestamp );
+               $vals['blockexpiry'] = $wgContLang->formatExpiry(
+                       $block->getExpiry(), TS_ISO_8601, 'infinite'
+               );
+               return $vals;
+       }
 
+       protected function getCurrentUserInfo() {
                $user = $this->getUser();
                $result = $this->getResult();
                $vals = array();
@@ -64,18 +87,8 @@ class ApiQueryUserInfo extends ApiQueryBase {
                        $vals['anon'] = true;
                }
 
-               if ( isset( $this->prop['blockinfo'] ) ) {
-                       if ( $user->isBlocked() ) {
-                               $block = $user->getBlock();
-                               $vals['blockid'] = $block->getId();
-                               $vals['blockedby'] = $block->getByName();
-                               $vals['blockedbyid'] = $block->getBy();
-                               $vals['blockreason'] = $user->blockedFor();
-                               $vals['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $block->mTimestamp );
-                               $vals['blockexpiry'] = $wgContLang->formatExpiry(
-                                       $block->getExpiry(), TS_ISO_8601, 'infinite'
-                               );
-                       }
+               if ( isset( $this->prop['blockinfo'] ) && $user->isBlocked() ) {
+                       $vals = array_merge( $vals, self::getBlockInfo( $user->getBlock() ) );
                }
 
                if ( isset( $this->prop['hasmsg'] ) ) {
index 1af83ba..f6c24b7 100644 (file)
@@ -53,7 +53,13 @@ class ApiUnblock extends ApiBase {
                if ( $user->isBlocked() ) {
                        $status = SpecialBlock::checkUnblockSelf( $params['user'], $user );
                        if ( $status !== true ) {
-                               $this->dieUsageMsg( $status );
+                               $msg = $this->parseMsg( $status );
+                               $this->dieUsage(
+                                       $msg['info'],
+                                       $msg['code'],
+                                       0,
+                                       array( 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) )
+                               );
                        }
                }
 
index c23e9ff..28702b1 100644 (file)
@@ -37,7 +37,12 @@ class ApiUndelete extends ApiBase {
                }
 
                if ( $this->getUser()->isBlocked() ) {
-                       $this->dieUsageMsg( 'blockedtext' );
+                       $this->dieUsage(
+                               'You have been blocked from editing',
+                               'blocked',
+                               0,
+                               array( 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $this->getUser()->getBlock() ) )
+                       );
                }
 
                $titleObj = Title::newFromText( $params['title'] );
index 862ed67..6a597ca 100644 (file)
@@ -48,7 +48,7 @@ class LCStoreStaticArray implements LCStore {
 
        public function startWrite( $code ) {
                $this->currentLang = $code;
-               $this->fname = $this->directory. '/' . $code . '.l10n.php';
+               $this->fname = $this->directory . '/' . $code . '.l10n.php';
                $this->data[$code] = array();
                if ( file_exists( $this->fname ) ) {
                        $this->data[$code] = require $this->fname;
@@ -125,7 +125,7 @@ class LCStoreStaticArray implements LCStore {
 
        public function get( $code, $key ) {
                if ( !array_key_exists( $code, $this->data ) ) {
-                       $fname = $this->directory. '/' . $code . '.l10n.php';
+                       $fname = $this->directory . '/' . $code . '.l10n.php';
                        if ( !file_exists( $fname ) ) {
                                return null;
                        }
index 99385c8..95f4816 100644 (file)
@@ -749,12 +749,6 @@ class ChangeTags {
                        return Status::newFatal( 'tags-manage-no-permission' );
                }
 
-               // non-existing tags cannot be activated
-               $tagUsage = self::tagUsageStatistics();
-               if ( !isset( $tagUsage[$tag] ) ) {
-                       return Status::newFatal( 'tags-activate-not-found', $tag );
-               }
-
                // defined tags cannot be activated (a defined tag is either extension-
                // defined, in which case the extension chooses whether or not to active it;
                // or user-defined, in which case it is considered active)
@@ -763,6 +757,12 @@ class ChangeTags {
                        return Status::newFatal( 'tags-activate-not-allowed', $tag );
                }
 
+               // non-existing tags cannot be activated
+               $tagUsage = self::tagUsageStatistics();
+               if ( !isset( $tagUsage[$tag] ) ) { // we already know the tag is undefined
+                       return Status::newFatal( 'tags-activate-not-found', $tag );
+               }
+
                return Status::newGood();
        }
 
@@ -887,7 +887,7 @@ class ChangeTags {
 
                // does the tag already exist?
                $tagUsage = self::tagUsageStatistics();
-               if ( isset( $tagUsage[$tag] ) ) {
+               if ( isset( $tagUsage[$tag] ) || in_array( $tag, self::listDefinedTags() ) ) {
                        return Status::newFatal( 'tags-create-already-exists', $tag );
                }
 
@@ -997,11 +997,11 @@ class ChangeTags {
                        return Status::newFatal( 'tags-manage-no-permission' );
                }
 
-               if ( !isset( $tagUsage[$tag] ) ) {
+               if ( !isset( $tagUsage[$tag] ) && !in_array( $tag, self::listDefinedTags() ) ) {
                        return Status::newFatal( 'tags-delete-not-found', $tag );
                }
 
-               if ( $tagUsage[$tag] > self::MAX_DELETE_USES ) {
+               if ( isset( $tagUsage[$tag] ) && $tagUsage[$tag] > self::MAX_DELETE_USES ) {
                        return Status::newFatal( 'tags-delete-too-many-uses', $tag, self::MAX_DELETE_USES );
                }
 
@@ -1046,6 +1046,7 @@ class ChangeTags {
 
                // store the tag usage statistics
                $tagUsage = self::tagUsageStatistics();
+               $hitcount = isset( $tagUsage[$tag] ) ? $tagUsage[$tag] : 0;
 
                // do it!
                $deleteResult = self::deleteTagEverywhere( $tag );
@@ -1054,7 +1055,7 @@ class ChangeTags {
                }
 
                // log it
-               $logId = self::logTagManagementAction( 'delete', $tag, $reason, $user, $tagUsage[$tag] );
+               $logId = self::logTagManagementAction( 'delete', $tag, $reason, $user, $hitcount );
                $deleteResult->value = $logId;
                return $deleteResult;
        }
index b5b6825..85f1b96 100644 (file)
@@ -1089,7 +1089,9 @@ class DatabaseMssql extends DatabaseBase {
         * @param string $s
         * @return string
         */
-       public function strencode( $s ) { # Should not be called by us
+       public function strencode( $s ) {
+               // Should not be called by us
+
                return str_replace( "'", "''", $s );
        }
 
index 60999e5..9ad76ab 100644 (file)
@@ -1510,7 +1510,9 @@ SQL;
                return pg_unescape_bytea( $b );
        }
 
-       function strencode( $s ) { # Should not be called by us
+       function strencode( $s ) {
+               // Should not be called by us
+
                return pg_escape_string( $this->mConn, $s );
        }
 
@@ -1702,4 +1704,5 @@ SQL;
        }
 } // end DatabasePostgres class
 
-class PostgresBlob extends Blob {}
+class PostgresBlob extends Blob {
+}
index ede30dd..90293f4 100644 (file)
@@ -74,6 +74,11 @@ class HTMLCheckField extends HTMLFormField {
        function getLabel() {
                if ( $this->mParent instanceof OOUIHTMLForm ) {
                        return $this->mLabel;
+               } elseif (
+                       $this->mParent instanceof HTMLForm &&
+                       $this->mParent->getDisplayFormat() === 'div'
+               ) {
+                       return '';
                } else {
                        return '&#160;';
                }
index cb4bba2..65fc0e8 100644 (file)
@@ -125,6 +125,7 @@ class HTMLForm extends ContextSource {
        public static $typeMappings = array(
                'api' => 'HTMLApiField',
                'text' => 'HTMLTextField',
+               'textwithbutton' => 'HTMLTextFieldWithButton',
                'textarea' => 'HTMLTextAreaField',
                'select' => 'HTMLSelectField',
                'radio' => 'HTMLRadioField',
@@ -138,6 +139,7 @@ class HTMLForm extends ContextSource {
                'selectorother' => 'HTMLSelectOrOtherField',
                'selectandother' => 'HTMLSelectAndOtherField',
                'namespaceselect' => 'HTMLSelectNamespace',
+               'namespaceselectwithbutton' => 'HTMLSelectNamespaceWithButton',
                'tagfilter' => 'HTMLTagFilter',
                'submit' => 'HTMLSubmitField',
                'hidden' => 'HTMLHiddenField',
index 49478fb..e19273b 100644 (file)
@@ -524,12 +524,20 @@ abstract class HTMLFormField {
                        'mw-htmlform-nolabel' => ( $label === '' )
                );
 
-               $field = Html::rawElement(
-                       'div',
-                       array( 'class' => $outerDivClass ) + $cellAttributes,
-                       $inputHtml . "\n$errors"
-               );
-               $divCssClasses = array( "mw-htmlform-field-$fieldType", $this->mClass, $this->mVFormClass, $errorClass );
+               $horizontalLabel = isset( $this->mParams['horizontal-label'] )
+                       ? $this->mParams['horizontal-label'] : false;
+
+               if ( $horizontalLabel ) {
+                       $field = '&#160;' . $inputHtml . "\n$errors";
+               } else {
+                       $field = Html::rawElement(
+                               'div',
+                               array( 'class' => $outerDivClass ) + $cellAttributes,
+                               $inputHtml . "\n$errors"
+                       );
+               }
+               $divCssClasses = array( "mw-htmlform-field-$fieldType",
+                       $this->mClass, $this->mVFormClass, $errorClass );
 
                $wrapperAttributes = array(
                        'class' => $divCssClasses,
@@ -796,6 +804,8 @@ abstract class HTMLFormField {
 
                $displayFormat = $this->mParent->getDisplayFormat();
                $html = '';
+               $horizontalLabel = isset( $this->mParams['horizontal-label'] )
+                       ? $this->mParams['horizontal-label'] : false;
 
                if ( $displayFormat === 'table' ) {
                        $html =
@@ -803,7 +813,7 @@ abstract class HTMLFormField {
                                        array( 'class' => 'mw-label' ) + $cellAttributes,
                                        Html::rawElement( 'label', $for, $labelValue ) );
                } elseif ( $hasLabel || $this->mShowEmptyLabels ) {
-                       if ( $displayFormat === 'div' ) {
+                       if ( $displayFormat === 'div' && !$horizontalLabel ) {
                                $html =
                                        Html::rawElement( 'div',
                                                array( 'class' => 'mw-label' ) + $cellAttributes,
diff --git a/includes/htmlform/HTMLFormFieldWithButton.php b/includes/htmlform/HTMLFormFieldWithButton.php
new file mode 100644 (file)
index 0000000..3c8910f
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Enables HTMLFormField elements to be build with a button.
+ */
+class HTMLFormFieldWithButton extends HTMLFormField {
+       /** @var string $mButtonClass CSS class for the button in this field */
+       protected $mButtonClass = '';
+
+       /** @var string|integer $mButtonId Element ID for the button in this field */
+       protected $mButtonId = '';
+
+       /** @var string $mButtonName Name the button in this field */
+       protected $mButtonName = '';
+
+       /** @var string $mButtonType Type of the button in this field (e.g. button or submit) */
+       protected $mButtonType = 'submit';
+
+       /** @var string $mButtonType Value for the button in this field */
+       protected $mButtonValue;
+
+       public function __construct( $info ) {
+               if ( isset( $info['buttonclass'] ) ) {
+                       $this->mButtonClass = $info['buttonclass'];
+               }
+               if ( isset( $info['buttonid'] ) ) {
+                       $this->mButtonId = $info['buttonid'];
+               }
+               if ( isset( $info['buttonname'] ) ) {
+                       $this->mButtonName = $info['buttonname'];
+               }
+               if ( isset( $info['buttondefault'] ) ) {
+                       $this->mButtonValue = $info['buttondefault'];
+               }
+               if ( isset( $info['buttontype'] ) ) {
+                       $this->mButtonType = $info['buttontype'];
+               }
+               parent::__construct( $info );
+       }
+
+       public function getInputHTML( $value ) {
+               $attr = array(
+                       'class' => 'mw-htmlform-submit ' . $this->mButtonClass,
+                       'id' => $this->mButtonId,
+               ) + $this->getAttributes( array( 'disabled', 'tabindex' ) );
+
+               return Html::input( $this->mButtonName, $this->mButtonValue, $this->mButtonType, $attr );
+       }
+
+       /**
+        * Combines the passed element with a button.
+        * @param String $element Element to combine the button with.
+        * @return String
+        */
+       public function getElement( $element ) {
+               return $element . '&#160;' . $this->getInputHTML( '' );
+       }
+}
\ No newline at end of file
diff --git a/includes/htmlform/HTMLSelectNamespaceWithButton.php b/includes/htmlform/HTMLSelectNamespaceWithButton.php
new file mode 100644 (file)
index 0000000..5ab57a3
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Creates a Html::namespaceSelector input field with a button assigned to the input field.
+ */
+class HTMLSelectNamespaceWithButton extends HTMLSelectNamespace {
+       /** @var HTMLFormClassWithButton $mClassWithButton */
+       protected $mClassWithButton = null;
+
+       public function __construct( $info ) {
+               $this->mClassWithButton = new HTMLFormFieldWithButton( $info );
+               parent::__construct( $info );
+       }
+
+       public function getInputHTML( $value ) {
+               return $this->mClassWithButton->getElement( parent::getInputHTML( $value ) );
+       }
+}
\ No newline at end of file
diff --git a/includes/htmlform/HTMLTextFieldWithButton.php b/includes/htmlform/HTMLTextFieldWithButton.php
new file mode 100644 (file)
index 0000000..00c0517
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Creates a text input field with a button assigned to the input field.
+ */
+class HTMLTextFieldWithButton extends HTMLTextField {
+       /** @var HTMLFormClassWithButton $mClassWithButton */
+       protected $mClassWithButton = null;
+
+       public function __construct( $info ) {
+               $this->mClassWithButton = new HTMLFormFieldWithButton( $info );
+               parent::__construct( $info );
+       }
+
+       public function getInputHTML( $value ) {
+               return $this->mClassWithButton->getElement( parent::getInputHTML( $value ) );
+       }
+}
\ No newline at end of file
index a3d214f..f95ba3f 100755 (executable)
@@ -26,7 +26,8 @@ abstract class EventRelayer {
        /**
         * @param array $params
         */
-       public function __construct( array $params ) {}
+       public function __construct( array $params ) {
+       }
 
        /**
         * @param string $channel
index 15a2ca5..6f9c291 100644 (file)
@@ -23,4 +23,5 @@
  *
  * @ingroup Exception
  */
-class MediaTransformInvalidParametersException extends MWException {}
+class MediaTransformInvalidParametersException extends MWException {
+}
index 2017a74..b8c1e75 100644 (file)
@@ -358,8 +358,6 @@ class SqlBagOStuff extends BagOStuff {
                return $result;
        }
 
-
-
        /**
         * @param string $key
         * @param mixed $value
index 11a3638..5d7f365 100644 (file)
@@ -333,7 +333,9 @@ class Article implements Page {
         * @return string|bool String containing article contents, or false if null
         * @deprecated since 1.21, use WikiPage::getContent() instead
         */
-       function fetchContent() { #BC cruft!
+       function fetchContent() {
+               // BC cruft!
+
                ContentHandler::deprecated( __METHOD__, '1.21' );
 
                if ( $this->mContentLoaded && $this->mContent ) {
index 9062251..d787edb 100644 (file)
@@ -39,5 +39,6 @@ class ProfileSection {
         *
         * @param string $name Name of the function to profile
         */
-       public function __construct( $name ) {}
+       public function __construct( $name ) {
+       }
 }
index 9983fec..c65a3f9 100644 (file)
@@ -145,8 +145,11 @@ abstract class Profiler {
        }
 
        // Kept BC for now, remove when possible
-       public function profileIn( $functionname ) {}
-       public function profileOut( $functionname ) {}
+       public function profileIn( $functionname ) {
+       }
+
+       public function profileOut( $functionname ) {
+       }
 
        /**
         * Mark the start of a custom profiling frame (e.g. DB queries).
index d767870..d48a1bd 100644 (file)
@@ -137,7 +137,7 @@ class ExtensionRegistry {
                        if ( !is_array( $info ) ) {
                                throw new Exception( "$path is not a valid JSON file." );
                        }
-                       if ( !isset( $info['manifest_version' ] ) ) {
+                       if ( !isset( $info['manifest_version'] ) ) {
                                // For backwards-compatability, assume a version of 1
                                $info['manifest_version'] = 1;
                        }
index bbe55ab..92b0156 100644 (file)
@@ -1104,9 +1104,9 @@ MESSAGE;
                $module = array(
                        $name,
                        $scripts,
-                       (object) $styles,
-                       (object) $messages,
-                       (object) $templates,
+                       (object)$styles,
+                       (object)$messages,
+                       (object)$templates,
                );
                self::trimArray( $module );
 
index 2c52c2e..2e1752a 100644 (file)
@@ -63,7 +63,6 @@ class ResourceLoaderContext {
                $modules = $request->getVal( 'modules' );
                $this->modules = $modules ? self::expandModuleNames( $modules ) : array();
 
-
                // Various parameters
                $this->user = $request->getVal( 'user' );
                $this->debug = $request->getFuzzyBool(
index bf68fdd..6382200 100644 (file)
@@ -60,9 +60,9 @@ class ResourceLoaderImage {
                                if ( strpos( $langList, ',' ) !== false ) {
                                        $this->descriptor['lang'] += array_fill_keys(
                                                explode( ',', $langList ),
-                                               $this->descriptor['lang'][ $langList ]
+                                               $this->descriptor['lang'][$langList]
                                        );
-                                       unset( $this->descriptor['lang'][ $langList ] );
+                                       unset( $this->descriptor['lang'][$langList] );
                                }
                        }
                }
@@ -121,10 +121,10 @@ class ResourceLoaderImage {
                $desc = $this->descriptor;
                if ( is_string( $desc ) ) {
                        return $this->basePath . '/' . $desc;
-               } elseif ( isset( $desc['lang'][ $context->getLanguage() ] ) ) {
-                       return $this->basePath . '/' . $desc['lang'][ $context->getLanguage() ];
-               } elseif ( isset( $desc[ $context->getDirection() ] ) ) {
-                       return $this->basePath . '/' . $desc[ $context->getDirection() ];
+               } elseif ( isset( $desc['lang'][$context->getLanguage()] ) ) {
+                       return $this->basePath . '/' . $desc['lang'][$context->getLanguage()];
+               } elseif ( isset( $desc[$context->getDirection()] ) ) {
+                       return $this->basePath . '/' . $desc[$context->getDirection()];
                } else {
                        return $this->basePath . '/' . $desc['default'];
                }
index 2caca87..0c1db1a 100644 (file)
@@ -86,9 +86,11 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
         *         // List of image files and their options
         *         'images' => array(
         *             [theme name] => array(
-        *                 [file path string],
-        *                 [file path string] => array(
-        *                     'name' => [image name string, defaults to file name],
+        *                 [icon name] => array(
+        *                     'file' => [file path string or array whose values are file path strings
+        *                                    and whose keys are 'default', 'ltr', 'rtl', a single
+        *                                    language code like 'en', or a list of language codes like
+        *                                    'en,de,ar'],
         *                     'variants' => [array of variant name strings, variants
         *                                    available for this image],
         *                 ),
@@ -229,23 +231,23 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                        $this->loadFromDefinition();
                        $this->imageObjects = array();
                }
-               if ( !isset( $this->imageObjects[ $skin ] ) ) {
-                       $this->imageObjects[ $skin ] = array();
-                       if ( !isset( $this->images[ $skin ] ) ) {
-                               $this->images[ $skin ] = isset( $this->images[ 'default' ] ) ?
-                                       $this->images[ 'default' ] :
+               if ( !isset( $this->imageObjects[$skin] ) ) {
+                       $this->imageObjects[$skin] = array();
+                       if ( !isset( $this->images[$skin] ) ) {
+                               $this->images[$skin] = isset( $this->images['default'] ) ?
+                                       $this->images['default'] :
                                        array();
                        }
-                       foreach ( $this->images[ $skin ] as $name => $options ) {
+                       foreach ( $this->images[$skin] as $name => $options ) {
                                $fileDescriptor = is_string( $options ) ? $options : $options['file'];
 
                                $allowedVariants = array_merge(
                                        is_array( $options ) && isset( $options['variants'] ) ? $options['variants'] : array(),
                                        $this->getGlobalVariants( $context )
                                );
-                               if ( isset( $this->variants[ $skin ] ) ) {
+                               if ( isset( $this->variants[$skin] ) ) {
                                        $variantConfig = array_intersect_key(
-                                               $this->variants[ $skin ],
+                                               $this->variants[$skin],
                                                array_fill_keys( $allowedVariants, true )
                                        );
                                } else {
@@ -259,11 +261,11 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                                        $this->localBasePath,
                                        $variantConfig
                                );
-                               $this->imageObjects[ $skin ][ $image->getName() ] = $image;
+                               $this->imageObjects[$skin][$image->getName()] = $image;
                        }
                }
 
-               return $this->imageObjects[ $skin ];
+               return $this->imageObjects[$skin];
        }
 
        /**
@@ -278,21 +280,21 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                        $this->loadFromDefinition();
                        $this->globalVariants = array();
                }
-               if ( !isset( $this->globalVariants[ $skin ] ) ) {
-                       $this->globalVariants[ $skin ] = array();
-                       if ( !isset( $this->variants[ $skin ] ) ) {
-                               $this->variants[ $skin ] = isset( $this->variants[ 'default' ] ) ?
-                                       $this->variants[ 'default' ] :
+               if ( !isset( $this->globalVariants[$skin] ) ) {
+                       $this->globalVariants[$skin] = array();
+                       if ( !isset( $this->variants[$skin] ) ) {
+                               $this->variants[$skin] = isset( $this->variants['default'] ) ?
+                                       $this->variants['default'] :
                                        array();
                        }
-                       foreach ( $this->variants[ $skin ] as $name => $config ) {
+                       foreach ( $this->variants[$skin] as $name => $config ) {
                                if ( isset( $config['global'] ) && $config['global'] ) {
-                                       $this->globalVariants[ $skin ][] = $name;
+                                       $this->globalVariants[$skin][] = $name;
                                }
                        }
                }
 
-               return $this->globalVariants[ $skin ];
+               return $this->globalVariants[$skin];
        }
 
        /**
index ec7ed70..63da592 100644 (file)
@@ -458,9 +458,9 @@ abstract class ResourceLoaderModule {
                // Cache this expensive operation. This calls builds the scripts, styles, and messages
                // content which typically involves filesystem and/or database access.
                if ( !array_key_exists( $contextHash, $this->contents ) ) {
-                       $this->contents[ $contextHash ] = $this->buildContent( $context );
+                       $this->contents[$contextHash] = $this->buildContent( $context );
                }
-               return $this->contents[ $contextHash ];
+               return $this->contents[$contextHash];
        }
 
        /**
@@ -608,9 +608,9 @@ abstract class ResourceLoaderModule {
                                $str .= strval( $mhash );
                        }
 
-                       $this->versionHash[ $contextHash ] = ResourceLoader::makeHash( $str );
+                       $this->versionHash[$contextHash] = ResourceLoader::makeHash( $str );
                }
-               return $this->versionHash[ $contextHash ];
+               return $this->versionHash[$contextHash];
        }
 
        /**
index ebbeb01..c825ab2 100644 (file)
@@ -50,7 +50,7 @@ class ResourceLoaderOOUIImageModule extends ResourceLoaderImageModule {
                                array_walk( $data['images'], function ( &$value ) use ( $fixPath ) {
                                        if ( is_string( $value['file'] ) ) {
                                                $fixPath( $value['file'] );
-                                       } else if ( is_array( $value['file'] ) ) {
+                                       } elseif ( is_array( $value['file'] ) ) {
                                                array_walk_recursive( $value['file'], $fixPath );
                                        }
                                } );
index 980b7fe..911d953 100644 (file)
@@ -44,13 +44,13 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
                                        '(min-resolution: 1.5dppx), ' .
                                        '(min-resolution: 144dpi)'
                                ][] = '.mw-wiki-logo { background-image: ' .
-                               CSSMin::buildUrlValue( $logoHD['1.5x'] ) .';' .
+                               CSSMin::buildUrlValue( $logoHD['1.5x'] ) . ';' .
                                'background-size: 135px auto; }';
                        }
                        if ( isset( $logoHD['2x'] ) ) {
                                $styles[
                                        '(-webkit-min-device-pixel-ratio: 2), ' .
-                                       '(min--moz-device-pixel-ratio: 2),'.
+                                       '(min--moz-device-pixel-ratio: 2),' .
                                        '(min-resolution: 2dppx), ' .
                                        '(min-resolution: 192dpi)'
                                ][] = '.mw-wiki-logo { background-image: ' .
index 8dbed8e..a578ece 100644 (file)
@@ -404,7 +404,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                // Pre-populate versionHash with something because the loop over all modules below includes
                // the startup module (this module).
                // See ResourceLoaderModule::getVersionHash() for usage of this cache.
-               $this->versionHash[ $context->getHash() ] = null;
+               $this->versionHash[$context->getHash()] = null;
 
                return $rl->getCombinedVersion( $context, $rl->getModuleNames() );
        }
index 6c5fbcd..327ef7c 100644 (file)
@@ -650,7 +650,7 @@ abstract class Skin extends ContextSource {
                }
 
                return $this->msg( 'retrievedfrom' )
-                       ->rawParams( '<a dir="ltr" href="' . $url. '">' . $url . '</a>' )
+                       ->rawParams( '<a dir="ltr" href="' . $url . '">' . $url . '</a>' )
                        ->parse();
        }
 
index 312769f..cd5e43c 100644 (file)
@@ -87,7 +87,7 @@ class SkinFallbackTemplate extends BaseTemplate {
                if ( file_exists( "$IP/skins/$skin/skin.json" ) ) {
                        return "wfLoadSkin( '$skin' );";
                } else {
-                       return  "require_once \"\$IP/skins/$skin/$skin.php\";";
+                       return "require_once \"\$IP/skins/$skin/$skin.php\";";
                }
        }
 
index 47884eb..920d34b 100644 (file)
@@ -188,113 +188,128 @@ class SpecialExport extends SpecialPage {
                        $categoryName = '';
                }
 
-               $form = Xml::openElement( 'form', array( 'method' => 'post',
-                       'action' => $this->getPageTitle()->getLocalURL( 'action=submit' ) ) );
-               $form .= Xml::inputLabel(
-                       $this->msg( 'export-addcattext' )->text(),
-                       'catname',
-                       'catname',
-                       40,
-                       $categoryName
-               ) . '&#160;';
-               $form .= Xml::submitButton(
-                       $this->msg( 'export-addcat' )->text(),
-                       array( 'name' => 'addcat' )
-               ) . '<br />';
-
+               $formDescriptor = array(
+                       'catname' => array(
+                               'type' => 'textwithbutton',
+                               'name' => 'catname',
+                               'horizontal-label' => true,
+                               'label-message' => 'export-addcattext',
+                               'default' => $categoryName,
+                               'size' => 40,
+                               'buttontype' => 'submit',
+                               'buttonname' => 'addcat',
+                               'buttondefault' => $this->msg( 'export-addcat' )->text(),
+                       ),
+               );
                if ( $config->get( 'ExportFromNamespaces' ) ) {
-                       $form .= Html::namespaceSelector(
-                               array(
-                                       'selected' => $nsindex,
-                                       'label' => $this->msg( 'export-addnstext' )->text()
-                               ), array(
+                       $formDescriptor += array(
+                               'nsindex' => array(
+                                       'type' => 'namespaceselectwithbutton',
+                                       'default' => $nsindex,
+                                       'label-message' => 'export-addnstext',
+                                       'horizontal-label' => true,
                                        'name' => 'nsindex',
                                        'id' => 'namespace',
-                                       'class' => 'namespaceselector',
-                               )
-                       ) . '&#160;';
-                       $form .= Xml::submitButton(
-                               $this->msg( 'export-addns' )->text(),
-                               array( 'name' => 'addns' )
-                       ) . '<br />';
+                                       'cssclass' => 'namespaceselector',
+                                       'buttontype' => 'submit',
+                                       'buttonname' => 'addns',
+                                       'buttondefault' => $this->msg( 'export-addns' )->text(),
+                               ),
+                       );
                }
 
                if ( $config->get( 'ExportAllowAll' ) ) {
-                       $form .= Xml::checkLabel(
-                               $this->msg( 'exportall' )->text(),
-                               'exportall',
-                               'exportall',
-                               $request->wasPosted() ? $request->getCheck( 'exportall' ) : false
-                       ) . '<br />';
+                       $formDescriptor += array(
+                               'exportall' => array(
+                                       'type' => 'check',
+                                       'label-message' => 'exportall',
+                                       'name' => 'exportall',
+                                       'id' => 'exportall',
+                                       'default' => $request->wasPosted() ? $request->getCheck( 'exportall' ) : false,
+                               ),
+                       );
                }
 
-               $form .= Xml::element(
-                       'textarea',
-                       array( 'name' => 'pages', 'cols' => 40, 'rows' => 10 ),
-                       $page,
-                       false
+               $formDescriptor += array(
+                       'textarea' => array(
+                               'class' => 'HTMLTextAreaField',
+                               'name' => 'pages',
+                               'nodata' => true,
+                               'cols' => 40,
+                               'rows' => 10,
+                               'default' => $page,
+                       ),
                );
-               $form .= '<br />';
 
                if ( $config->get( 'ExportAllowHistory' ) ) {
-                       $form .= Xml::checkLabel(
-                               $this->msg( 'exportcuronly' )->text(),
-                               'curonly',
-                               'curonly',
-                               $request->wasPosted() ? $request->getCheck( 'curonly' ) : true
-                       ) . '<br />';
+                       $formDescriptor += array(
+                               'curonly' => array(
+                                       'type' => 'check',
+                                       'label-message' => 'exportcuronly',
+                                       'name' => 'curonly',
+                                       'id' => 'curonly',
+                                       'default' => $request->wasPosted() ? $request->getCheck( 'curonly' ) : true,
+                               ),
+                       );
                } else {
                        $out->addWikiMsg( 'exportnohistory' );
                }
 
-               $form .= Xml::checkLabel(
-                       $this->msg( 'export-templates' )->text(),
-                       'templates',
-                       'wpExportTemplates',
-                       $request->wasPosted() ? $request->getCheck( 'templates' ) : false
-               ) . '<br />';
+               $formDescriptor += array(
+                       'templates' => array(
+                               'type' => 'check',
+                               'label-message' => 'export-templates',
+                               'name' => 'templates',
+                               'id' => 'wpExportTemplates',
+                               'default' => $request->wasPosted() ? $request->getCheck( 'templates' ) : false,
+                       ),
+               );
 
                if ( $config->get( 'ExportMaxLinkDepth' ) || $this->userCanOverrideExportDepth() ) {
-                       $form .= Xml::inputLabel(
-                               $this->msg( 'export-pagelinks' )->text(),
-                               'pagelink-depth',
-                               'pagelink-depth',
-                               20,
-                               0
-                       ) . '<br />';
+                       $formDescriptor += array(
+                               'pagelink-depth' => array(
+                                       'type' => 'text',
+                                       'name' => 'pagelink-depth',
+                                       'id' => 'pagelink-depth',
+                                       'label-message' => 'export-pagelinks',
+                                       'default' => '0',
+                                       'size' => 20,
+                               ),
+                       );
                }
 
-               /* Enable this when we can do something useful exporting/importing image information.
-               $form .= Xml::checkLabel(
-                               $this->msg( 'export-images' )->text(),
-                               'images',
-                               'wpExportImages',
-                               false
-                       ) . '<br />';
-               */
-               $form .= Xml::checkLabel(
-                       $this->msg( 'export-download' )->text(),
-                       'wpDownload',
-                       'wpDownload',
-                       $request->wasPosted() ? $request->getCheck( 'wpDownload' ) : true
-               ) . '<br />';
+               $formDescriptor += array(
+                       /* Enable this when we can do something useful exporting/importing image information.
+                       'images' => array(
+                               'type' => 'check',
+                               'name' => 'images',
+                               'id' => 'wpExportImages',
+                               'default' => false,
+                       ),*/
+                       'wpDownload' => array(
+                               'type' => 'check',
+                               'name' =>'wpDownload',
+                               'id' => 'wpDownload',
+                               'default' => $request->wasPosted() ? $request->getCheck( 'wpDownload' ) : true,
+                               'label-message' => 'export-download',
+                       ),
+               );
 
                if ( $config->get( 'ExportAllowListContributors' ) ) {
-                       $form .= Xml::checkLabel(
-                               $this->msg( 'exportlistauthors' )->text(),
-                               'listauthors',
-                               'listauthors',
-                               $request->wasPosted() ? $request->getCheck( 'listauthors' ) : false
-                       ) . '<br />';
+                       $formDescriptor += array(
+                               'listauthors' => array(
+                                       'type' => 'check',
+                                       'label-message' => 'exportlistauthors',
+                                       'default' => $request->wasPosted() ? $request->getCheck( 'listauthors' ) : false,
+                                       'name' => 'listauthors',
+                                       'id' => 'listauthors',
+                               ),
+                       );
                }
 
-               $form .= Xml::submitButton(
-                       $this->msg( 'export-submit' )->text(),
-                       Linker::tooltipAndAccesskeyAttribs( 'export' )
-               );
-               $form .= Xml::closeElement( 'form' );
-
-               $out->addHTML( $form );
+               $htmlForm = HTMLForm::factory( 'div', $formDescriptor, $this->getContext() );
+               $htmlForm->setSubmitTextMsg( 'export-submit' );
+               $htmlForm->prepareForm()->displayForm( false );
                $this->addHelpLink( 'Help:Export' );
        }
 
index 8259718..11744f6 100644 (file)
@@ -453,8 +453,7 @@ class LoginForm extends SpecialPage {
         * @return Status
         */
        public function addNewAccountInternal() {
-               global $wgAuth, $wgMemc, $wgAccountCreationThrottle,
-                       $wgMinimalPasswordLength, $wgEmailConfirmToEdit;
+               global $wgAuth, $wgMemc, $wgAccountCreationThrottle, $wgEmailConfirmToEdit;
 
                // If the user passes an invalid domain, something is fishy
                if ( !$wgAuth->validDomain( $this->mDomain ) ) {
index fc59ace..4c099b3 100644 (file)
@@ -241,7 +241,7 @@ class UploadFromUrl extends UploadBase {
                        wfDebugLog(
                                'fileupload',
                                'Short write ' . $this->nbytes . '/' . strlen( $buffer ) .
-                                       ' bytes, aborting with '  . $this->mFileSize . ' uploaded so far'
+                                       ' bytes, aborting with ' . $this->mFileSize . ' uploaded so far'
                        );
                        fclose( $this->mTmpHandle );
                        $this->mTmpHandle = false;
index cd40649..7bcf987 100644 (file)
        "badsig": "Invalid raw signature.\nCheck HTML tags.",
        "badsiglength": "Your signature is too long.\nIt must not be more than $1 {{PLURAL:$1|character|characters}} long.",
        "yourgender": "How do you prefer to be described?",
-       "gender-unknown": "I prefer not to say",
+       "gender-unknown": "When mentioning you, the software will use gender neutral words whenever possible",
        "gender-male": "He edits wiki pages",
        "gender-female": "She edits wiki pages",
        "prefs-help-gender": "Setting this preference is optional.\nThe software uses its value to address you and to mention you to others using the appropriate grammatical gender.\nThis information will be public.",
index cf3b9e4..1035d7b 100644 (file)
        "badsig": "Error message displayed when entering invalid signature in user preferences",
        "badsiglength": "Warning message that is displayed on [[Special:Preferences]] when trying to save a signature that is too long.\n\nParameters\n* $1 - the maximum number of characters that is allowed in a signature (multi-byte characters are counted as one character)",
        "yourgender": "Used in [[Special:Preferences]], first tab, in the Internationalisation section.\nThis may be customized for other languages. This should sound like a question, the answer to which can be selected in one of these:\n* {{msg-mw|gender-unknown}}\n* {{msg-mw|gender-male}}\n* {{msg-mw|gender-female}}\nThe idea is that this preference is used for speaking to the user and about the user, and the label and the preference are supposed to demonstrate it.",
-       "gender-unknown": "Used in [[Special:Preferences]], first tab, as one of the selectable options of the {{msg-mw|Yourgender}} prompt. Choosing it indicates that the grammatical gender of the user name is not to be made public, cannot be determined, or matches none of the other choices preset in the select.\n\nThis may appropriately customized for your language. It should sound like a reply to {{msg-mw|yourgender}}.",
+       "gender-unknown": "Used in [[Special:Preferences]], first tab, as one of the selectable options of the {{msg-mw|Yourgender}} prompt. Choosing it indicates that the grammatical gender of the user name is gender neutral or unknown.\n\nThis may be appropriately customized for your language. It should sound like a reply to {{msg-mw|yourgender}}.",
        "gender-male": "Used in [[Special:Preferences]], first tab, as one of the selectable options of the {{msg-mw|Yourgender}} prompt.\nChoosing it indicates that the grammatical gender of the user name should be \"male\" for those languages having a \"normal\" male grammatical gender.\n\nYou have to customize this example for your language if needed to have a sentence which varies depending on the grammatical gender.\nThe wording must demonstrate the actual usage of the option. It should sound like a reply to {{msg-mw|Yourgender}}.\n\nFor example, if the verb \"I edit\" in your language is different in masculine and feminine, translate \"I edit\" in masculine here.\nIf your language does not make a distinction at all, use sentences like \"he is male/a man\".",
        "gender-female": "Used in [[Special:Preferences]], first tab, as one of the selectable options of the {{msg-mw|Yourgender}} prompt.\nChoosing it indicates that the grammatical gender of the user name should be \"female\" for those languages having a \"normal\" female grammatical gender.\n\nYou have to customize this example for your language if needed to have a sentence which varies depending on the grammatical gender.\nThe wording must demonstrate the actual usage of the option. It should sound like a reply to {{msg-mw|Yourgender}}.\n\nFor example, if the verb \"I edit\" in your language is different in masculine and feminine, translate \"I edit\" in feminine here.\nIf your language does not make a distinction at all, use sentences like \"she is female/woman\".",
        "prefs-help-gender": "Used as additional description for {{msg-mw|yourgender}} field in [[Special:Preferences]], section {{msg-mw|prefs-i18n}}.",
index d684ed5..4adf154 100644 (file)
@@ -8,4 +8,4 @@
  *
  */
 
-$fallback = 'gom-deva';
\ No newline at end of file
+$fallback = 'gom-deva';
index 58fc505..b5cc343 100644 (file)
@@ -28,4 +28,4 @@ $namespaceNames = array(
        NS_HELP_TALK        => 'मजत_चर्चा',
        NS_CATEGORY         => 'श्रेणी',
        NS_CATEGORY_TALK    => 'श्रेणी_चर्चा',
-);
\ No newline at end of file
+);
index 0ca2a49..b0a4ca7 100644 (file)
@@ -48,8 +48,6 @@ $datePreferences = array(
 
 $defaultDateFormat = 'pnt';
 
-
-
 $dateFormats = array(
        'pnt time' => 'H:i',
        'pnt date' => 'j xg Y',
index ce95e3a..b7fe80b 100644 (file)
@@ -56,7 +56,8 @@ class ConvertExtensionToRegistration extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->mDescription = 'Converts extension entry points to the new JSON registration format';
-               $this->addArg( 'path', 'Location to the PHP entry point you wish to convert', /* $required = */ true );
+               $this->addArg( 'path', 'Location to the PHP entry point you wish to convert',
+                       /* $required = */ true );
                $this->addOption( 'skin', 'Whether to write to skin.json', false, false );
        }
 
@@ -95,7 +96,8 @@ class ConvertExtensionToRegistration extends Maintenance {
                        }
 
                        if ( isset( $this->custom[$realName] ) ) {
-                               call_user_func_array( array( $this, $this->custom[$realName] ), array( $realName, $value, $vars ) );
+                               call_user_func_array( array( $this, $this->custom[$realName] ),
+                                       array( $realName, $value, $vars ) );
                        } elseif ( in_array( $realName, $globalSettings ) ) {
                                $this->json[$realName] = $value;
                        } elseif ( array_key_exists( $realName, $this->noLongerSupportedGlobals ) ) {
@@ -133,7 +135,9 @@ class ConvertExtensionToRegistration extends Maintenance {
        protected function handleExtensionFunctions( $realName, $value ) {
                foreach ( $value as $func ) {
                        if ( $func instanceof Closure ) {
-                               $this->error( "Error: Closures cannot be converted to JSON. Please move your extension function somewhere else.", 1 );
+                               $this->error( "Error: Closures cannot be converted to JSON. " .
+                                       "Please move your extension function somewhere else.", 1
+                               );
                        }
                }
 
@@ -197,7 +201,9 @@ class ConvertExtensionToRegistration extends Maintenance {
                foreach ( $value as $hookName => $handlers ) {
                        foreach ( $handlers as $func ) {
                                if ( $func instanceof Closure ) {
-                                       $this->error( "Error: Closures cannot be converted to JSON. Please move the handler for $hookName somewhere else.", 1 );
+                                       $this->error( "Error: Closures cannot be converted to JSON. " .
+                                               "Please move the handler for $hookName somewhere else.", 1
+                                       );
                                }
                        }
                }
@@ -229,7 +235,6 @@ class ConvertExtensionToRegistration extends Maintenance {
                                }
                        }
 
-
                        $this->json[$realName][$name] = $data;
                }
                if ( $defaults ) {
index 1c71dc0..0c61633 100644 (file)
@@ -34,7 +34,7 @@ class ExportSites extends Maintenance {
 
                $handle = fopen( $file, 'w' );
 
-               if ( !$handle )  {
+               if ( !$handle ) {
                        $this->error( "Failed to open $file for writing.\n", 1 );
                }
 
@@ -51,4 +51,4 @@ class ExportSites extends Maintenance {
 }
 
 $maintClass = 'ExportSites';
-require_once( RUN_MAINTENANCE_IF_MAIN );
+require_once RUN_MAINTENANCE_IF_MAIN;
index 7abb8d7..4537943 100644 (file)
@@ -49,4 +49,4 @@ class ImportSites extends Maintenance {
 }
 
 $maintClass = 'ImportSites';
-require_once( RUN_MAINTENANCE_IF_MAIN );
+require_once RUN_MAINTENANCE_IF_MAIN;
index 37203fb..88a703e 100644 (file)
@@ -115,7 +115,7 @@ return call_user_func( function () {
                        $module['selectorWithVariant'] = '.oo-ui-image-{variant} .oo-ui-icon-{name}, .oo-ui-image-{variant}.oo-ui-icon-{name}, .mw-ui-icon-{name}-{variant}:before, .mw-ui-hovericon:hover .mw-ui-icon-{name}-{variant}-hover:before, .mw-ui-hovericon.mw-ui-icon-{name}-{variant}-hover:hover:before';
                }
 
-               $modules[ "oojs-ui.styles.$name" ] = $module;
+               $modules["oojs-ui.styles.$name"] = $module;
        }
 
        return $modules;
index 058a149..493920d 100644 (file)
@@ -10,7 +10,8 @@
                        "زكريا",
                        "مشعل الحربي",
                        "ترجمان05",
-                       "Abanima"
+                       "Abanima",
+                       "محمد أحمد عبد الفتاح"
                ]
        },
        "ooui-outline-control-move-down": "انقل العنصر للأسفل",
@@ -24,5 +25,7 @@
        "ooui-dialog-process-error": "حدث خطأ",
        "ooui-dialog-process-dismiss": "أغلق",
        "ooui-dialog-process-retry": "حاول مرة أخرى",
-       "ooui-dialog-process-continue": "استمر"
+       "ooui-dialog-process-continue": "استمر",
+       "ooui-selectfile-not-supported": "تحديد الملفات غير مدعوم",
+       "ooui-selectfile-placeholder": "لم يختر أي ملف"
 }
index d50e62d..f0fae3c 100644 (file)
@@ -19,5 +19,6 @@
        "ooui-dialog-message-reject": "Mégse",
        "ooui-dialog-process-dismiss": "Elrejt",
        "ooui-dialog-process-retry": "Próbáld újra",
-       "ooui-dialog-process-continue": "Folytatás"
+       "ooui-dialog-process-continue": "Folytatás",
+       "ooui-selectfile-placeholder": "Nincs fájl kiválasztva"
 }
index 0ff8af8..387d736 100644 (file)
@@ -12,7 +12,8 @@
                        "Minerva Titani",
                        "Raoli",
                        "Una giornata uggiosa '94",
-                       "Ontsed"
+                       "Ontsed",
+                       "Alexmar983"
                ]
        },
        "ooui-outline-control-move-down": "Sposta in basso",
@@ -26,5 +27,7 @@
        "ooui-dialog-process-error": "Qualcosa è andato storto",
        "ooui-dialog-process-dismiss": "Nascondi",
        "ooui-dialog-process-retry": "Riprova",
-       "ooui-dialog-process-continue": "Continua"
+       "ooui-dialog-process-continue": "Continua",
+       "ooui-selectfile-not-supported": "La selezione del file non è supportata",
+       "ooui-selectfile-placeholder": "Nessun file è selezionato"
 }
index ef92e49..bc3cf0b 100644 (file)
@@ -15,5 +15,8 @@
        "ooui-dialog-process-error": "Не эсе да табсыз кетди",
        "ooui-dialog-process-dismiss": "Джаб",
        "ooui-dialog-process-retry": "Энтда сынаб кёр",
-       "ooui-dialog-process-continue": "Бардыр"
+       "ooui-dialog-process-continue": "Бардыр",
+       "ooui-selectfile-not-supported": "Файл сайлау тутулмайды",
+       "ooui-selectfile-placeholder": "Бир файл да сайланмагъанды",
+       "ooui-semicolon-separator": ";"
 }
index 7c7b176..8eba859 100644 (file)
@@ -31,5 +31,6 @@
        "ooui-dialog-process-error": "Er is iets misgegaan",
        "ooui-dialog-process-dismiss": "Sluiten",
        "ooui-dialog-process-retry": "Opnieuw proberen",
-       "ooui-dialog-process-continue": "Doorgaan"
+       "ooui-dialog-process-continue": "Doorgaan",
+       "ooui-selectfile-placeholder": "Er is geen bestand geselecteerd"
 }
index 3fd8d36..3f59200 100644 (file)
@@ -14,7 +14,8 @@
                        "Spring Roll Conan",
                        "Waihorace",
                        "Cwlin0416",
-                       "LNDDYL"
+                       "LNDDYL",
+                       "Shangkuanlc"
                ]
        },
        "ooui-outline-control-move-down": "項目下移",
@@ -28,5 +29,7 @@
        "ooui-dialog-process-error": "發生不明錯誤",
        "ooui-dialog-process-dismiss": "關閉",
        "ooui-dialog-process-retry": "再試一次",
-       "ooui-dialog-process-continue": "繼續"
+       "ooui-dialog-process-continue": "繼續",
+       "ooui-selectfile-not-supported": "無法支援所選擇的檔案",
+       "ooui-selectfile-placeholder": "沒有選擇檔案"
 }
index 13e9d27..34991fd 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.11.4
+ * OOjs UI v0.11.5
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-06-09T22:03:21Z
+ * Date: 2015-06-17T00:59:03Z
  */
 @-webkit-keyframes oo-ui-progressBarWidget-slide {
        from {
 .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        margin-left: 0.25em;
 }
+.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
+       padding-left: 0.25em;
+       color: #333333;
+}
+.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:focus {
+       color: #000000;
+}
 .oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #087ecc;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
        margin-right: 0;
 }
-.oo-ui-fieldLayout-disabled .oo-ui-labelElement-label {
+.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
        color: #cccccc;
 }
 .oo-ui-actionFieldLayout-input,
        display: inline-block;
        vertical-align: middle;
 }
+.oo-ui-buttonInputWidget > button,
+.oo-ui-buttonInputWidget > input {
+       border: 0;
+       padding: 0;
+       background-color: transparent;
+}
 .oo-ui-dropdownInputWidget {
        position: relative;
        vertical-align: middle;
index 9bdac7b..e19c127 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.11.4
+ * OOjs UI v0.11.5
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-06-09T22:03:14Z
+ * Date: 2015-06-17T00:58:56Z
  */
 /**
  * @class
index 72cc1e3..76aeeac 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.11.4
+ * OOjs UI v0.11.5
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-06-09T22:03:21Z
+ * Date: 2015-06-17T00:59:03Z
  */
 @-webkit-keyframes oo-ui-progressBarWidget-slide {
        from {
        margin-left: 0.25em;
        margin-right: 0.25em;
 }
+.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
+       padding-left: 0.25em;
+       padding-right: 0.25em;
+       color: #333333;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #555555;
 }
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #444444;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
        margin-right: 0;
 }
-.oo-ui-fieldLayout-disabled .oo-ui-labelElement-label {
+.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
        color: #cccccc;
 }
 .oo-ui-actionFieldLayout-input,
        display: inline-block;
        vertical-align: middle;
 }
+.oo-ui-buttonInputWidget > button,
+.oo-ui-buttonInputWidget > input {
+       border: 0;
+       padding: 0;
+       background-color: transparent;
+}
 .oo-ui-checkboxInputWidget {
        position: relative;
        line-height: 1.6em;
index db175a5..bb4e8a9 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.11.4
+ * OOjs UI v0.11.5
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-06-09T22:03:14Z
+ * Date: 2015-06-17T00:58:56Z
  */
 /**
  * @class
index e824a8f..b4bb365 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.11.4
+ * OOjs UI v0.11.5
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-06-09T22:03:14Z
+ * Date: 2015-06-17T00:58:56Z
  */
 ( function ( OO ) {
 
@@ -13724,7 +13724,6 @@ OO.ui.RadioSelectInputWidget = function OoUiRadioSelectInputWidget( config ) {
        this.setOptions( config.options || [] );
        this.$element
                .addClass( 'oo-ui-radioSelectInputWidget' )
-               .empty()
                .append( this.radioSelectWidget.$element );
 };
 
@@ -14477,6 +14476,14 @@ OO.ui.ComboBoxWidget.prototype.getMenu = function () {
        return this.menu;
 };
 
+/**
+ * Get the combobox's text input widget.
+ * @return {OO.ui.TextInputWidget} Text input widget
+ */
+OO.ui.ComboBoxWidget.prototype.getInput = function () {
+       return this.input;
+};
+
 /**
  * Handle input change events.
  *
@@ -16894,8 +16901,10 @@ OO.mixinClass( OO.ui.RadioSelectWidget, OO.ui.mixin.TabIndexedElement );
  * @cfg {OO.ui.TextInputWidget} [input] Text input used to implement option highlighting for menu items that match
  *  the text the user types. This config is used by {@link OO.ui.ComboBoxWidget ComboBoxWidget}
  *  and {@link OO.ui.mixin.LookupElement LookupElement}
- * @cfg {OO.ui.Widget} [widget] Widget associated with the menu’s active state. If the user clicks the mouse
- *  anywhere on the page outside of this widget, the menu is hidden.
+ * @cfg {OO.ui.Widget} [widget] Widget associated with the menu's active state. If the user clicks the mouse
+ *  anywhere on the page outside of this widget, the menu is hidden. For example, if there is a button
+ *  that toggles the menu's visibility on click, the menu will be hidden then re-shown when the user clicks
+ *  that button, unless the button (or its parent widget) is passed in here.
  * @cfg {boolean} [autoHide=true] Hide the menu when the mouse is pressed outside the menu.
  */
 OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
index 1f12f2a..d4be285 100644 (file)
                        "ltr": "images/icons/lock-ltr.svg",
                        "rtl": "images/icons/lock-rtl.svg"
                }, "variants": [ "destructive" ] },
+               "ongoingConversation": { "file": {
+                       "ltr": "images/icons/ongoingConversation-ltr.svg",
+                       "rtl": "images/icons/ongoingConversation-rtl.svg"
+               } },
                "star": { "file": "images/icons/star.svg" },
                "trash": { "file": "images/icons/trash.svg" },
                "trashUndo": { "file": {
index d385eb1..a311de0 100644 (file)
@@ -25,7 +25,7 @@
                "advanced": { "file": "images/icons/advanced.svg" },
                "alert": { "file": "images/icons/alert.svg", "variants": [ "warning" ] },
                "cancel": { "file": "images/icons/cancel.svg" },
-               "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive" ] },
+               "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive", "destructive" ] },
                "circle": { "file": "images/icons/circle.svg", "variants": [ "constructive" ] },
                "close": { "file": {
                        "ltr": "images/icons/close-ltr.svg",
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.png
new file mode 100644 (file)
index 0000000..9577504
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.svg
new file mode 100644 (file)
index 0000000..7e09e65
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+    <g id="check">
+        <path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr-invert.png
new file mode 100644 (file)
index 0000000..5db6cf8
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr-invert.svg
new file mode 100644 (file)
index 0000000..5385f32
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #FFFFFF }</style>
+    <g id="ongoing-conversation" fill-rule="evenodd">
+        <path d="M17.8 18.6H2.5l2.7-2.7V6h15.3v9.9c0 1.53-1.17 2.7-2.7 2.7zm-7.542-4.95c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405-.27-.27-.405-.607-.405-.945 0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405-.27-.27-.405-.607-.405-.945 0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405-.27-.27-.405-.607-.405-.945 0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr.png
new file mode 100644 (file)
index 0000000..eff32eb
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr.svg
new file mode 100644 (file)
index 0000000..5d4b3ac
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+    <g id="ongoing-conversation" fill-rule="evenodd">
+        <path d="M17.8 18.6H2.5l2.7-2.7V6h15.3v9.9c0 1.53-1.17 2.7-2.7 2.7zm-7.542-4.95c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405-.27-.27-.405-.607-.405-.945 0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405-.27-.27-.405-.607-.405-.945 0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405-.27-.27-.405-.607-.405-.945 0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl-invert.png
new file mode 100644 (file)
index 0000000..dd93100
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl-invert.svg
new file mode 100644 (file)
index 0000000..451f247
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #FFFFFF }</style>
+    <g id="ongoing-conversation" fill-rule="evenodd">
+        <path d="M5.2 18.6h15.3l-2.7-2.7V6H2.5v9.9c0 1.53 1.17 2.7 2.7 2.7zm7.542-4.95c0 .405.135.675.405.945.27.27.607.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945-.27-.27-.608-.405-.945-.405-.338 0-.675.135-.945.405-.27.27-.405.607-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945-.27-.27-.608-.405-.945-.405-.338 0-.675.135-.945.405-.27.27-.405.608-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945-.27-.27-.607-.405-.945-.405-.337 0-.675.135-.945.405-.27.27-.405.608-.405.945z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl.png
new file mode 100644 (file)
index 0000000..9a22767
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl.svg
new file mode 100644 (file)
index 0000000..9e5b7f6
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+    <g id="ongoing-conversation" fill-rule="evenodd">
+        <path d="M5.2 18.6h15.3l-2.7-2.7V6H2.5v9.9c0 1.53 1.17 2.7 2.7 2.7zm7.542-4.95c0 .405.135.675.405.945.27.27.607.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945-.27-.27-.608-.405-.945-.405-.338 0-.675.135-.945.405-.27.27-.405.607-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945-.27-.27-.608-.405-.945-.405-.338 0-.675.135-.945.405-.27.27-.405.608-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945-.27-.27-.607-.405-.945-.405-.337 0-.675.135-.945.405-.27.27-.405.608-.405.945z"/>
+    </g>
+</svg>
index 8e7b168..29c533d 100644 (file)
                        data = {},
                        timer = null;
 
+               function stashEdit( token ) {
+                       data = $form.serializeObject();
+
+                       pending = api.post( {
+                               action: 'stashedit',
+                               token: token,
+                               title: mw.config.get( 'wgPageName' ),
+                               section: data.wpSection,
+                               sectiontitle: '',
+                               text: data.wpTextbox1,
+                               contentmodel: data.model,
+                               contentformat: data.format,
+                               baserevid: data.parentRevId
+                       } );
+               }
+
                /* Has the edit body text changed since the last stashEdit() call? */
                function isChanged() {
                        // Normalize line endings to CRLF, like $.fn.serializeObject does.
                                pending.abort();
                        }
 
-                       data = $form.serializeObject();
-                       pending = api.postWithToken( 'edit', {
-                               action: 'stashedit',
-                               title: mw.config.get( 'wgPageName' ),
-                               section: data.wpSection,
-                               sectiontitle: '',
-                               text: data.wpTextbox1,
-                               contentmodel: data.model,
-                               contentformat: data.format,
-                               baserevid: data.parentRevId
-                       } );
+                       api.getToken( 'edit' ).then( stashEdit );
                }
 
                function onKeyPress( e ) {
index 223019c..3165bb8 100644 (file)
@@ -51,7 +51,7 @@ abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
 
                $globals = array();
                foreach ( self::getSettings() as $key => $value ) {
-                       $globals[ 'wg' . $key ] = $value;
+                       $globals['wg' . $key] = $value;
                }
                $this->setMwGlobals( $globals );
        }
index e8ef180..ee1a954 100644 (file)
@@ -71,7 +71,7 @@ class ApiMainTest extends ApiTestCase {
                        new FauxRequest( array( 'action' => 'query', 'meta' => 'siteinfo' ) )
                );
                $modules = $api->getModuleManager()->getNamesWithClasses();
-               foreach( $modules as $name => $class ) {
+               foreach ( $modules as $name => $class ) {
                        $this->assertArrayHasKey(
                                $class,
                                $classes,
index 1ed571c..6f4300e 100644 (file)
@@ -1565,7 +1565,7 @@ class ApiResultTest extends MediaWikiTestCase {
 
                try {
                        $arr = array();
-                       ApiResult::setValue( $arr, 'foo',  new ApiResultTestSerializableObject(
+                       ApiResult::setValue( $arr, 'foo', new ApiResultTestSerializableObject(
                                new ApiResultTestStringifiableObject()
                        ) );
                        $this->fail( 'Expected exception not thrown' );
@@ -1579,7 +1579,7 @@ class ApiResultTest extends MediaWikiTestCase {
 
                try {
                        $arr = array();
-                       ApiResult::setValue( $arr, 'foo',  new ApiResultTestSerializableObject( NAN ) );
+                       ApiResult::setValue( $arr, 'foo', new ApiResultTestSerializableObject( NAN ) );
                        $this->fail( 'Expected exception not thrown' );
                } catch ( UnexpectedValueException $ex ) {
                        $this->assertSame(
@@ -1590,7 +1590,7 @@ class ApiResultTest extends MediaWikiTestCase {
                }
 
                $arr = array();
-               ApiResult::setValue( $arr, 'foo',  new ApiResultTestSerializableObject(
+               ApiResult::setValue( $arr, 'foo', new ApiResultTestSerializableObject(
                        array(
                                'one' => new ApiResultTestStringifiableObject( '1' ),
                                'two' => new ApiResultTestSerializableObject( 2 ),
index 5f061b5..61b992b 100644 (file)
@@ -131,7 +131,7 @@ class ApiQueryTest extends ApiTestCase {
                );
                $queryApi = new ApiQuery( $api, 'query' );
                $modules = $queryApi->getModuleManager()->getNamesWithClasses();
-               foreach( $modules as $name => $class ) {
+               foreach ( $modules as $name => $class ) {
                        $this->assertArrayHasKey(
                                $class,
                                $classes,
index 9220732..a9d3cc1 100644 (file)
@@ -26,7 +26,9 @@ class ObjectFactoryTest extends PHPUnit_Framework_TestCase {
        public function testClosureExpansionDisabled() {
                $obj = ObjectFactory::getObjectFromSpec( array(
                        'class' => 'ObjectFactoryTest_Fixture',
-                       'args' => array( function (){ return 'unwrapped'; }, ),
+                       'args' => array( function() {
+                               return 'unwrapped';
+                       }, ),
                        'closure_expansion' => false,
                ) );
                $this->assertInstanceOf( 'Closure', $obj->args[0] );
@@ -39,7 +41,9 @@ class ObjectFactoryTest extends PHPUnit_Framework_TestCase {
        public function testClosureExpansionEnabled() {
                $obj = ObjectFactory::getObjectFromSpec( array(
                        'class' => 'ObjectFactoryTest_Fixture',
-                       'args' => array( function (){ return 'unwrapped'; }, ),
+                       'args' => array( function() {
+                               return 'unwrapped';
+                       }, ),
                        'closure_expansion' => true,
                ) );
                $this->assertInternalType( 'string', $obj->args[0] );
@@ -47,7 +51,9 @@ class ObjectFactoryTest extends PHPUnit_Framework_TestCase {
 
                $obj = ObjectFactory::getObjectFromSpec( array(
                        'class' => 'ObjectFactoryTest_Fixture',
-                       'args' => array( function (){ return 'unwrapped'; }, ),
+                       'args' => array( function() {
+                               return 'unwrapped';
+                       }, ),
                ) );
                $this->assertInternalType( 'string', $obj->args[0] );
                $this->assertSame( 'unwrapped', $obj->args[0] );
@@ -56,5 +62,7 @@ class ObjectFactoryTest extends PHPUnit_Framework_TestCase {
 
 class ObjectFactoryTest_Fixture {
        public $args;
-       public function __construct( /*...*/ ) { $this->args = func_get_args(); }
+       public function __construct( /*...*/ ) {
+               $this->args = func_get_args();
+       }
 }
index 10dee83..47a83b3 100644 (file)
@@ -66,7 +66,7 @@ class WANObjectCacheTest extends MediaWikiTestCase {
 
        public function testSetOver() {
                $key = wfRandomString();
-               for ( $i=0; $i<3; ++$i ) {
+               for ( $i = 0; $i < 3; ++$i ) {
                        $value = wfRandomString();
                        $this->cache->set( $key, $value, 3 );
 
index 49a9633..bebc093 100644 (file)
@@ -32,7 +32,7 @@ class HashSiteStoreTest extends MediaWikiTestCase {
        public function testGetSites() {
                $expectedSites = array();
 
-               foreach( TestSites::getSites() as $testSite ) {
+               foreach ( TestSites::getSites() as $testSite ) {
                        $siteId = $testSite->getGlobalId();
                        $expectedSites[$siteId] = $testSite;
                }
index 19dd0aa..7be19ef 100644 (file)
@@ -53,7 +53,7 @@ class SiteExporterTest extends PHPUnit_Framework_TestCase {
                $exporter->exportSites( array( $foo, $acme ) );
 
                fseek( $tmp, 0 );
-               $xml = fread( $tmp, 16*1024 );
+               $xml = fread( $tmp, 16 * 1024 );
 
                $this->assertContains( '<sites ', $xml );
                $this->assertContains( '<site>', $xml );
@@ -133,7 +133,7 @@ class SiteExporterTest extends PHPUnit_Framework_TestCase {
                $exporter->exportSites( $sites );
 
                fseek( $tmp, 0 );
-               $xml = fread( $tmp, 16*1024 );
+               $xml = fread( $tmp, 16 * 1024 );
 
                $actualSites = new SiteList();
                $store = $this->newSiteStore( $actualSites );
index 64b195d..b11b1a9 100644 (file)
@@ -141,12 +141,12 @@ class SiteImporterTest extends PHPUnit_Framework_TestCase {
        /**
         * @dataProvider provideImportFromXML
         */
-       public function testImportFromXML( $xml, array $expectedSites, $errorCount = 0 )  {
+       public function testImportFromXML( $xml, array $expectedSites, $errorCount = 0 ) {
                $importer = $this->newSiteImporter( $expectedSites, $errorCount );
                $importer->importFromXML( $xml );
        }
 
-       public function testImportFromXML_malformed()  {
+       public function testImportFromXML_malformed() {
                $this->setExpectedException( 'Exception' );
 
                $store = $this->getMock( 'SiteStore' );
@@ -154,7 +154,7 @@ class SiteImporterTest extends PHPUnit_Framework_TestCase {
                $importer->importFromXML( 'THIS IS NOT XML' );
        }
 
-       public function testImportFromFile()  {
+       public function testImportFromFile() {
                $foo = Site::newForType( Site::TYPE_UNKNOWN );
                $foo->setGlobalId( 'Foo' );
 
index 65464c4..04b8f48 100644 (file)
@@ -360,17 +360,17 @@ class IPTest extends PHPUnit_Framework_TestCase {
        public static function provideIsPublic() {
                return array(
                        array( false, 'fc00::3' ), # RFC 4193 (local)
-                       array( false, 'fc00::ff'), # RFC 4193 (local)
-                       array( false, '127.1.2.3'), # loopback
-                       array( false, '::1'), # loopback
-                       array( false, 'fe80::1'), # link-local
-                       array( false, '169.254.1.1'), # link-local
-                       array( false, '10.0.0.1'), # RFC 1918 (private)
-                       array( false, '172.16.0.1'), # RFC 1918 (private)
-                       array( false, '192.168.0.1'), # RFC 1918 (private)
-                       array( true, '2001:5c0:1000:a::133'), # public
-                       array( true, 'fc::3'), # public
-                       array( true, '00FC::') # public
+                       array( false, 'fc00::ff' ), # RFC 4193 (local)
+                       array( false, '127.1.2.3' ), # loopback
+                       array( false, '::1' ), # loopback
+                       array( false, 'fe80::1' ), # link-local
+                       array( false, '169.254.1.1' ), # link-local
+                       array( false, '10.0.0.1' ), # RFC 1918 (private)
+                       array( false, '172.16.0.1' ), # RFC 1918 (private)
+                       array( false, '192.168.0.1' ), # RFC 1918 (private)
+                       array( true, '2001:5c0:1000:a::133' ), # public
+                       array( true, 'fc::3' ), # public
+                       array( true, '00FC::' ) # public
                );
        }
 
index 51d31aa..ccf5393 100644 (file)
@@ -19,11 +19,11 @@ class AvailableRightsTest extends PHPUnit_Framework_TestCase {
 
                $rights = User::getAllRights();
 
-               foreach( $wgGroupPermissions as $permissions ) {
+               foreach ( $wgGroupPermissions as $permissions ) {
                        $rights = array_merge( $rights, array_keys( $permissions ) );
                }
 
-               foreach( $wgRevokePermissions as $permissions ) {
+               foreach ( $wgRevokePermissions as $permissions ) {
                        $rights = array_merge( $rights, array_keys( $permissions ) );
                }
 
index c77cddc..c4e690e 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -89,7 +89,6 @@ function wfThumbHandle404() {
 function wfStreamThumb( array $params ) {
        global $wgVaryOnXFP;
 
-
        $headers = array(); // HTTP headers to send
 
        $fileName = isset( $params['f'] ) ? $params['f'] : '';