Merge "In RevisionStore, use DB_MASTER when READ_LATEST is set."
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 11 Jul 2018 09:56:15 +0000 (09:56 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 11 Jul 2018 09:56:15 +0000 (09:56 +0000)
59 files changed:
RELEASE-NOTES-1.32
includes/Block.php
includes/CommentStore.php
includes/DefaultSettings.php
includes/EditPage.php
includes/Storage/PageUpdater.php
includes/Storage/RevisionStore.php
includes/WikiReference.php
includes/actions/InfoAction.php
includes/api/ApiQueryAllDeletedRevisions.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllLinks.php
includes/api/ApiQueryContributors.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiSetPageLanguage.php
includes/api/i18n/ja.json
includes/changes/CategoryMembershipChange.php
includes/db/CloneDatabase.php
includes/htmlform/HTMLFormField.php
includes/libs/filebackend/fileop/FileOp.php
includes/libs/objectcache/MultiWriteBagOStuff.php
includes/libs/objectcache/ReplicatedBagOStuff.php
includes/logging/LogEntry.php
includes/media/FormatMetadata.php
includes/resourceloader/ResourceLoaderLanguageDataModule.php
includes/resourceloader/ResourceLoaderLanguageNamesModule.php
includes/search/SearchResultSet.php
includes/site/DBSiteStore.php
includes/specialpage/QueryPage.php
includes/specials/SpecialChangeEmail.php
includes/specials/SpecialContributions.php
includes/specials/SpecialFileDuplicateSearch.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUserrights.php
includes/specials/pagers/ProtectedPagesPager.php
languages/i18n/da.json
languages/i18n/es-formal.json
languages/i18n/hr.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/mg.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/sd.json
languages/i18n/sk.json
languages/i18n/sr-ec.json
languages/i18n/tr.json
languages/i18n/zh-hant.json
maintenance/updateSpecialPages.php
resources/Resources.php
resources/src/mediawiki.api/index.js
resources/src/mediawiki.language/mediawiki.language.init.js
tests/phpunit/ResourceLoaderTestCase.php
tests/phpunit/includes/Storage/DerivedPageDataUpdaterTest.php
tests/phpunit/includes/Storage/PageUpdaterTest.php
tests/phpunit/includes/session/CookieSessionProviderTest.php
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js

index 2b37f5e..179e970 100644 (file)
@@ -28,6 +28,7 @@ production.
   be blocked.
 * The archive table's ar_rev_id field is now unique.
 * Special:BotPasswords now requires reauthentication.
+* (T194414) The default watchlist view time has been increased from 3 to 7 days.
 
 === New features in 1.32 ===
 * (T112474) Generalized the ResourceLoader mechanism for overriding modules
index 1d2e341..a7d89e2 100644 (file)
@@ -1641,7 +1641,7 @@ class Block {
                        $reason,
                        $context->getRequest()->getIP(),
                        $this->getByName(),
-                       $systemBlockType !== null ? $systemBlockType : $this->getId(),
+                       $systemBlockType ?? $this->getId(),
                        $lang->formatExpiry( $this->mExpiry ),
                        (string)$intended,
                        $lang->userTimeAndDate( $this->mTimestamp, $context->getUser() ),
index 484b846..d03a00e 100644 (file)
@@ -138,7 +138,7 @@ class CommentStore {
         * @return string
         */
        private function getKey( $methodKey = null ) {
-               $key = $this->key !== null ? $this->key : $methodKey;
+               $key = $this->key ?? $methodKey;
                if ( $key === null ) {
                        // @codeCoverageIgnoreStart
                        throw new InvalidArgumentException( '$key should not be null' );
index 2fa3b72..2642884 100644 (file)
@@ -4865,7 +4865,7 @@ $wgDefaultUserOptions = [
        'watchdefault' => 1,
        'watchdeletion' => 0,
        'watchuploads' => 1,
-       'watchlistdays' => 3.0,
+       'watchlistdays' => 7.0,
        'watchlisthideanons' => 0,
        'watchlisthidebots' => 0,
        'watchlisthideliu' => 0,
index dfb2b43..a1cf3e2 100644 (file)
@@ -3352,7 +3352,7 @@ ERROR;
                }
 
                $this->showTextbox(
-                       $textoverride !== null ? $textoverride : $this->textbox1,
+                       $textoverride ?? $this->textbox1,
                        'wpTextbox1',
                        $attribs
                );
index 67928f9..c6795ea 100644 (file)
@@ -615,7 +615,6 @@ class PageUpdater {
                // Defend against mistakes caused by differences with the
                // signature of WikiPage::doEditContent.
                Assert::parameterType( 'integer', $flags, '$flags' );
-               Assert::parameterType( 'CommentStoreComment', $summary, '$summary' );
 
                if ( $this->wasCommitted() ) {
                        throw new RuntimeException( 'saveRevision() has already been called on this PageUpdater!' );
index 7a5c1f4..602364c 100644 (file)
@@ -1137,7 +1137,7 @@ class RevisionStore
                                if ( !property_exists( $row, 'old_flags' ) ) {
                                        throw new InvalidArgumentException( 'old_flags was not set in $row' );
                                }
-                               $blobFlags = ( $row->old_flags === null ) ? '' : $row->old_flags;
+                               $blobFlags = $row->old_flags ?? '';
                        }
 
                        $mainSlotRow->slot_revision_id = intval( $row->rev_id );
index 724ba98..d3688c8 100644 (file)
@@ -36,7 +36,7 @@ class WikiReference {
        public function __construct( $canonicalServer, $path, $server = null ) {
                $this->mCanonicalServer = $canonicalServer;
                $this->mPath = $path;
-               $this->mServer = $server === null ? $canonicalServer : $server;
+               $this->mServer = $server ?? $canonicalServer;
        }
 
        /**
index 0a4eae8..98dfeb3 100644 (file)
@@ -218,21 +218,15 @@ class InfoAction extends FormlessAction {
 
                $pageCounts = $this->pageCounts( $this->page );
 
-               $pageProperties = [];
                $props = PageProps::getInstance()->getAllProperties( $title );
-               if ( isset( $props[$id] ) ) {
-                       $pageProperties = $props[$id];
-               }
+               $pageProperties = $props[$id] ?? [];
 
                // Basic information
                $pageInfo = [];
                $pageInfo['header-basic'] = [];
 
                // Display title
-               $displayTitle = $title->getPrefixedText();
-               if ( isset( $pageProperties['displaytitle'] ) ) {
-                       $displayTitle = $pageProperties['displaytitle'];
-               }
+               $displayTitle = $pageProperties['displaytitle'] ?? $title->getPrefixedText();
 
                $pageInfo['header-basic'][] = [
                        $this->msg( 'pageinfo-display-title' ), $displayTitle
@@ -254,10 +248,7 @@ class InfoAction extends FormlessAction {
                }
 
                // Default sort key
-               $sortKey = $title->getCategorySortkey();
-               if ( isset( $pageProperties['defaultsort'] ) ) {
-                       $sortKey = $pageProperties['defaultsort'];
-               }
+               $sortKey = $pageProperties['defaultsort'] ?? $title->getCategorySortkey();
 
                $sortKey = htmlspecialchars( $sortKey );
                $pageInfo['header-basic'][] = [ $this->msg( 'pageinfo-default-sort' ), $sortKey ];
index ee13f3d..87f99dd 100644 (file)
@@ -149,11 +149,7 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                $miser_ns = null;
 
                if ( $mode == 'all' ) {
-                       if ( $params['namespace'] !== null ) {
-                               $namespaces = $params['namespace'];
-                       } else {
-                               $namespaces = MWNamespace::getValidNamespaces();
-                       }
+                       $namespaces = $params['namespace'] ?? MWNamespace::getValidNamespaces();
                        $this->addWhereFld( 'ar_namespace', $namespaces );
 
                        // For from/to/prefix, we have to consider the potential
index 14f1cc4..c7a0cbc 100644 (file)
@@ -129,15 +129,15 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                        if ( !is_null( $params['continue'] ) ) {
                                $cont = explode( '|', $params['continue'] );
                                $this->dieContinueUsageIf( count( $cont ) != 1 );
-                               $op = ( $ascendingOrder ? '>' : '<' );
+                               $op = $ascendingOrder ? '>' : '<';
                                $continueFrom = $db->addQuotes( $cont[0] );
                                $this->addWhere( "img_name $op= $continueFrom" );
                        }
 
                        // Image filters
-                       $from = ( $params['from'] === null ? null : $this->titlePartToKey( $params['from'], NS_FILE ) );
-                       $to = ( $params['to'] === null ? null : $this->titlePartToKey( $params['to'], NS_FILE ) );
-                       $this->addWhereRange( 'img_name', ( $ascendingOrder ? 'newer' : 'older' ), $from, $to );
+                       $from = $params['from'] === null ? null : $this->titlePartToKey( $params['from'], NS_FILE );
+                       $to = $params['to'] === null ? null : $this->titlePartToKey( $params['to'], NS_FILE );
+                       $this->addWhereRange( 'img_name', $ascendingOrder ? 'newer' : 'older', $from, $to );
 
                        if ( isset( $params['prefix'] ) ) {
                                $this->addWhere( 'img_name' . $db->buildLike(
@@ -210,7 +210,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                                                'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
                                        ]
                                ] ] );
-                               $groupCond = ( $params['filterbots'] == 'nobots' ? 'NULL' : 'NOT NULL' );
+                               $groupCond = $params['filterbots'] == 'nobots' ? 'NULL' : 'NOT NULL';
                                $this->addWhere( "ug_group IS $groupCond" );
                        }
                }
index 057dbb2..8377e74 100644 (file)
@@ -150,10 +150,10 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
                }
 
                // 'continue' always overrides 'from'
-               $from = $continue || $params['from'] === null ? null :
-                       $this->titlePartToKey( $params['from'], $namespace ) );
-               $to = $params['to'] === null ? null :
-                       $this->titlePartToKey( $params['to'], $namespace ) );
+               $from = $continue || $params['from'] === null ? null :
+                       $this->titlePartToKey( $params['from'], $namespace );
+               $to = $params['to'] === null ? null :
+                       $this->titlePartToKey( $params['to'], $namespace );
                $this->addWhereRange( $pfx . $fieldTitle, 'newer', $from, $to );
 
                if ( isset( $params['prefix'] ) ) {
index d07df5a..6848fcb 100644 (file)
@@ -106,7 +106,7 @@ class ApiQueryContributors extends ApiQueryBase {
                                // some other module used up all the space. Just set a dummy
                                // continue and hope it works next time.
                                $this->setContinueEnumParameter( 'continue',
-                                       $params['continue'] !== null ? $params['continue'] : '0|0'
+                                       $params['continue'] ?? '0|0'
                                );
 
                                return;
index 177b248..8994e06 100644 (file)
@@ -127,7 +127,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                        if ( count( $pageIds[NS_FILE] ) == 1 ) {
                                                // See the 'the user is screwed' comment below
                                                $this->setContinueEnumParameter( 'start',
-                                                       $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
+                                                       $start ?? wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
                                                );
                                        } else {
                                                $this->setContinueEnumParameter( 'continue',
@@ -152,7 +152,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                                // thing again. When the violating queries have been
                                                // out-continued, the result will get through
                                                $this->setContinueEnumParameter( 'start',
-                                                       $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
+                                                       $start ?? wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
                                                );
                                        } else {
                                                $this->setContinueEnumParameter( 'continue',
index 84e12d7..8fd1ed5 100644 (file)
@@ -321,7 +321,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        }
                        if ( LogEventsList::userCan( $row, LogPage::DELETED_USER, $user ) ) {
                                if ( $this->fld_user ) {
-                                       $vals['user'] = $row->user_name === null ? $row->log_user_text : $row->user_name;
+                                       $vals['user'] = $row->user_name ?? $row->log_user_text;
                                }
                                if ( $this->fld_userid ) {
                                        $vals['userid'] = intval( $row->log_user );
index 40826ae..84ab3ea 100644 (file)
@@ -80,7 +80,7 @@ class ApiSetPageLanguage extends ApiBase {
                        $this,
                        $titleObj,
                        $params['lang'],
-                       $params['reason'] === null ? '' : $params['reason'],
+                       $params['reason'] ?? '',
                        $params['tags'] ?: []
                );
 
index 84e1046..97309ff 100644 (file)
        "apihelp-compare-param-fromtitle": "比較する1つ目のページ名。",
        "apihelp-compare-param-fromid": "比較する1つ目のページID。",
        "apihelp-compare-param-fromrev": "比較する1つ目の版。",
+       "apihelp-compare-param-fromtext": "<var>fromtitle</var>, <var>fromid</var> or <var>fromrev</var> で指定された版の内容の代わりに、このテキストを使用します。",
+       "apihelp-compare-param-fromsection": "'from' の内容のうち指定された節のみを使用します。",
        "apihelp-compare-param-frompst": "<var>fromtext</var>に保存前変換を行います。",
        "apihelp-compare-param-fromcontentmodel": "<var>fromtext</var>のコンテンツモデル。指定されていない場合は、他のパラメータに基づいて推測されます。",
        "apihelp-compare-param-totitle": "比較する2つ目のページ名。",
        "apihelp-compare-param-toid": "比較する2つ目のページID。",
        "apihelp-compare-param-torev": "比較する2つ目の版。",
+       "apihelp-compare-param-tosection": "'to' の内容のうち指定された節のみを使用します。",
        "apihelp-compare-param-topst": "<var>totext</var>に保存前変換を行います。",
+       "apihelp-compare-param-tocontentmodel": "<var>totext</var> のコンテンツモデル。指定されていない場合は、他のパラメータに基づいて推測されます。",
        "apihelp-compare-param-prop": "どの情報を取得するか:",
        "apihelp-compare-paramvalue-prop-diff": "差分HTML。",
        "apihelp-compare-paramvalue-prop-diffsize": "差分HTMLのサイズ (バイト数)。",
index e745203..f1e61bb 100644 (file)
@@ -23,8 +23,6 @@
  * @since 1.27
  */
 
-use Wikimedia\Assert\Assert;
-
 class CategoryMembershipChange {
 
        const CATEGORY_ADDITION = 1;
@@ -83,11 +81,10 @@ class CategoryMembershipChange {
         *
         * @throws MWException
         */
-       public function overrideNewForCategorizationCallback( $callback ) {
+       public function overrideNewForCategorizationCallback( callable $callback ) {
                if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
                        throw new MWException( 'Cannot override newForCategorization callback in operation.' );
                }
-               Assert::parameterType( 'callable', $callback, '$callback' );
                $this->newForCategorizationCallback = $callback;
        }
 
index 20b08ed..1564fab 100644 (file)
@@ -55,7 +55,7 @@ class CloneDatabase {
                $this->db = $db;
                $this->tablesToClone = $tablesToClone;
                $this->newTablePrefix = $newTablePrefix;
-               $this->oldTablePrefix = $oldTablePrefix !== null ? $oldTablePrefix : $this->db->tablePrefix();
+               $this->oldTablePrefix = $oldTablePrefix ?? $this->db->tablePrefix();
                $this->dropCurrentTables = $dropCurrentTables;
        }
 
index 83fe65a..97e4b50 100644 (file)
@@ -968,11 +968,7 @@ abstract class HTMLFormField {
        }
 
        public function getDefault() {
-               if ( isset( $this->mDefault ) ) {
-                       return $this->mDefault;
-               } else {
-                       return null;
-               }
+               return $this->mDefault ?? null;
        }
 
        /**
index 2119289..206048b 100644 (file)
@@ -115,7 +115,7 @@ abstract class FileOp {
                if ( FileBackend::isStoragePath( $path ) ) {
                        $res = FileBackend::normalizeStoragePath( $path );
 
-                       return ( $res !== null ) ? $res : $path;
+                       return $res ?? $path;
                }
 
                return $path;
index fd45024..64bfa95 100644 (file)
@@ -250,6 +250,10 @@ class MultiWriteBagOStuff extends BagOStuff {
                return $ret;
        }
 
+       public function makeKeyInternal( $keyspace, $args ) {
+               return $this->caches[0]->makeKeyInternal( ...func_get_args() );
+       }
+
        public function makeKey( $class, $component = null ) {
                return $this->caches[0]->makeKey( ...func_get_args() );
        }
index 1c14f7c..f2c3732 100644 (file)
@@ -129,6 +129,10 @@ class ReplicatedBagOStuff extends BagOStuff {
                $this->readStore->clearLastError();
        }
 
+       public function makeKeyInternal( $keyspace, $args ) {
+               return $this->writeStore->makeKeyInternal( ...func_get_args() );
+       }
+
        public function makeKey( $class, $component = null ) {
                return $this->writeStore->makeKey( ...func_get_args() );
        }
index 39e679b..b53a486 100644 (file)
@@ -821,7 +821,7 @@ class ManualLogEntry extends LogEntryBase {
        }
 
        public function getTimestamp() {
-               $ts = $this->timestamp !== null ? $this->timestamp : wfTimestampNow();
+               $ts = $this->timestamp ?? wfTimestampNow();
 
                return wfTimestamp( TS_MW, $ts );
        }
index b98d7f1..f647a9d 100644 (file)
@@ -971,11 +971,7 @@ class FormatMetadata extends ContextSource {
 
                                        case 'LanguageCode':
                                                $lang = Language::fetchLanguageName( strtolower( $val ), $this->getLanguage()->getCode() );
-                                               if ( $lang ) {
-                                                       $val = htmlspecialchars( $lang );
-                                               } else {
-                                                       $val = htmlspecialchars( $val );
-                                               }
+                                               $val = htmlspecialchars( $lang ?: $val );
                                                break;
 
                                        default:
index f6716e7..4b24081 100644 (file)
@@ -23,9 +23,9 @@
  */
 
 /**
- * ResourceLoader module for populating language specific data.
+ * ResourceLoader module for populating language specific data, such as grammar forms.
  */
-class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
+class ResourceLoaderLanguageDataModule extends ResourceLoaderFileModule {
 
        protected $targets = [ 'desktop', 'mobile' ];
 
@@ -54,7 +54,8 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
         * @return string JavaScript code
         */
        public function getScript( ResourceLoaderContext $context ) {
-               return Xml::encodeJsCall(
+               $fileScript = parent::getScript( $context );
+               $langDataScript = Xml::encodeJsCall(
                        'mw.language.setData',
                        [
                                $context->getLanguage(),
@@ -62,6 +63,7 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
                        ],
                        ResourceLoader::inDebugMode()
                );
+               return $fileScript . $langDataScript;
        }
 
        /**
@@ -72,10 +74,9 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
        }
 
        /**
-        * @param ResourceLoaderContext|null $context
-        * @return array
+        * @return bool
         */
-       public function getDependencies( ResourceLoaderContext $context = null ) {
-               return [ 'mediawiki.language.init' ];
+       public function supportsURLLoading() {
+               return false;
        }
 }
index 72ccf66..eb09664 100644 (file)
@@ -28,7 +28,7 @@
 /**
  * ResourceLoader module for populating language specific data.
  */
-class ResourceLoaderLanguageNamesModule extends ResourceLoaderModule {
+class ResourceLoaderLanguageNamesModule extends ResourceLoaderFileModule {
 
        protected $targets = [ 'desktop', 'mobile' ];
 
@@ -64,7 +64,7 @@ class ResourceLoaderLanguageNamesModule extends ResourceLoaderModule {
         * @return array
         */
        public function getDependencies( ResourceLoaderContext $context = null ) {
-               return [ 'mediawiki.language.init' ];
+               return [ 'mediawiki.language' ];
        }
 
        /**
index 5728a52..e82779a 100644 (file)
@@ -205,7 +205,7 @@ class SearchResultSet implements Countable, IteratorAggregate {
                $it = $this->bcIterator();
                $searchResult = $it->current();
                $it->next();
-               return $searchResult === null ? false : $searchResult;
+               return $searchResult ?? false;
        }
 
        /**
@@ -338,11 +338,7 @@ class SearchResultSet implements Countable, IteratorAggregate {
                        return;
                }
                $result->setExtensionData( function () use ( $id ) {
-                       if ( isset( $this->extraData[$id] ) ) {
-                               return $this->extraData[$id];
-                       } else {
-                               return [];
-                       }
+                       return $this->extraData[$id] ?? [];
                } );
        }
 
index b1da25c..54d9e9c 100644 (file)
@@ -198,7 +198,7 @@ class DBSiteStore implements SiteStore {
                                'site_type' => $site->getType(),
                                'site_group' => $site->getGroup(),
                                'site_source' => $site->getSource(),
-                               'site_language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(),
+                               'site_language' => $site->getLanguageCode() ?? '',
                                'site_protocol' => $site->getProtocol(),
                                'site_domain' => strrev( $site->getDomain() ) . '.',
                                'site_data' => serialize( $site->getExtraData() ),
index 655b495..96f50bf 100644 (file)
@@ -865,7 +865,7 @@ abstract class QueryPage extends SpecialPage {
 
                $batch = new LinkBatch;
                foreach ( $res as $row ) {
-                       $batch->add( $ns !== null ? $ns : $row->namespace, $row->title );
+                       $batch->add( $ns ?? $row->namespace, $row->title );
                }
                $batch->execute();
 
index 4f97ba2..8cf64b1 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\Auth\AuthManager;
+use MediaWiki\Logger\LoggerFactory;
 
 /**
  * Let users change their email address.
@@ -165,6 +166,14 @@ class SpecialChangeEmail extends FormSpecialPage {
                        return $status;
                }
 
+               LoggerFactory::getInstance( 'authentication' )->info(
+                       'Changing email address for {user} from {oldemail} to {newemail}', [
+                               'user' => $user->getName(),
+                               'oldemail' => $oldaddr,
+                               'newemail' => $newaddr,
+                       ]
+               );
+
                Hooks::run( 'PrefsEmailAudit', [ $user, $oldaddr, $newaddr ] );
 
                $user->saveSettings();
index 836dfcd..f5e2b86 100644 (file)
@@ -50,11 +50,7 @@ class SpecialContributions extends IncludableSpecialPage {
                $this->opts = [];
                $request = $this->getRequest();
 
-               if ( $par !== null ) {
-                       $target = $par;
-               } else {
-                       $target = $request->getVal( 'target' );
-               }
+               $target = $par ?? $request->getVal( 'target' );
 
                if ( $request->getVal( 'contribs' ) == 'newbie' || $par === 'newbies' ) {
                        $target = 'newbies';
index e6d81c9..cf0ca48 100644 (file)
@@ -103,7 +103,7 @@ class FileDuplicateSearchPage extends QueryPage {
                $this->setHeaders();
                $this->outputHeader();
 
-               $this->filename = $par !== null ? $par : $this->getRequest()->getText( 'filename' );
+               $this->filename = $par ?? $this->getRequest()->getText( 'filename' );
                $this->file = null;
                $this->hash = '';
                $title = Title::newFromText( $this->filename, NS_FILE );
index 3741272..52db060 100644 (file)
@@ -163,7 +163,7 @@ class SpecialPageLanguage extends FormSpecialPage {
                        $this->getContext(),
                        $title,
                        $newLanguage,
-                       $data['reason'] === null ? '' : $data['reason']
+                       $data['reason'] ?? ''
                );
        }
 
index f826844..13259c9 100644 (file)
@@ -259,7 +259,7 @@ class SpecialSearch extends SpecialPage {
                        return null;
                }
 
-               return $url === null ? $title->getFullUrlForRedirect() : $url;
+               return $url ?? $title->getFullUrlForRedirect();
        }
 
        /**
index 0a35178..4205188 100644 (file)
@@ -87,11 +87,7 @@ class UserrightsPage extends SpecialPage {
 
                $out->addModules( [ 'mediawiki.special.userrights' ] );
 
-               if ( $par !== null ) {
-                       $this->mTarget = $par;
-               } else {
-                       $this->mTarget = $request->getVal( 'user' );
-               }
+               $this->mTarget = $par ?? $request->getVal( 'user' );
 
                if ( is_string( $this->mTarget ) ) {
                        $this->mTarget = trim( $this->mTarget );
index 0d4b5ab..3e97923 100644 (file)
@@ -235,7 +235,7 @@ class ProtectedPagesPager extends TablePager {
                                                $this->getUser()
                                        ) ) {
                                                $value = CommentStore::getStore()->getComment( 'log_comment', $row )->text;
-                                               $formatted = Linker::formatComment( $value !== null ? $value : '' );
+                                               $formatted = Linker::formatComment( $value ?? '' );
                                        } else {
                                                $formatted = $this->msg( 'rev-deleted-comment' )->escaped();
                                        }
index eb33c30..875e447 100644 (file)
        "savechanges": "Gem ændringer",
        "publishpage": "Offentliggør side",
        "publishchanges": "Offentliggør ændringer",
+       "savearticle-start": "Gem side...",
+       "savechanges-start": "Gem ændringer...",
+       "publishpage-start": "Offentliggør side...",
+       "publishchanges-start": "Offentliggør ændringer...",
        "preview": "Forhåndsvisning",
        "showpreview": "Forhåndsvisning",
        "showdiff": "Vis ændringer",
        "rcfilters-other-review-tools": "Andre gennemgangsværktøjer",
        "rcfilters-group-results-by-page": "Grupper resultater efter side",
        "rcfilters-activefilters": "Aktive filtre",
+       "rcfilters-activefilters-hide": "Skjul",
+       "rcfilters-activefilters-show": "Vis",
        "rcfilters-advancedfilters": "Avancerede filtre",
-       "rcfilters-limit-title": "Ændringer som skal vises",
+       "rcfilters-limit-title": "Antal resultater som skal vises",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|ændring|ændringer}}, $2",
        "rcfilters-days-title": "De sidste dage",
        "rcfilters-hours-title": "De sidste timer",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|dag|dage}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|time|timer}}",
        "rcfilters-highlighted-filters-list": "Fremhævede: $1",
        "rcfilters-quickfilters": "Gemte filtre",
-       "rcfilters-quickfilters-placeholder-title": "Ingen links gemt endnu",
+       "rcfilters-quickfilters-placeholder-title": "Ingen filtre gemt endnu",
        "rcfilters-savedqueries-defaultlabel": "Gemte filtre",
        "rcfilters-savedqueries-rename": "Omdøb",
        "rcfilters-savedqueries-setdefault": "Vælg som grundindstilling",
        "rcfilters-savedqueries-unsetdefault": "Fravælg som grundindstilling",
-       "rcfilters-savedqueries-remove": "Fjern",
+       "rcfilters-savedqueries-remove": "Slet",
        "rcfilters-savedqueries-new-name-label": "Navn",
        "rcfilters-savedqueries-new-name-placeholder": "Beskriv formålet med filteret",
        "rcfilters-savedqueries-apply-label": "Opret filter",
        "rcfilters-filtergroup-userExpLevel": "Brugerregistrering og -erfaring",
        "rcfilters-filter-user-experience-level-registered-label": "Registrerede",
        "rcfilters-filter-user-experience-level-registered-description": "Indloggede brugere",
-       "rcfilters-filter-user-experience-level-unregistered-label": "Uregistrerede",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Uregistreret",
        "rcfilters-filter-user-experience-level-unregistered-description": "Redaktører, der ikke er logget ind.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Nybegyndere",
        "rcfilters-filter-user-experience-level-newcomer-description": "Registrerede brugere som har færre end 10 redigeringer eller 4 dages aktivitet.",
        "rcfilters-filter-user-experience-level-learner-label": "Let øvede",
-       "rcfilters-filter-user-experience-level-learner-description": "Mere erfaring end \"nybegyndere\" men mindre end \"erfarne brugere\".",
+       "rcfilters-filter-user-experience-level-learner-description": "Registrerede brugere med mere erfaring end \"nybegyndere\" men mindre end \"erfarne brugere\".",
        "rcfilters-filter-user-experience-level-experienced-label": "Erfarne brugere",
        "rcfilters-filter-user-experience-level-experienced-description": "Registrerede skribenter med mere end 500 redigeringer og 30 dages aktivitet.",
        "rcfilters-filtergroup-automated": "Automatiserede bidrag",
        "rcfilters-filter-humans-label": "Menneske (ikke bot)",
        "rcfilters-filter-humans-description": "Redigeringer udført af mennesker.",
        "rcfilters-filtergroup-reviewstatus": "Gennemgangsstatus",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Redigeringer som ikke er manuelt eller automatisk mærket som patruljerede.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Upatruljerede",
+       "rcfilters-filter-reviewstatus-manual-description": "Redigeringer som manuelt er mærket som patruljeret.",
+       "rcfilters-filter-reviewstatus-manual-label": "Patruljeret manuelt",
+       "rcfilters-filter-reviewstatus-auto-label": "Autopatruljeret",
        "rcfilters-filtergroup-significance": "Betydning",
        "rcfilters-filter-minor-label": "Mindre redigeringer",
        "rcfilters-filter-minor-description": "Redigeringer som ophavsmanden har markeret som mindre.",
        "backend-fail-read": "Kunne ikke læse filen $1.",
        "backend-fail-create": "Kunne ikke gemme filen $1.",
        "backend-fail-maxsize": "Kunne ikke gemme filen $1, da den er større end {{PLURAL:$2|en byte|$2 bytes}}.",
-       "backend-fail-readonly": "Lagrings-backend \"$1\" er i øjeblikket skrivebeskyttet. Den angivne begrundelse var: \" $2 \"",
+       "backend-fail-readonly": "Lagrings-backend \"$1\" er i øjeblikket skrivebeskyttet. Den angivne begrundelse er: <em>$2</em>",
        "backend-fail-synced": "Filen \"$1\" er i en inkonsistent tilstand inden for de interne lagringsbackends",
        "backend-fail-connect": "Kunne ikke forbinde til lagringsbackend \"$1\".",
        "backend-fail-internal": "En ukendt fejl opstod i filbackend \"$1\".",
index 99d0511..3a99aaa 100644 (file)
        "mycustomjsprotected": "No tiene permiso para editar esta página JavaScript.",
        "myprivateinfoprotected": "No tiene permiso para editar su información privada.",
        "mypreferencesprotected": "No tiene permiso para editar sus preferencias.",
-       "exception-nologin-text": "Por favor inicie sesión para acceder a esta página o llevar a cabo esta acción.",
+       "exception-nologin-text": "Necesita acceder para ver esta página o llevar a cabo esta acción.",
        "exception-nologin-text-manual": "Necesita $1 para poder ver esta página o llevar a cabo esta acción.",
        "logouttext": "<strong>Su sesión ha finalizado.</strong>\n\nPuede que algunas páginas continúen mostrándose como si la sesión estuviera iniciada hasta que actualice la caché de su navegador.",
        "welcomeuser": "Le damos la bienvenida, $1.",
index cad811d..013c0b1 100644 (file)
        "rcfilters-liveupdates-button-title-off": "Prikaži nove izmjene uživo",
        "rcfilters-watchlist-markseen-button": "Označi sve izmjene kao pregledane",
        "rcfilters-watchlist-edit-watchlist-button": "Izmijeni popis praćenih stranica",
+       "rcfilters-watchlist-showupdated": "Izmjene na stranicama koje niste posjetili otkako su se izmjene dogodile istaknute su <strong>podebljanim slovima</strong>, s ispunjenim kružićima.",
        "rcfilters-preference-label": "Skrij poboljšanu inačicu nedavnih promjena",
        "rcfilters-preference-help": "Vraća natrag stanje prije redizajna sučelja 2017., te svih oruđa dodanih tada i poslije toga.",
        "rcfilters-watchlist-preference-label": "Sakrij poboljšanu inačicu popisa praćenja",
index 048f3a3..336b741 100644 (file)
        "nosuchusershort": "Ora ana panganggo mawa asma \"$1\". Coba dipriksa manèh pasang aksarané (éjaané).",
        "nouserspecified": "Panjenengan kudu milih jeneng panganggo.",
        "login-userblocked": "Panganggo iki pinalangan. Ora kena mbelu.",
-       "wrongpassword": "Tembung wadi sing diisèkaké salah.\nMangga jajalen manèh.",
+       "wrongpassword": "Jenang panganggo utawa tembung wadi kang diisèkaké salah.\nMangga jajalen manèh.",
        "wrongpasswordempty": "Tembung wadi kosong.\nJajalen manèh.",
        "passwordtooshort": "Tembung sesinglon paling sethithik cacahé {{PLURAL:$1|1 aksara|$1 aksara}}.",
        "passwordtoolong": "Tembung wadi ora kena munjuli {{PLURAL:$1|1 pralambang|$1 pralambang}}.",
        "rcfilters-group-results-by-page": "Golongaké kasilé miturut kacané",
        "rcfilters-activefilters": "Saringan murub",
        "rcfilters-advancedfilters": "Saringan lanjutan",
-       "rcfilters-limit-title": "Owahan-owahan sing arep dituduhaké",
+       "rcfilters-limit-title": "Kasil kang arep dituduhaké",
        "rcfilters-days-title": "Dina-dina sing mentas waé",
        "rcfilters-hours-title": "Jam-jam sing mentas waé",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|dina|dina}}",
        "rcfilters-quickfilters": "Saringan sumimpen",
-       "rcfilters-quickfilters-placeholder-title": "Durung ana pranala sing disimpen",
+       "rcfilters-quickfilters-placeholder-title": "Durung ana saringan kang kasimpen",
        "rcfilters-quickfilters-placeholder-description": "Saperlu nyimpen setèlaning saringan lan nganggo setèlan iku manèh ing tembé, kliken ikon markah buku ing babagan Saringan Murub ing ngisor.",
        "rcfilters-savedqueries-defaultlabel": "Saringan sumimpen",
        "rcfilters-savedqueries-rename": "Ganti jeneng",
        "rcfilters-savedqueries-add-new-title": "Simpen setèlané saringan sing saiki",
        "rcfilters-restore-default-filters": "Pulihaké saringan gawan",
        "rcfilters-clear-all-filters": "Resiki kabèh saringan",
-       "rcfilters-search-placeholder": "Saring owah-owahan anyar (lurua utawa wiwita ngetik)",
+       "rcfilters-search-placeholder": "Owah-owahan saringan (anggo menu utawa golèk jeneng saringan)",
        "rcfilters-invalid-filter": "Saringan ora sah",
        "rcfilters-empty-filter": "Ora ana saringan sing aktif. Kabèh sumbangan katuduhaké.",
        "rcfilters-filterlist-title": "Saringan",
-       "rcfilters-filterlist-whatsthis": "Apa iki?",
-       "rcfilters-filterlist-feedbacklink": "Wènèhi saran ngenani saringan (béta) sing anyar",
+       "rcfilters-filterlist-whatsthis": "Kapiyé cara nganggo iki?",
+       "rcfilters-filterlist-feedbacklink": "Kandhani awak dhéwé panemumu bab piranti saringan iki",
        "rcfilters-highlightbutton-title": "Sentrongi kasil",
        "rcfilters-highlightmenu-title": "Pilih werna",
        "rcfilters-highlightmenu-help": "Pilih werna kanggo nyentrong properti iki",
        "tag-filter-submit": "Penyaring",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tenger|Tenger}}]]: $2)",
        "tag-mw-contentmodelchange": "owahan modhèl isi",
+       "tag-mw-new-redirect": "Alihan anyar",
        "tag-mw-blank": "Ngosongaké",
        "tags-title": "Tag",
        "tags-intro": "Kaca iki isi pratélan tenger sing dienggo nandhani besutan déning piranti alus, sinartan tegesé.",
index 3c5dd6f..951289f 100644 (file)
        "savechanges": "ცვლილებების შენახვა",
        "publishpage": "გვერდის გამოქვეყნება",
        "publishchanges": "ცვლილებების შენახვა",
+       "publishchanges-start": "ცვლილებების შენახვა…",
        "preview": "წინასწარი გადახედვა",
        "showpreview": "წინასწარი გადახედვის ჩვენება",
        "showdiff": "ცვლილებების ჩვენება",
        "postedit-confirmation-created": "გვერდი შეიქმნა.",
        "postedit-confirmation-restored": "გვერდი აღდგა.",
        "postedit-confirmation-saved": "თქვენი რედაქტირება შენახულია.",
+       "postedit-confirmation-published": "თქვენი რედაქტირება შენახულია.",
        "edit-already-exists": "ახალი გვერდის შექმნა არ მოხერხდა.\nის უკვე არსებობს.",
        "defaultmessagetext": "შეტყობინების სტანდარტული ტექსტი",
        "content-failed-to-parse": "$2-ის შინაარსი არ შეესაბამება $1-ის ტიპს: $3.",
        "rcfilters-watchlist-showupdated": "ცვლილებები გვერდებზე, რომლებიც თქვენ ჯერ არ გინახავთ ამ ცვლილებების გაკეთების შემდეგ, ნაჩვენებია <strong>მუქად</strong>, განსხვავებული ფერით.",
        "rcfilters-preference-label": "ბოლო ცვლილებების გაუმჯობესებული ვერსიის დამალვა",
        "rcfilters-preference-help": "გათიშავს 2017 წლის ინტერფეისის დიზაინზე გაკეთებულ განახლებას, გაითიშება მას შემდეგ დამატებული ყველა ხელსაწყო.",
+       "rcfilters-watchlist-preference-label": "კონტროლის სიის გაუმჯობესებული ვერსიის დამალვა",
+       "rcfilters-watchlist-preference-help": "აუქმებს 2017 წლის ინტერფეისისა და ყველა ხელსაწყოს რედიზაინს დამატებულს მაშინ და შემდგომ.",
        "rcnotefrom": "ქვემოთ {{PLURAL:$5|ნაჩვენებია ცვლილება|ნაჩვენებია ცვლილებები}} <strong>$3, $4</strong>-დან (ნაჩვენებია არაუმეტეს <strong>$1</strong>).",
        "rclistfromreset": "თარიღის საწყის კონფიგურაციაზე დაბრუნება",
        "rclistfrom": "ახალი ცვლილებების ჩვენება დაწყებული $3 $2-დან",
index 95adaf8..aea1f0e 100644 (file)
        "version-libraries-license": "Fahazoan-dalana",
        "version-libraries-description": "Visavisa",
        "version-libraries-authors": "Mpamorona",
+       "redirect-summary": "Ity pejy manokana ity dia manome fihodinana mankany amina rakitra (anaran-drakitra) na pejy (ID fiovana na pejy nomena). Fampiasana:\n[[{{#Special:Redirect}}/file/Example.jpg]],\n[[{{#Special:Redirect}}/page/64308]],\n[[{{#Special:Redirect}}/revision/328429]],\n[[{{#Special:Redirect}}/user/101]], na\n[[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Alefa",
        "redirect-lookup": "Karohana:",
        "redirect-value": "Sanda:",
        "tag-filter": "manasongadina [[Special:Tags|balizy]] :",
        "tag-filter-submit": "Manasongadina",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Marika}}]]: $2)",
+       "tag-mw-new-redirect": "Fihodinana vaovao",
        "tags-title": "Balizy",
        "tags-intro": "Ity pejy ity dia manalisitra ny balizy azon'ny rindrankajy ampiasaina mba hanamarika fanovana iray sy ny dikany.",
        "tags-tag": "Anaran'ny balizy",
        "revdelete-unrestricted": "fanerena nesorina tamin'ny mpandrindra",
        "logentry-move-move": "nanova ny anaran'i $3 ho $4 i $1",
        "logentry-move-move-noredirect": "$1{{GENDER:$2|}} dia namindra ny pejy $3 ho $4 fa tsy namela fihodinana",
+       "logentry-move-move_redir": "$1 dia namindra{{GENDER:$2|}} ny pejy $3 any amin'i $4 ary nanitsaka fihodinana",
+       "logentry-patrol-patrol-auto": "$1 dia nanamarika ho azy ny{{GENDER:$2|}} fiovana $4 ny pejy $3 ho voatety",
        "logentry-newusers-newusers": "{{GENDER:$2|Noforonina}} ny kaontim-pikambana $1",
        "logentry-newusers-create": "{{GENDER:$2|Noforonina}} ny kaontim-pikambana $1",
        "logentry-newusers-create2": "{{GENDER:$2|Noforonin}}'i $1 ny kaomtim-pikambana $3",
index 23b2f66..5b61e8b 100644 (file)
        "sort-descending": "Ordenar por ordem descendente",
        "sort-ascending": "Ordenar por ordem ascendente",
        "nstab-main": "Página",
-       "nstab-user": "Página d{{GENDER:{{BASEPAGENAME}}|o usuário|a usuária|e usuário(a)}}",
+       "nstab-user": "Página {{GENDER:{{ROOTPAGENAME}}|do usuário|da usuária|de usuário(a)}}",
        "nstab-media": "Página de mídia",
        "nstab-special": "Página especial",
        "nstab-project": "Página do projeto",
        "revdelete-text-file": "Versões dos arquivos apagados continuarão a aparecer no arquivo de histórico, mas parte de seus conteúdos estarão inacessíveis ao público.",
        "logdelete-text": "Eventos de log apagados continuarão a aparecer nos logs, mas parte de seus conteúdos estarão inacessíveis ao público.",
        "revdelete-text-others": "Outros administradores do site {{SITENAME}} continuarão capazes de acessar o conteúdo oculto e podem apagá-lo pela mesma interface, a menos que restrições adicionais tenham sido feitas.",
-       "revdelete-confirm": "Por favor confirme que pretende executar esta ação, que compreende as suas consequências e que o faz em concordância com as [[{{MediaWiki:Policy-url}}|políticas e recomendações]].",
+       "revdelete-confirm": "Por favor, confirme que pretende executar esta ação, que compreende as consequências dela e que o faz em concordância com as [[{{MediaWiki:Policy-url}}|políticas e recomendações]].",
        "revdelete-suppress-text": "A supressão deverá ser usada '''apenas''' para os seguintes casos:\n* Informação potencialmente difamatória\n* Informação pessoal inapropriada\n*: ''endereços de domicílio e números de telefone, números da segurança social, etc''",
        "revdelete-legend": "Definir restrições de visualização",
        "revdelete-hide-text": "Texto de revisão",
        "datedefault": "Sem preferência",
        "prefs-labs": "Características de laboratório",
        "prefs-user-pages": "Páginas de usuário",
-       "prefs-personal": "Dados do usuário",
+       "prefs-personal": "Dados pessoais",
        "prefs-rc": "Mudanças recentes",
        "prefs-watchlist": "Lista de páginas vigiadas",
        "prefs-editwatchlist": "Editar lista de páginas vigiadas",
        "timezoneregion-pacific": "Oceano Pacífico",
        "allowemail": "Permitir que outros usuários enviem-me e-mails",
        "email-allow-new-users-label": "Permitir e-mails de novos usuários",
-       "email-blacklist-label": "Proibir que estes usuários enviem-me e-mails:",
+       "email-blacklist-label": "Proibir que estes usuários me enviem e-mails:",
        "prefs-searchoptions": "Busca",
        "prefs-namespaces": "Espaços nominais",
        "default": "padrão",
        "markaspatrolledtext-file": "Marcar esta versão de artigo como patrulhada",
        "markedaspatrolled": "Marcado como verificado",
        "markedaspatrolledtext": "A revisão selecionada de [[:$1]] foi marcada como patrulhada.",
-       "rcpatroldisabled": "Edições verificadas nas Mudanças Recentes desativadas",
-       "rcpatroldisabledtext": "A funcionalidade de Edições verificadas nas Mudanças Recentes está atualmente desativada.",
+       "rcpatroldisabled": "Edições verificadas nas mudanças recentes desativadas",
+       "rcpatroldisabledtext": "A funcionalidade de edições verificadas nas mudanças recentes está atualmente desativada.",
        "markedaspatrollederror": "Não é possível marcar como verificado",
        "markedaspatrollederrortext": "Você precisa de especificar uma revisão para poder marcar como verificado.",
        "markedaspatrollederror-noautopatrol": "Você não está autorizado a marcar suas próprias edições como edições patrulhadas.",
        "watchlistedit-clear-explain": "Todos os títulos serão removidos da sua lista de páginas vigiadas",
        "watchlistedit-clear-titles": "Títulos:",
        "watchlistedit-clear-submit": "Limpar a lista de páginas vigiadas (Esta ação é permanente!)",
-       "watchlistedit-clear-done": "Sua lista de páginas vigiadas foi limpa.",
+       "watchlistedit-clear-done": "Sua lista de páginas vigiadas foi esvaziada.",
        "watchlistedit-clear-jobqueue": "A sua lista de páginas vigiadas está a ser esvaziada. Esta operação pode ser demorada.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Foi removido um título|Foram removidos $1 títulos}}:",
        "watchlistedit-too-many": "Há muitas páginas para exibir aqui.",
index 26ec459..7dfddfb 100644 (file)
        "sort-descending": "Ordenar por ordem descendente",
        "sort-ascending": "Ordenar por ordem ascendente",
        "nstab-main": "Página",
-       "nstab-user": "Página {{GENDER:{{BASEPAGENAME}}|do utilizador|da utilizadora}}",
+       "nstab-user": "Página {{GENDER:{{ROOTPAGENAME}}|do utilizador|da utilizadora}}",
        "nstab-media": "Multimédia",
        "nstab-special": "Página especial",
        "nstab-project": "Página do projeto",
        "datedefault": "Sem preferência",
        "prefs-labs": "Funcionalidades dos laboratórios",
        "prefs-user-pages": "Páginas de utilizador",
-       "prefs-personal": "Dados do utilizador",
+       "prefs-personal": "Dados pessoais",
        "prefs-rc": "Mudanças recentes",
        "prefs-watchlist": "Páginas vigiadas",
        "prefs-editwatchlist": "Editar lista de páginas vigiadas",
        "markaspatrolledtext-file": "Marcar esta versão do ficheiro como patrulhada",
        "markedaspatrolled": "Marcada como patrulhada",
        "markedaspatrolledtext": "A edição selecionada de [[:$1]] foi marcada como patrulhada.",
-       "rcpatroldisabled": "Edições patrulhadas nas Mudanças Recentes desativadas",
-       "rcpatroldisabledtext": "A funcionalidade de edições patrulhadas nas Mudanças Recentes está atualmente desativada.",
+       "rcpatroldisabled": "Edições patrulhadas nas mudanças recentes desativadas",
+       "rcpatroldisabledtext": "A funcionalidade de edições patrulhadas nas mudanças recentes está atualmente desativada.",
        "markedaspatrollederror": "Não é possível marcar como patrulhada",
        "markedaspatrollederrortext": "É necessário especificar uma edição a ser marcada como patrulhada.",
        "markedaspatrollederror-noautopatrol": "Não está autorizado a marcar as suas próprias edições como edições patrulhadas.",
        "watchlistedit-clear-explain": "Todos os títulos serão removidos da sua lista de páginas vigiadas.",
        "watchlistedit-clear-titles": "Páginas:",
        "watchlistedit-clear-submit": "Limpar páginas vigiadas (isto é permanente!)",
-       "watchlistedit-clear-done": "A sua lista de páginas vigiadas foi limpa.",
+       "watchlistedit-clear-done": "A sua lista de páginas vigiadas foi esvaziada.",
        "watchlistedit-clear-jobqueue": "A sua lista de páginas vigiadas está a ser esvaziada. Esta operação pode ser demorada.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 página foi removida|$1 páginas foram removidas}}:",
        "watchlistedit-too-many": "Existem demasiadas páginas para apresentar.",
index 62ae7d5..fd63903 100644 (file)
        "exif-software": "مستعمل منطقگري",
        "exif-artist": "ليکڪ",
        "exif-copyright": "حق ۽ واسطا رکندڙ",
+       "exif-exifversion": "اِي ايڪس آئي ايف ورشن",
        "exif-colorspace": "رنگ پولار",
        "exif-pixelxdimension": "عڪس جي ويڪر",
        "exif-pixelydimension": "عڪس جي اوچائي",
index db457ae..326b33b 100644 (file)
        "rcfilters-watchlist-showupdated": "Zmeny stránok, ktoré ste od ich zmeny nenavštívili, sú zobrazené <strong>hrubo</strong> s vyplneným krúžkom.",
        "rcfilters-preference-label": "Skryť vylepšenú verziu posledných úprav",
        "rcfilters-preference-help": "Zruší novú podobu rozhrania z roku 2017 a všetky nástroje odvtedy pridané.",
+       "rcfilters-watchlist-preference-label": "Skryť vylepšenú verziu sledovaných stránok",
+       "rcfilters-watchlist-preference-help": "Zruší novú podobu rozhrania z roku 2017 a všetky nástroje odvtedy pridané.",
        "rcnotefrom": "Nižšie {{PLURAL:$5|je zobrazená úprava|sú zobrazené úpravy}} od <strong>$2</strong> (do <strong>$1</strong>).",
        "rclistfromreset": "Obnoviť výber údajov",
        "rclistfrom": "Zobraziť nové úpravy počnúc od $3 $2",
        "unblocked-id": "Blokovanie $1 bolo odstránené",
        "unblocked-ip": "Adresa [[Special:Contributions/$1|$1]] bola odblokovaná.",
        "blocklist": "Zablokovaní používatelia",
+       "autoblocklist": "Automatické blokovania",
+       "autoblocklist-submit": "Hľadať",
+       "autoblocklist-legend": "Zoznam automatických blokovaní",
+       "autoblocklist-localblocks": "Miestne automatické {{PLURAL:$1|blokovanie|blokovania}}",
+       "autoblocklist-total-autoblocks": "Celkový počet automatických blokovaní: $1",
+       "autoblocklist-empty": "Zoznam automatických blokovaní je prázdny.",
+       "autoblocklist-otherblocks": "Iné automatické {{PLURAL:$1|blokovanie|blokovania}}",
        "ipblocklist": "Zablokovaní používatelia",
        "ipblocklist-legend": "Nájsť zablokovaného používateľa",
        "blocklist-userblocks": "Skryť blokovania účtov",
index 9f8a351..31d3cc8 100644 (file)
        "variants": "Варијанте",
        "navigation-heading": "Навигациони мени",
        "errorpagetitle": "Грешка",
-       "returnto": "Назад на $1.",
+       "returnto": "Назад на страницу „$1“.",
        "tagline": "Извор: {{SITENAME}}",
        "help": "Помоћ",
        "search": "Претрага",
        "tooltip-ca-watch": "Додајте ову страницу на свој списак надгледања",
        "tooltip-ca-unwatch": "Уклоните ову страницу са списка надгледања",
        "tooltip-search": "Претражите пројекат {{SITENAME}}",
-       "tooltip-search-go": "Идите на страницу са тачно овим именом ако постоји",
+       "tooltip-search-go": "Идите на страницу с тачно овим именом ако постоји",
        "tooltip-search-fulltext": "Претражите странице са овим текстом",
        "tooltip-p-logo": "Посетите главну страну",
        "tooltip-n-mainpage": "Посетите главну страну",
index e5e01ba..52ad568 100644 (file)
        "rcfilters-liveupdates-button": "Canlı güncelleme",
        "rcfilters-liveupdates-button-title-on": "Canlı güncellemeyi kapat",
        "rcfilters-liveupdates-button-title-off": "Yeni değişiklikleri yapıldıkları anda görüntüleyin",
-       "rcfilters-watchlist-markseen-button": "Tüm değişiklileri görüldü olarak işaretle",
+       "rcfilters-watchlist-markseen-button": "Tüm değişiklikleri görüldü olarak işaretle",
        "rcfilters-watchlist-edit-watchlist-button": "İzlenen sayfaların listesini düzenle",
        "rcfilters-target-page-placeholder": "Bir sayfa (ya da kategori) adı girin",
        "rcnotefrom": "<strong>$3, $4</strong> tarihinden itibaren yapılan {{PLURAL:$5|değişiklik|değişiklik}} aşağıdadır (<strong>$1</strong> tarhine kadar olanlar gösterilmektedir).",
index e34c4f4..21cfdcc 100644 (file)
        "tog-watchlisthideminor": "隱藏監視清單中的次要修訂",
        "tog-watchlisthideliu": "隱藏監視清單中已登入使用者的編輯",
        "tog-watchlistreloadautomatically": "篩選條件變更時自動重新讀取監視清單(需要使用 JavaScript)",
-       "tog-watchlistunwatchlinks": "為帶有變更的監試頁面添加直接(取消)監視標記({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}),需要 JavaScript 來打開功能",
+       "tog-watchlistunwatchlinks": "為有更改的監視頁面添加直接(取消)監視標記({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}},需要JavaScript才能開啟功能)",
        "tog-watchlisthideanons": "隱藏監視清單中匿名使用者的編輯",
        "tog-watchlisthidepatrolled": "隱藏監視清單中已巡查的編輯",
        "tog-watchlisthidecategorization": "隱藏頁面分類",
index 3c4d1f9..01aace0 100644 (file)
@@ -84,7 +84,7 @@ class UpdateSpecialPages extends Maintenance {
                                if ( $queryPage->isExpensive() ) {
                                        $t1 = microtime( true );
                                        # Do the query
-                                       $num = $queryPage->recache( $limit === null ? $wgQueryCacheLimit : $limit );
+                                       $num = $queryPage->recache( $limit ?? $wgQueryCacheLimit );
                                        $t2 = microtime( true );
                                        if ( $num === false ) {
                                                $this->output( "FAILED: database error\n" );
index c41fcd6..dc8fd0c 100644 (file)
@@ -58,9 +58,6 @@ return [
        'user.options' => [ 'class' => ResourceLoaderUserOptionsModule::class ],
        'user.tokens' => [ 'class' => ResourceLoaderUserTokensModule::class ],
 
-       // Scripts for the dynamic language specific data, like grammar forms.
-       'mediawiki.language.data' => [ 'class' => ResourceLoaderLanguageDataModule::class ],
-
        /* MediaWiki base skinning modules */
 
        /**
@@ -1560,7 +1557,9 @@ return [
        /* MediaWiki Language */
 
        'mediawiki.language' => [
+               'class' => ResourceLoaderLanguageDataModule::class,
                'scripts' => [
+                       'resources/src/mediawiki.language/mediawiki.language.init.js',
                        'resources/src/mediawiki.language/mediawiki.language.js',
                        'resources/src/mediawiki.language/mediawiki.language.numbers.js',
                        'resources/src/mediawiki.language/mediawiki.language.fallback.js',
@@ -1578,10 +1577,8 @@ return [
                        'sl' => 'resources/src/mediawiki.language/languages/sl.js',
                ],
                'dependencies' => [
-                       'mediawiki.language.data',
                        'mediawiki.cldr',
                ],
-               'targets' => [ 'desktop', 'mobile' ],
                'messages' => [
                        'and',
                        'comma-separator',
@@ -1605,11 +1602,6 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
 
-       'mediawiki.language.init' => [
-               'scripts' => 'resources/src/mediawiki.language/mediawiki.language.init.js',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
-
        'mediawiki.jqueryMsg' => [
                // Add data for mediawiki.jqueryMsg, such as allowed tags
                'class' => ResourceLoaderJqueryMsgModule::class,
index 0038ed8..51f359c 100644 (file)
         *  each individual request by passing them to #get or #post (or directly #ajax) later on.
         */
        mw.Api = function ( options ) {
-               options = options || {};
+               var defaults = $.extend( {}, options ),
+                       setsUrl = options && options.ajax && options.ajax.url !== undefined;
+
+               defaults.parameters = $.extend( {}, defaultOptions.parameters, defaults.parameters );
+               defaults.ajax = $.extend( {}, defaultOptions.ajax, defaults.ajax );
 
                // Force a string if we got a mw.Uri object
-               if ( options.ajax && options.ajax.url !== undefined ) {
-                       options.ajax.url = String( options.ajax.url );
+               if ( setsUrl ) {
+                       defaults.ajax.url = String( defaults.ajax.url );
+               }
+               if ( defaults.useUS === undefined ) {
+                       defaults.useUS = !setsUrl;
                }
 
-               options = $.extend( { useUS: !options.ajax || !options.ajax.url }, options );
-
-               options.parameters = $.extend( {}, defaultOptions.parameters, options.parameters );
-               options.ajax = $.extend( {}, defaultOptions.ajax, options.ajax );
-
-               this.defaults = options;
+               this.defaults = defaults;
                this.requests = [];
        };
 
index 077473b..34add28 100644 (file)
@@ -13,8 +13,8 @@
        mw.language = {
                /**
                 * Language-related data (keyed by language, contains instances of mw.Map).
-                * Loaded dynamically (see ResourceLoaderLanguageDataModule class in PHP, registered
-                * as mediawiki.language.data on the client).
+                *
+                * Exported dynamically by the ResourceLoaderLanguageDataModule class in PHP.
                 *
                 * To set data:
                 *
index f0c78ec..cadd0ff 100644 (file)
@@ -143,7 +143,7 @@ class ResourceLoaderTestModule extends ResourceLoaderModule {
        }
 
        public function shouldEmbedModule( ResourceLoaderContext $context ) {
-               return $this->shouldEmbed !== null ? $this->shouldEmbed : parent::shouldEmbedModule( $context );
+               return $this->shouldEmbed ?? parent::shouldEmbedModule( $context );
        }
 
        public function enableModuleContentVersion() {
index 2924812..3a1f078 100644 (file)
@@ -74,7 +74,7 @@ class DerivedPageDataUpdaterTest extends MediaWikiTestCase {
                $comment = CommentStoreComment::newUnsavedComment( $summary );
 
                if ( !$content instanceof Content ) {
-                       $content = new WikitextContent( $content === null ? $summary : $content );
+                       $content = new WikitextContent( $content ?? $summary );
                }
 
                $this->getDerivedPageDataUpdater( $page ); // flush cached instance before.
index bdabf9c..f01c6ba 100644 (file)
@@ -235,7 +235,7 @@ class PageUpdaterTest extends MediaWikiTestCase {
                $comment = CommentStoreComment::newUnsavedComment( $summary );
 
                if ( !$content instanceof Content ) {
-                       $content = new TextContent( $content === null ? $summary : $content );
+                       $content = new TextContent( $content ?? $summary );
                }
 
                $updater = $page->newPageUpdater( $user );
index c1df365..aeaf273 100644 (file)
@@ -519,7 +519,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
 
                $normalExpiry = $config->get( 'CookieExpiration' );
                $extendedExpiry = $config->get( 'ExtendedLoginCookieExpiration' );
-               $extendedExpiry = (int)( $extendedExpiry === null ? 0 : $extendedExpiry );
+               $extendedExpiry = (int)( $extendedExpiry ?? 0 );
                $expect = [
                        'MySessionName' => [
                                'value' => (string)$sessionId,
index 7701170..50fd581 100644 (file)
                                        skin: mw.config.get( 'skin' ),
                                        lang: langCode,
                                        debug: mw.config.get( 'debug' ),
-                                       modules: [
-                                               'mediawiki.language.data',
-                                               'mediawiki.language'
-                                       ].join( '|' ),
+                                       modules: 'mediawiki.language',
                                        only: 'scripts'
                                },
                                dataType: 'script',
                                getMwLanguage( test.lang )
                                        .then( function ( langClass ) {
                                                var parser;
+                                               // The unit tests perform hot-reloading of mw.language (in hacky way).
+                                               // For the languages/*.js script files to work, they need to statically
+                                               // access mw.language.getData() for the "current" language.
+                                               mw.language = langClass;
                                                mw.config.set( 'wgUserLanguage', test.lang );
                                                parser = new mw.jqueryMsg.Parser( { language: langClass } );
                                                assert.strictEqual(