Merge "mediawiki.util: Only call $.fn.updateTooltipAccessKeys if accesskey is set"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 17 Aug 2018 21:18:22 +0000 (21:18 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 17 Aug 2018 21:18:22 +0000 (21:18 +0000)
63 files changed:
RELEASE-NOTES-1.32
autoload.php
docs/scripts.txt
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/Linker.php
includes/MediaWiki.php
includes/MediaWikiServices.php
includes/Message.php
includes/OutputPage.php
includes/PrefixSearch.php
includes/ServiceWiring.php
includes/Setup.php
includes/Title.php
includes/actions/SpecialPageAction.php
includes/api/ApiPageSet.php
includes/api/ApiQuerySiteinfo.php
includes/api/i18n/zh-hant.json
includes/changes/OldChangesList.php
includes/installer/MssqlUpdater.php
includes/installer/MysqlUpdater.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/libs/JavaScriptMinifier.php
includes/logging/LogPage.php
includes/parser/CoreParserFunctions.php
includes/resourceloader/ResourceLoader.php
includes/skins/Skin.php
includes/skins/SkinTemplate.php
includes/specialpage/SpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specialpage/SpecialPageFactory_deprecated.php [new file with mode: 0644]
includes/specials/SpecialSpecialpages.php
jsduck.json
languages/i18n/ce.json
languages/i18n/hy.json
languages/i18n/mni.json
languages/i18n/nn.json
languages/i18n/ro.json
languages/i18n/sr-ec.json
languages/i18n/sv.json
languages/i18n/ta.json
languages/i18n/tt-cyrl.json
maintenance/archives/patch-recentchanges-rc_this_oldid-index.sql [new file with mode: 0644]
maintenance/mssql/tables.sql
maintenance/oracle/tables.sql
maintenance/postgres/tables.sql
maintenance/tables.sql
maintenance/updateSpecialPages.php
profileinfo.php
resources/Resources.php
resources/src/jquery/jquery.expandableField.js [deleted file]
resources/src/jquery/jquery.suggestions.js
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/PrefixSearchTest.php
tests/phpunit/includes/api/ApiQuerySiteinfoTest.php
tests/phpunit/includes/libs/JavaScriptMinifierTest.php
tests/phpunit/includes/search/SearchEnginePrefixTest.php
tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php
tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php
tests/phpunit/includes/specials/SpecialSearchTest.php
tests/phpunit/structure/SpecialPageFatalTest.php

index 0ed2631..f5522a6 100644 (file)
@@ -194,6 +194,7 @@ because of Phabricator reports.
 * The mediawiki.widgets.visibleByteLimit module alias, deprecated in 1.32, was
   removed. Use mediawiki.widgets.visibleLengthLimit instead.
 * The jquery.farbtastic module, unused since 1.18, was removed.
+* The 'jquery.expandableField' module, unused since 1.22, was removed.
 * (T181318) The $wgStyleVersion setting and its appendage to various script and
   style URLs in OutputPage, deprecated in 1.31, was removed.
 * The hooks 'PreferencesFormPreSave' and 'PreferencesGetLegend' may provide
@@ -249,6 +250,8 @@ because of Phabricator reports.
   resetServiceForTesting( 'MagicWordFactory' ) on a MediaWikiServices.
 * mw.util.init() has been removed. This function is not needed anymore and was
   a no-op function since 1.30.
+* SpecialPageFactory::resetList() is a no-op.  Call overrideMwServices()
+  instead.
 
 === Deprecations in 1.32 ===
 * Use of a StartProfiler.php file is deprecated in favour of placing
@@ -348,6 +351,15 @@ because of Phabricator reports.
   methods instead.
 * PasswordFactory::init is deprecated. To get a password factory with the
   standard configuration, use MediaWikiServices::getPasswordFactory.
+* $wgContLang is deprecated, use MediaWikiServices::getContentLanguage()
+  instead.
+* $wgParser is deprecated, use MediaWikiServices::getParser() instead.
+* wfGetMainCache() is deprecated, use ObjectCache::getLocalClusterInstance()
+  instead.
+* wfGetCache() is deprecated, use ObjectCache::getInstance() instead.
+* All SpecialPageFactory static methods are deprecated. Instead, call the
+  methods on a SpecialPageFactory instance, which may be obtained from
+  MediaWikiServices.
 
 === Other changes in 1.32 ===
 * (T198811) The following tables have had their UNIQUE indexes turned into
index 1c1eeef..999d82d 100644 (file)
@@ -930,6 +930,7 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Search\\ParserOutputSearchDataExtractor' => __DIR__ . '/includes/search/ParserOutputSearchDataExtractor.php',
        'MediaWiki\\ShellDisabledError' => __DIR__ . '/includes/exception/ShellDisabledError.php',
        'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
+       'MediaWiki\\Special\\SpecialPageFactory' => __DIR__ . '/includes/specialpage/SpecialPageFactory.php',
        'MediaWiki\\User\\UserIdentity' => __DIR__ . '/includes/user/UserIdentity.php',
        'MediaWiki\\User\\UserIdentityValue' => __DIR__ . '/includes/user/UserIdentityValue.php',
        'MediaWiki\\Widget\\ComplexNamespaceInputWidget' => __DIR__ . '/includes/widget/ComplexNamespaceInputWidget.php',
@@ -1392,7 +1393,7 @@ $wgAutoloadLocalClasses = [
        'SpecialPage' => __DIR__ . '/includes/specialpage/SpecialPage.php',
        'SpecialPageAction' => __DIR__ . '/includes/actions/SpecialPageAction.php',
        'SpecialPageData' => __DIR__ . '/includes/specials/SpecialPageData.php',
-       'SpecialPageFactory' => __DIR__ . '/includes/specialpage/SpecialPageFactory.php',
+       'SpecialPageFactory' => __DIR__ . '/includes/specialpage/SpecialPageFactory_deprecated.php',
        'SpecialPageLanguage' => __DIR__ . '/includes/specials/SpecialPageLanguage.php',
        'SpecialPagesWithProp' => __DIR__ . '/includes/specials/SpecialPagesWithProp.php',
        'SpecialPasswordPolicies' => __DIR__ . '/includes/specials/SpecialPasswordPolicies.php',
index dff428c..b2501d4 100644 (file)
@@ -28,19 +28,9 @@ Primary scripts:
     that points to the search engines of the wiki.
 
   profileinfo.php
-    Allow users to see the profiling information that are stored in the
-    database.
-
-    To save the profiling information in the database (required to use this
-    script), you have to modify StartProfiler.php to use the Profiler class and
-    not the stub profiler which is enabled by default.
-    You will also need to set $wgProfiler['output'] to 'db' in LocalSettings.php
-    to force the profiler to save the informations in the database and apply the
-    maintenance/archives/patch-profiling.sql patch to the database.
-
-    To enable the profileinfo.php itself, you'll need to set $wgDBadminuser
-    and $wgDBadminpassword in your LocalSettings.php, as well as $wgEnableProfileInfo
-    See also https://www.mediawiki.org/wiki/Manual:Profiling .
+    Simple interface for displaying request profiles that were stored in the
+    database. For more information, see the documentation in that file, and at
+    https://www.mediawiki.org/wiki/Manual:Profiling.
 
   thumb.php
     Script used to resize images if it is configured to be done when the web
index e81909a..736e319 100644 (file)
@@ -6411,6 +6411,13 @@ $wgDeprecationReleaseLimit = false;
  */
 $wgProfiler = [];
 
+/**
+ * Allow the profileinfo.php entrypoint to be used.
+ *
+ * @since 1.5.0
+ */
+$wgEnableProfileInfo = false;
+
 /**
  * Only record profiling info for pages that took longer than this
  * @deprecated since 1.25: set $wgProfiler['threshold'] instead.
index 567db85..d24b74d 100644 (file)
@@ -3119,6 +3119,7 @@ function wfBCP47( $code ) {
 /**
  * Get a specific cache object.
  *
+ * @deprecated since 1.32, use ObjectCache::getInstance() instead
  * @param int|string $cacheType A CACHE_* constants, or other key in $wgObjectCaches
  * @return BagOStuff
  */
@@ -3129,11 +3130,11 @@ function wfGetCache( $cacheType ) {
 /**
  * Get the main cache object
  *
+ * @deprecated since 1.32, use ObjectCache::getLocalClusterInstance() instead
  * @return BagOStuff
  */
 function wfGetMainCache() {
-       global $wgMainCacheType;
-       return ObjectCache::getInstance( $wgMainCacheType );
+       return ObjectCache::getLocalClusterInstance();
 }
 
 /**
index 56e377d..08a5724 100644 (file)
@@ -205,7 +205,8 @@ class Linker {
         */
        public static function normaliseSpecialPage( LinkTarget $target ) {
                if ( $target->getNamespace() == NS_SPECIAL && !$target->isExternal() ) {
-                       list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $target->getDBkey() );
+                       list( $name, $subpage ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                               resolveAlias( $target->getDBkey() );
                        if ( !$name ) {
                                return $target;
                        }
index 2a84556..4636ba3 100644 (file)
@@ -250,14 +250,15 @@ class MediaWiki {
                // Redirect loops, titleless URL, $wgUsePathInfo URLs, and URLs with a variant
                } elseif ( !$this->tryNormaliseRedirect( $title ) ) {
                        // Prevent information leak via Special:MyPage et al (T109724)
+                       $spFactory = MediaWikiServices::getInstance()->getSpecialPageFactory();
                        if ( $title->isSpecialPage() ) {
-                               $specialPage = SpecialPageFactory::getPage( $title->getDBkey() );
+                               $specialPage = $spFactory->getPage( $title->getDBkey() );
                                if ( $specialPage instanceof RedirectSpecialPage ) {
                                        $specialPage->setContext( $this->context );
                                        if ( $this->config->get( 'HideIdentifiableRedirects' )
                                                && $specialPage->personallyIdentifiableTarget()
                                        ) {
-                                               list( , $subpage ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
+                                               list( , $subpage ) = $spFactory->resolveAlias( $title->getDBkey() );
                                                $target = $specialPage->getRedirect( $subpage );
                                                // target can also be true. We let that case fall through to normal processing.
                                                if ( $target instanceof Title ) {
@@ -284,7 +285,7 @@ class MediaWiki {
                        // Special pages ($title may have changed since if statement above)
                        if ( $title->isSpecialPage() ) {
                                // Actions that need to be made when we have a special pages
-                               SpecialPageFactory::executePath( $title, $this->context );
+                               $spFactory->executePath( $title, $this->context );
                        } else {
                                // ...otherwise treat it as an article view. The article
                                // may still be a wikipage redirect to another article or URL.
@@ -338,7 +339,8 @@ class MediaWiki {
                }
 
                if ( $title->isSpecialPage() ) {
-                       list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
+                       list( $name, $subpage ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                               resolveAlias( $title->getDBkey() );
                        if ( $name ) {
                                $title = SpecialPage::getTitleFor( $name, $subpage );
                        }
@@ -1055,7 +1057,8 @@ class MediaWiki {
 
                $invokedWithSuccess = true;
                if ( $sock ) {
-                       $special = SpecialPageFactory::getPage( 'RunJobs' );
+                       $special = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                               getPage( 'RunJobs' );
                        $url = $special->getPageTitle()->getCanonicalURL( $query );
                        $req = (
                                "POST $url HTTP/1.1\r\n" .
index 326c12c..f9d9aab 100644 (file)
@@ -15,6 +15,7 @@ use IBufferingStatsdDataFactory;
 use MediaWiki\Http\HttpRequestFactory;
 use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Shell\CommandFactory;
+use MediaWiki\Special\SpecialPageFactory;
 use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\BlobStoreFactory;
 use MediaWiki\Storage\NameTableStore;
@@ -828,6 +829,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'SlotRoleStore' );
        }
 
+       /**
+        * @since 1.32
+        * @return SpecialPageFactory
+        */
+       public function getSpecialPageFactory() : SpecialPageFactory {
+               return $this->getService( 'SpecialPageFactory' );
+       }
+
        /**
         * @since 1.27
         * @return IBufferingStatsdDataFactory
index e2fe254..3bd7755 100644 (file)
@@ -473,13 +473,13 @@ class Message implements MessageSpecifier, Serializable {
                global $wgForceUIMsgAsContentMsg;
 
                $contLang = MediaWikiServices::getInstance()->getContentLanguage();
+               $lang = $this->getLanguage();
                $title = $this->key;
                if (
-                       !$this->language->equals( $contLang )
+                       !$lang->equals( $contLang )
                        && in_array( $this->key, (array)$wgForceUIMsgAsContentMsg )
                ) {
-                       $code = $this->language->getCode();
-                       $title .= '/' . $code;
+                       $title .= '/' . $lang->getCode();
                }
 
                return Title::makeTitle(
index f6d5dc9..20557e9 100644 (file)
@@ -3075,7 +3075,8 @@ class OutputPage extends ContextSource {
 
                if ( $ns == NS_SPECIAL ) {
                        list( $canonicalSpecialPageName, /*...*/ ) =
-                               SpecialPageFactory::resolveAlias( $title->getDBkey() );
+                               MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                                       resolveAlias( $title->getDBkey() );
                } elseif ( $this->canUseWikiPage() ) {
                        $wikiPage = $this->getWikiPage();
                        $curRevisionId = $wikiPage->getLatest();
index e32b439..7bc7a08 100644 (file)
@@ -173,13 +173,14 @@ abstract class PrefixSearch {
                $subpageSearch = $searchParts[1] ?? null;
 
                // Handle subpage search separately.
+               $spFactory = MediaWikiServices::getInstance()->getSpecialPageFactory();
                if ( $subpageSearch !== null ) {
                        // Try matching the full search string as a page name
                        $specialTitle = Title::makeTitleSafe( NS_SPECIAL, $searchKey );
                        if ( !$specialTitle ) {
                                return [];
                        }
-                       $special = SpecialPageFactory::getPage( $specialTitle->getText() );
+                       $special = $spFactory->getPage( $specialTitle->getText() );
                        if ( $special ) {
                                $subpages = $special->prefixSearchSubpages( $subpageSearch, $limit, $offset );
                                return array_map( function ( $sub ) use ( $specialTitle ) {
@@ -198,12 +199,12 @@ abstract class PrefixSearch {
                // Unlike SpecialPage itself, we want the canonical forms of both
                // canonical and alias title forms...
                $keys = [];
-               foreach ( SpecialPageFactory::getNames() as $page ) {
+               foreach ( $spFactory->getNames() as $page ) {
                        $keys[$contLang->caseFold( $page )] = [ 'page' => $page, 'rank' => 0 ];
                }
 
                foreach ( $contLang->getSpecialPageAliases() as $page => $aliases ) {
-                       if ( !in_array( $page, SpecialPageFactory::getNames() ) ) {# T22885
+                       if ( !in_array( $page, $spFactory->getNames() ) ) {# T22885
                                continue;
                        }
 
index 344c31d..e710575 100644 (file)
@@ -48,6 +48,7 @@ use MediaWiki\MediaWikiServices;
 use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Preferences\DefaultPreferencesFactory;
 use MediaWiki\Shell\CommandFactory;
+use MediaWiki\Special\SpecialPageFactory;
 use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\BlobStoreFactory;
 use MediaWiki\Storage\NameTableStore;
@@ -545,6 +546,13 @@ return [
                );
        },
 
+       'SpecialPageFactory' => function ( MediaWikiServices $services ) : SpecialPageFactory {
+               return new SpecialPageFactory(
+                       $services->getMainConfig(),
+                       $services->getContentLanguage()
+               );
+       },
+
        'StatsdDataFactory' => function ( MediaWikiServices $services ) : IBufferingStatsdDataFactory {
                return new BufferingStatsdDataFactory(
                        rtrim( $services->getMainConfig()->get( 'StatsdMetricPrefix' ), '.' )
index 9923ae2..c015eac 100644 (file)
@@ -774,7 +774,7 @@ if ( $wgCommandLineMode ) {
        wfDebug( $debug );
 }
 
-$wgMemc = wfGetMainCache();
+$wgMemc = ObjectCache::getLocalClusterInstance();
 $messageMemc = wfGetMessageCacheStorage();
 
 wfDebugLog( 'caches',
@@ -898,6 +898,7 @@ $wgOut = RequestContext::getMain()->getOutput(); // BackCompat
 
 /**
  * @var Parser $wgParser
+ * @deprecated since 1.32, use MediaWikiServices::getParser() instead
  */
 $wgParser = new StubObject( 'wgParser', function () {
        return MediaWikiServices::getInstance()->getParser();
index 1218639..e74824c 100644 (file)
@@ -1119,7 +1119,9 @@ class Title implements LinkTarget {
         */
        public function isSpecial( $name ) {
                if ( $this->isSpecialPage() ) {
-                       list( $thisName, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $this->mDbkeyform );
+                       list( $thisName, /* $subpage */ ) =
+                               MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                                       resolveAlias( $this->mDbkeyform );
                        if ( $name == $thisName ) {
                                return true;
                        }
@@ -1135,9 +1137,10 @@ class Title implements LinkTarget {
         */
        public function fixSpecialName() {
                if ( $this->isSpecialPage() ) {
-                       list( $canonicalName, $par ) = SpecialPageFactory::resolveAlias( $this->mDbkeyform );
+                       $spFactory = MediaWikiServices::getInstance()->getSpecialPageFactory();
+                       list( $canonicalName, $par ) = $spFactory->resolveAlias( $this->mDbkeyform );
                        if ( $canonicalName ) {
-                               $localName = SpecialPageFactory::getLocalNameFor( $canonicalName, $par );
+                               $localName = $spFactory->getLocalNameFor( $canonicalName, $par );
                                if ( $localName != $this->mDbkeyform ) {
                                        return self::makeTitle( NS_SPECIAL, $localName );
                                }
@@ -2705,7 +2708,9 @@ class Title implements LinkTarget {
                        } elseif ( $this->isSpecialPage() ) {
                                # If it's a special page, ditch the subpage bit and check again
                                $name = $this->mDbkeyform;
-                               list( $name, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $name );
+                               list( $name, /* $subpage */ ) =
+                                       MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                                               resolveAlias( $name );
                                if ( $name ) {
                                        $pure = SpecialPage::getTitleFor( $name )->getPrefixedText();
                                        if ( in_array( $pure, $wgWhitelistRead, true ) ) {
@@ -4678,7 +4683,8 @@ class Title implements LinkTarget {
                                return (bool)wfFindFile( $this );
                        case NS_SPECIAL:
                                // valid special page
-                               return SpecialPageFactory::exists( $this->mDbkeyform );
+                               return MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                                       exists( $this->mDbkeyform );
                        case NS_MAIN:
                                // selflink, possibly with fragment
                                return $this->mDbkeyform == '';
index e59b6d6..8a231cb 100644 (file)
@@ -18,6 +18,8 @@
  * @ingroup Actions
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * An action that just passes the request to the relevant special page
  *
@@ -92,6 +94,7 @@ class SpecialPageAction extends FormlessAction {
                }
 
                // map actions to (whitelisted) special pages
-               return SpecialPageFactory::getPage( self::$actionToSpecialPageMapping[$action] );
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                       getPage( self::$actionToSpecialPageMapping[$action] );
        }
 }
index 3786e8d..41358cb 100644 (file)
@@ -1217,7 +1217,8 @@ class ApiPageSet extends ApiBase {
                                                $this->mAllSpecials[$ns][$dbkey] = $this->mFakePageId;
                                                $target = null;
                                                if ( $ns === NS_SPECIAL && $this->mResolveRedirects ) {
-                                                       $special = SpecialPageFactory::getPage( $dbkey );
+                                                       $spFactory = MediaWikiServices::getInstance()->getSpecialPageFactory();
+                                                       $special = $spFactory->getPage( $dbkey );
                                                        if ( $special instanceof RedirectSpecialArticle ) {
                                                                // Only RedirectSpecialArticle is intended to redirect to an article, other kinds of
                                                                // RedirectSpecialPage are probably applying weird URL parameters we don't want to handle.
@@ -1225,7 +1226,7 @@ class ApiPageSet extends ApiBase {
                                                                $context->setTitle( $titleObj );
                                                                $context->setRequest( new FauxRequest );
                                                                $special->setContext( $context );
-                                                               list( /* $alias */, $subpage ) = SpecialPageFactory::resolveAlias( $dbkey );
+                                                               list( /* $alias */, $subpage ) = $spFactory->resolveAlias( $dbkey );
                                                                $target = $special->getRedirect( $subpage );
                                                        }
                                                }
index eaa3bc1..697eab6 100644 (file)
@@ -341,8 +341,9 @@ class ApiQuerySiteinfo extends ApiQueryBase {
 
        protected function appendSpecialPageAliases( $property ) {
                $data = [];
-               $aliases = MediaWikiServices::getInstance()->getContentLanguage()->getSpecialPageAliases();
-               foreach ( SpecialPageFactory::getNames() as $specialpage ) {
+               $services = MediaWikiServices::getInstance();
+               $aliases = $services->getContentLanguage()->getSpecialPageAliases();
+               foreach ( $services->getSpecialPageFactory()->getNames() as $specialpage ) {
                        if ( isset( $aliases[$specialpage] ) ) {
                                $arr = [ 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] ];
                                ApiResult::setIndexedTagName( $arr['aliases'], 'alias' );
index 98ecec6..c7aaa18 100644 (file)
        "apihelp-query+allcategories-param-to": "終止列舉的分類。",
        "apihelp-query+allcategories-param-prefix": "搜尋以此值為開頭的所有分類標題。",
        "apihelp-query+allcategories-param-dir": "排序的方向。",
+       "apihelp-query+allcategories-param-min": "僅回傳至少有這樣多成員的分類。",
+       "apihelp-query+allcategories-param-max": "僅回傳最多有這樣多成員的分類。",
        "apihelp-query+allcategories-param-limit": "要回傳的分類數量。",
        "apihelp-query+allcategories-param-prop": "要取得的屬性。",
        "apihelp-query+allcategories-paramvalue-prop-size": "在分類裡添加頁面數。",
        "apihelp-query+allpages-param-filterredir": "要列出的頁面。",
        "apihelp-query+allpages-param-limit": "要回傳的頁面總數。",
        "apihelp-query+allredirects-summary": "列出至命名空間的所有重新導向。",
+       "apihelp-query+allredirects-paramvalue-prop-title": "添加重新導向的標題。",
        "apihelp-query+allredirects-param-namespace": "要列舉的命名空間。",
        "apihelp-query+allredirects-param-limit": "要回傳的項目總數。",
+       "apihelp-query+allredirects-param-dir": "列出時所採用的方向。",
        "apihelp-query+allredirects-example-generator": "取得包含重新導向的頁面。",
        "apihelp-query+allrevisions-summary": "列出所有修訂版本。",
        "apihelp-query+allrevisions-param-start": "起始列舉的時間戳記。",
        "apihelp-query+mystashedfiles-paramvalue-prop-size": "索取檔案大小與圖片尺寸。",
        "apihelp-query+mystashedfiles-paramvalue-prop-type": "索取檔案的 MIME 類型以及媒體類型。",
        "apihelp-query+mystashedfiles-param-limit": "要取得的檔案數量。",
+       "apihelp-query+alltransclusions-param-namespace": "要列舉的命名空間。",
        "apihelp-query+alltransclusions-param-limit": "要回傳的項目總數。",
        "apihelp-query+alltransclusions-param-dir": "列出時所採用的方向。",
        "apihelp-query+allusers-param-from": "起始列舉的使用者名稱。",
        "apihelp-query+allusers-param-dir": "排序的方向。",
        "apihelp-query+allusers-example-Y": "列出以<kbd>Y</kbd>開頭的使用者。",
        "apihelp-query+authmanagerinfo-summary": "取得目前身分核對狀態的資訊。",
+       "apihelp-query+backlinks-summary": "找出連結至指定頁面的所有頁面。",
        "apihelp-query+backlinks-param-namespace": "要列舉的命名空間。",
        "apihelp-query+backlinks-param-dir": "列出時所採用的方向。",
        "apihelp-query+blocks-summary": "列出所有被封鎖使用者與 IP 位址。",
        "apihelp-query+categorymembers-param-limit": "回傳的頁面數量上限。",
        "apihelp-query+categorymembers-param-startsortkey": "請改用 $1starthexsortkey。",
        "apihelp-query+categorymembers-param-endsortkey": "請改用 $1endhexsortkey。",
+       "apihelp-query+categorymembers-example-simple": "取得在 <kbd>Category:Physics</kbd> 裡前 10 項的頁面。",
        "apihelp-query+contributors-param-limit": "要回傳的貢獻人員數量。",
        "apihelp-query+deletedrevisions-summary": "取得已刪除修訂的資訊。",
        "apihelp-query+deletedrevisions-param-user": "此列出由該使用者作出的修訂。",
        "apihelp-query+duplicatefiles-param-limit": "要回傳的重複檔案數量。",
        "apihelp-query+duplicatefiles-param-dir": "列出時所採用的方向。",
        "apihelp-query+duplicatefiles-example-generated": "查看全部有重複到的檔案。",
+       "apihelp-query+embeddedin-param-namespace": "要列舉的命名空間。",
        "apihelp-query+embeddedin-param-dir": "列出時所採用的方向。",
        "apihelp-query+embeddedin-param-filterredir": "如何過濾重新導向。",
        "apihelp-query+embeddedin-param-limit": "要回傳的頁面總數。",
        "apihelp-query+extlinks-summary": "回傳所有指定頁面的外部 URL (非 interwiki)。",
        "apihelp-query+extlinks-param-limit": "要回傳的連結數量。",
        "apihelp-query+exturlusage-paramvalue-prop-ids": "添加頁面 ID。",
+       "apihelp-query+exturlusage-paramvalue-prop-url": "添加用於頁面的 URL。",
        "apihelp-query+exturlusage-param-namespace": "要列舉的頁面命名空間。",
        "apihelp-query+exturlusage-param-limit": "要回傳的頁面數量。",
        "apihelp-query+filearchive-param-limit": "要回傳的圖片總數。",
        "apihelp-query+imageusage-param-dir": "列出時所採用的方向。",
        "apihelp-query+info-summary": "取得基本頁面訊息。",
        "apihelp-query+info-param-prop": "要取得的額外屬性:",
+       "apihelp-query+info-paramvalue-prop-readable": "使用者是否可閱讀此頁面。",
        "apihelp-query+iwbacklinks-param-prop": "要取得的屬性。",
        "apihelp-query+iwlinks-summary": "回傳指定頁面的所有 interwiki 連結。",
        "apihelp-query+iwlinks-paramvalue-prop-url": "添加完整的 URL。",
index 7ba12fb..a2af01c 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 class OldChangesList extends ChangesList {
 
        /**
@@ -90,7 +92,8 @@ class OldChangesList extends ChangesList {
                        }
                // Log entries (old format) or log targets, and special pages
                } elseif ( $rc->mAttribs['rc_namespace'] == NS_SPECIAL ) {
-                       list( $name, $htmlubpage ) = SpecialPageFactory::resolveAlias( $rc->mAttribs['rc_title'] );
+                       list( $name, $htmlubpage ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                               resolveAlias( $rc->mAttribs['rc_title'] );
                        if ( $name == 'Log' ) {
                                $this->insertLog( $html, $rc->getTitle(), $htmlubpage );
                        }
index 50c4517..6ebf95e 100644 (file)
@@ -144,6 +144,7 @@ class MssqlUpdater extends DatabaseUpdater {
                        [ 'addIndex', 'protected_titles', 'PRIMARY', 'patch-protected_titles-pk.sql' ],
                        [ 'addIndex', 'page_props', 'PRIMARY', 'patch-page_props-pk.sql' ],
                        [ 'addIndex', 'site_identifiers', 'PRIMARY', 'patch-site_identifiers-pk.sql' ],
+                       [ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
                ];
        }
 
index ac0a520..408f2fb 100644 (file)
@@ -367,6 +367,7 @@ class MysqlUpdater extends DatabaseUpdater {
                                'patch-protected_titles-fix-pk.sql' ],
                        [ 'renameIndex', 'site_identifiers', 'site_ids_type', 'PRIMARY', false,
                                'patch-site_identifiers-fix-pk.sql' ],
+                       [ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
                ];
        }
 
index c9ed53f..fbb7696 100644 (file)
@@ -155,6 +155,7 @@ class OracleUpdater extends DatabaseUpdater {
                        [ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
                        [ 'addIndex', 'archive', 'ar_revid_uniq', 'patch-archive-ar_rev_id-unique.sql' ],
                        [ 'populateContentTables' ],
+                       [ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
 
                        // KEEP THIS AT THE BOTTOM!!
                        [ 'doRebuildDuplicateFunction' ],
index 932c941..e8663fb 100644 (file)
@@ -590,6 +590,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'addIndex', 'interwiki', 'interwiki_pkey', 'patch-interwiki-pk.sql' ],
                        [ 'addIndex', 'protected_titles', 'protected_titles_pkey', 'patch-protected_titles-pk.sql' ],
                        [ 'addIndex', 'site_identifiers', 'site_identifiers_pkey', 'patch-site_identifiers-pk.sql' ],
+                       [ 'addPgIndex', 'recentchanges', 'rc_this_oldid', '(rc_this_oldid)' ],
                ];
        }
 
index 80eb843..57bf389 100644 (file)
@@ -231,6 +231,7 @@ class SqliteUpdater extends DatabaseUpdater {
                                'patch-protected_titles-fix-pk.sql' ],
                        [ 'renameIndex', 'site_identifiers', 'site_ids_type', 'PRIMARY', false,
                                'patch-site_identifiers-fix-pk.sql' ],
+                       [ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
                ];
        }
 
index 3015825..73f3e70 100644 (file)
@@ -334,6 +334,8 @@ class JavaScriptMinifier {
                                        self::ACTION_GOTO => self::PAREN_EXPRESSION,
                                ],
                        ],
+                       // Property assignment - This is an object literal declaration.
+                       // For example: `{ key: value }`
                        self::PROPERTY_ASSIGNMENT => [
                                self::TYPE_COLON => [
                                        self::ACTION_GOTO => self::PROPERTY_EXPRESSION,
@@ -520,6 +522,7 @@ class JavaScriptMinifier {
                                        self::ACTION_GOTO => self::STATEMENT,
                                ],
                        ],
+                       // Property expression - The value of a key in an object literal.
                        self::PROPERTY_EXPRESSION => [
                                self::TYPE_BRACE_OPEN => [
                                        self::ACTION_PUSH => self::PROPERTY_EXPRESSION_OP,
@@ -547,7 +550,8 @@ class JavaScriptMinifier {
                                        self::ACTION_GOTO => self::PROPERTY_EXPRESSION,
                                ],
                                self::TYPE_HOOK => [
-                                       self::ACTION_GOTO => self::PROPERTY_EXPRESSION,
+                                       self::ACTION_PUSH => self::PROPERTY_EXPRESSION,
+                                       self::ACTION_GOTO => self::EXPRESSION_TERNARY,
                                ],
                                self::TYPE_COMMA => [
                                        self::ACTION_GOTO => self::PROPERTY_ASSIGNMENT,
index 673c929..af99940 100644 (file)
@@ -294,9 +294,11 @@ class LogPage {
                        return $title->getPrefixedText();
                }
 
-               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+               $services = MediaWikiServices::getInstance();
+               $linkRenderer = $services->getLinkRenderer();
                if ( $title->isSpecialPage() ) {
-                       list( $name, $par ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
+                       list( $name, $par ) = $services->getSpecialPageFactory()->
+                               resolveAlias( $title->getDBkey() );
 
                        # Use the language name for log titles, rather than Log/X
                        if ( $name == 'Log' ) {
index ae7ca6d..1f5308f 100644 (file)
@@ -950,7 +950,8 @@ class CoreParserFunctions {
        }
 
        public static function special( $parser, $text ) {
-               list( $page, $subpage ) = SpecialPageFactory::resolveAlias( $text );
+               list( $page, $subpage ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                       resolveAlias( $text );
                if ( $page ) {
                        $title = SpecialPage::getTitleFor( $page, $subpage );
                        return $title->getPrefixedText();
index 2b25d91..98bae24 100644 (file)
@@ -37,7 +37,7 @@ use Wikimedia\WrappedString;
  */
 class ResourceLoader implements LoggerAwareInterface {
        /** @var int */
-       protected static $filterCacheVersion = 7;
+       protected static $filterCacheVersion = 8;
 
        /** @var bool */
        protected static $debugMode = null;
index 83d02a0..69168c6 100644 (file)
@@ -449,7 +449,8 @@ abstract class Skin extends ContextSource {
                if ( $title->isSpecialPage() ) {
                        $type = 'ns-special';
                        // T25315: provide a class based on the canonical special page name without subpages
-                       list( $canonicalName ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
+                       list( $canonicalName ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                               resolveAlias( $title->getDBkey() );
                        if ( $canonicalName ) {
                                $type .= ' ' . Sanitizer::escapeClass( "mw-special-$canonicalName" );
                        } else {
index ceebf12..b44d409 100644 (file)
@@ -659,7 +659,9 @@ class SkinTemplate extends Skin {
                        # so it doesn't contain the original alias-with-subpage.
                        $origTitle = Title::newFromText( $request->getText( 'title' ) );
                        if ( $origTitle instanceof Title && $origTitle->isSpecialPage() ) {
-                               list( $spName, $spPar ) = SpecialPageFactory::resolveAlias( $origTitle->getText() );
+                               list( $spName, $spPar ) =
+                                       MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                                               resolveAlias( $origTitle->getText() );
                                $active = $spName == 'Contributions'
                                        && ( ( $spPar && $spPar == $this->username )
                                                || $request->getText( 'target' ) == $this->username );
index 13287bd..e18eacc 100644 (file)
@@ -95,7 +95,8 @@ class SpecialPage implements MessageLocalizer {
         * @return TitleValue
         */
        public static function getTitleValueFor( $name, $subpage = false, $fragment = '' ) {
-               $name = SpecialPageFactory::getLocalNameFor( $name, $subpage );
+               $name = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                       getLocalNameFor( $name, $subpage );
 
                return new TitleValue( NS_SPECIAL, $name, $fragment );
        }
@@ -108,7 +109,8 @@ class SpecialPage implements MessageLocalizer {
         * @return Title|null Title object or null if the page doesn't exist
         */
        public static function getSafeTitleFor( $name, $subpage = false ) {
-               $name = SpecialPageFactory::getLocalNameFor( $name, $subpage );
+               $name = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                       getLocalNameFor( $name, $subpage );
                if ( $name ) {
                        return Title::makeTitleSafe( NS_SPECIAL, $name );
                } else {
@@ -233,7 +235,8 @@ class SpecialPage implements MessageLocalizer {
         */
        function getLocalName() {
                if ( !isset( $this->mLocalName ) ) {
-                       $this->mLocalName = SpecialPageFactory::getLocalNameFor( $this->mName );
+                       $this->mLocalName = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                               getLocalNameFor( $this->mName );
                }
 
                return $this->mLocalName;
index 9645811..c6ffbe4 100644 (file)
  * @ingroup SpecialPage
  * @defgroup SpecialPage SpecialPage
  */
+
+namespace MediaWiki\Special;
+
+use Config;
+use Hooks;
+use IContextSource;
+use Language;
 use MediaWiki\Linker\LinkRenderer;
-use MediaWiki\MediaWikiServices;
+use Profiler;
+use RequestContext;
+use SpecialPage;
+use Title;
+use User;
 use Wikimedia\ObjectFactory;
 
 /**
@@ -43,165 +54,180 @@ use Wikimedia\ObjectFactory;
  * SpecialPageFactory::$list. To remove a core static special page at runtime, use
  * a SpecialPage_initList hook.
  *
+ * @note There are two classes called SpecialPageFactory.  You should use this first one, in
+ * namespace MediaWiki\Special, which is a service.  \SpecialPageFactory is a deprecated collection
+ * of static methods that forwards to the global service.
+ *
  * @ingroup SpecialPage
  * @since 1.17
  */
 class SpecialPageFactory {
        /**
         * List of special page names to the subclass of SpecialPage which handles them.
+        * @todo Make this a const when we drop HHVM support (T192166).  It can still be private in PHP
+        * 7.1.
         */
        private static $coreList = [
                // Maintenance Reports
-               'BrokenRedirects' => BrokenRedirectsPage::class,
-               'Deadendpages' => DeadendPagesPage::class,
-               'DoubleRedirects' => DoubleRedirectsPage::class,
-               'Longpages' => LongPagesPage::class,
-               'Ancientpages' => AncientPagesPage::class,
-               'Lonelypages' => LonelyPagesPage::class,
-               'Fewestrevisions' => FewestrevisionsPage::class,
-               'Withoutinterwiki' => WithoutInterwikiPage::class,
-               'Protectedpages' => SpecialProtectedpages::class,
-               'Protectedtitles' => SpecialProtectedtitles::class,
-               'Shortpages' => ShortPagesPage::class,
-               'Uncategorizedcategories' => UncategorizedCategoriesPage::class,
-               'Uncategorizedimages' => UncategorizedImagesPage::class,
-               'Uncategorizedpages' => UncategorizedPagesPage::class,
-               'Uncategorizedtemplates' => UncategorizedTemplatesPage::class,
-               'Unusedcategories' => UnusedCategoriesPage::class,
-               'Unusedimages' => UnusedimagesPage::class,
-               'Unusedtemplates' => UnusedtemplatesPage::class,
-               'Unwatchedpages' => UnwatchedpagesPage::class,
-               'Wantedcategories' => WantedCategoriesPage::class,
-               'Wantedfiles' => WantedFilesPage::class,
-               'Wantedpages' => WantedPagesPage::class,
-               'Wantedtemplates' => WantedTemplatesPage::class,
+               'BrokenRedirects' => \BrokenRedirectsPage::class,
+               'Deadendpages' => \DeadendPagesPage::class,
+               'DoubleRedirects' => \DoubleRedirectsPage::class,
+               'Longpages' => \LongPagesPage::class,
+               'Ancientpages' => \AncientPagesPage::class,
+               'Lonelypages' => \LonelyPagesPage::class,
+               'Fewestrevisions' => \FewestrevisionsPage::class,
+               'Withoutinterwiki' => \WithoutInterwikiPage::class,
+               'Protectedpages' => \SpecialProtectedpages::class,
+               'Protectedtitles' => \SpecialProtectedtitles::class,
+               'Shortpages' => \ShortPagesPage::class,
+               'Uncategorizedcategories' => \UncategorizedCategoriesPage::class,
+               'Uncategorizedimages' => \UncategorizedImagesPage::class,
+               'Uncategorizedpages' => \UncategorizedPagesPage::class,
+               'Uncategorizedtemplates' => \UncategorizedTemplatesPage::class,
+               'Unusedcategories' => \UnusedCategoriesPage::class,
+               'Unusedimages' => \UnusedimagesPage::class,
+               'Unusedtemplates' => \UnusedtemplatesPage::class,
+               'Unwatchedpages' => \UnwatchedpagesPage::class,
+               'Wantedcategories' => \WantedCategoriesPage::class,
+               'Wantedfiles' => \WantedFilesPage::class,
+               'Wantedpages' => \WantedPagesPage::class,
+               'Wantedtemplates' => \WantedTemplatesPage::class,
 
                // List of pages
-               'Allpages' => SpecialAllPages::class,
-               'Prefixindex' => SpecialPrefixindex::class,
-               'Categories' => SpecialCategories::class,
-               'Listredirects' => ListredirectsPage::class,
-               'PagesWithProp' => SpecialPagesWithProp::class,
-               'TrackingCategories' => SpecialTrackingCategories::class,
+               'Allpages' => \SpecialAllPages::class,
+               'Prefixindex' => \SpecialPrefixindex::class,
+               'Categories' => \SpecialCategories::class,
+               'Listredirects' => \ListredirectsPage::class,
+               'PagesWithProp' => \SpecialPagesWithProp::class,
+               'TrackingCategories' => \SpecialTrackingCategories::class,
 
                // Authentication
-               'Userlogin' => SpecialUserLogin::class,
-               'Userlogout' => SpecialUserLogout::class,
-               'CreateAccount' => SpecialCreateAccount::class,
-               'LinkAccounts' => SpecialLinkAccounts::class,
-               'UnlinkAccounts' => SpecialUnlinkAccounts::class,
-               'ChangeCredentials' => SpecialChangeCredentials::class,
-               'RemoveCredentials' => SpecialRemoveCredentials::class,
+               'Userlogin' => \SpecialUserLogin::class,
+               'Userlogout' => \SpecialUserLogout::class,
+               'CreateAccount' => \SpecialCreateAccount::class,
+               'LinkAccounts' => \SpecialLinkAccounts::class,
+               'UnlinkAccounts' => \SpecialUnlinkAccounts::class,
+               'ChangeCredentials' => \SpecialChangeCredentials::class,
+               'RemoveCredentials' => \SpecialRemoveCredentials::class,
 
                // Users and rights
-               'Activeusers' => SpecialActiveUsers::class,
-               'Block' => SpecialBlock::class,
-               'Unblock' => SpecialUnblock::class,
-               'BlockList' => SpecialBlockList::class,
-               'AutoblockList' => SpecialAutoblockList::class,
-               'ChangePassword' => SpecialChangePassword::class,
-               'BotPasswords' => SpecialBotPasswords::class,
-               'PasswordReset' => SpecialPasswordReset::class,
-               'DeletedContributions' => DeletedContributionsPage::class,
-               'Preferences' => SpecialPreferences::class,
-               'ResetTokens' => SpecialResetTokens::class,
-               'Contributions' => SpecialContributions::class,
-               'Listgrouprights' => SpecialListGroupRights::class,
-               'Listgrants' => SpecialListGrants::class,
-               'Listusers' => SpecialListUsers::class,
-               'Listadmins' => SpecialListAdmins::class,
-               'Listbots' => SpecialListBots::class,
-               'Userrights' => UserrightsPage::class,
-               'EditWatchlist' => SpecialEditWatchlist::class,
-               'PasswordPolicies' => SpecialPasswordPolicies::class,
+               'Activeusers' => \SpecialActiveUsers::class,
+               'Block' => \SpecialBlock::class,
+               'Unblock' => \SpecialUnblock::class,
+               'BlockList' => \SpecialBlockList::class,
+               'AutoblockList' => \SpecialAutoblockList::class,
+               'ChangePassword' => \SpecialChangePassword::class,
+               'BotPasswords' => \SpecialBotPasswords::class,
+               'PasswordReset' => \SpecialPasswordReset::class,
+               'DeletedContributions' => \DeletedContributionsPage::class,
+               'Preferences' => \SpecialPreferences::class,
+               'ResetTokens' => \SpecialResetTokens::class,
+               'Contributions' => \SpecialContributions::class,
+               'Listgrouprights' => \SpecialListGroupRights::class,
+               'Listgrants' => \SpecialListGrants::class,
+               'Listusers' => \SpecialListUsers::class,
+               'Listadmins' => \SpecialListAdmins::class,
+               'Listbots' => \SpecialListBots::class,
+               'Userrights' => \UserrightsPage::class,
+               'EditWatchlist' => \SpecialEditWatchlist::class,
+               'PasswordPolicies' => \SpecialPasswordPolicies::class,
 
                // Recent changes and logs
-               'Newimages' => SpecialNewFiles::class,
-               'Log' => SpecialLog::class,
-               'Watchlist' => SpecialWatchlist::class,
-               'Newpages' => SpecialNewpages::class,
-               'Recentchanges' => SpecialRecentChanges::class,
-               'Recentchangeslinked' => SpecialRecentChangesLinked::class,
-               'Tags' => SpecialTags::class,
+               'Newimages' => \SpecialNewFiles::class,
+               'Log' => \SpecialLog::class,
+               'Watchlist' => \SpecialWatchlist::class,
+               'Newpages' => \SpecialNewpages::class,
+               'Recentchanges' => \SpecialRecentChanges::class,
+               'Recentchangeslinked' => \SpecialRecentChangesLinked::class,
+               'Tags' => \SpecialTags::class,
 
                // Media reports and uploads
-               'Listfiles' => SpecialListFiles::class,
-               'Filepath' => SpecialFilepath::class,
-               'MediaStatistics' => MediaStatisticsPage::class,
-               'MIMEsearch' => MIMEsearchPage::class,
-               'FileDuplicateSearch' => FileDuplicateSearchPage::class,
-               'Upload' => SpecialUpload::class,
-               'UploadStash' => SpecialUploadStash::class,
-               'ListDuplicatedFiles' => ListDuplicatedFilesPage::class,
+               'Listfiles' => \SpecialListFiles::class,
+               'Filepath' => \SpecialFilepath::class,
+               'MediaStatistics' => \MediaStatisticsPage::class,
+               'MIMEsearch' => \MIMEsearchPage::class,
+               'FileDuplicateSearch' => \FileDuplicateSearchPage::class,
+               'Upload' => \SpecialUpload::class,
+               'UploadStash' => \SpecialUploadStash::class,
+               'ListDuplicatedFiles' => \ListDuplicatedFilesPage::class,
 
                // Data and tools
-               'ApiSandbox' => SpecialApiSandbox::class,
-               'Statistics' => SpecialStatistics::class,
-               'Allmessages' => SpecialAllMessages::class,
-               'Version' => SpecialVersion::class,
-               'Lockdb' => SpecialLockdb::class,
-               'Unlockdb' => SpecialUnlockdb::class,
+               'ApiSandbox' => \SpecialApiSandbox::class,
+               'Statistics' => \SpecialStatistics::class,
+               'Allmessages' => \SpecialAllMessages::class,
+               'Version' => \SpecialVersion::class,
+               'Lockdb' => \SpecialLockdb::class,
+               'Unlockdb' => \SpecialUnlockdb::class,
 
                // Redirecting special pages
-               'LinkSearch' => LinkSearchPage::class,
-               'Randompage' => RandomPage::class,
-               'RandomInCategory' => SpecialRandomInCategory::class,
-               'Randomredirect' => SpecialRandomredirect::class,
-               'Randomrootpage' => SpecialRandomrootpage::class,
-               'GoToInterwiki' => SpecialGoToInterwiki::class,
+               'LinkSearch' => \LinkSearchPage::class,
+               'Randompage' => \RandomPage::class,
+               'RandomInCategory' => \SpecialRandomInCategory::class,
+               'Randomredirect' => \SpecialRandomredirect::class,
+               'Randomrootpage' => \SpecialRandomrootpage::class,
+               'GoToInterwiki' => \SpecialGoToInterwiki::class,
 
                // High use pages
-               'Mostlinkedcategories' => MostlinkedCategoriesPage::class,
-               'Mostimages' => MostimagesPage::class,
-               'Mostinterwikis' => MostinterwikisPage::class,
-               'Mostlinked' => MostlinkedPage::class,
-               'Mostlinkedtemplates' => MostlinkedTemplatesPage::class,
-               'Mostcategories' => MostcategoriesPage::class,
-               'Mostrevisions' => MostrevisionsPage::class,
+               'Mostlinkedcategories' => \MostlinkedCategoriesPage::class,
+               'Mostimages' => \MostimagesPage::class,
+               'Mostinterwikis' => \MostinterwikisPage::class,
+               'Mostlinked' => \MostlinkedPage::class,
+               'Mostlinkedtemplates' => \MostlinkedTemplatesPage::class,
+               'Mostcategories' => \MostcategoriesPage::class,
+               'Mostrevisions' => \MostrevisionsPage::class,
 
                // Page tools
-               'ComparePages' => SpecialComparePages::class,
-               'Export' => SpecialExport::class,
-               'Import' => SpecialImport::class,
-               'Undelete' => SpecialUndelete::class,
-               'Whatlinkshere' => SpecialWhatLinksHere::class,
-               'MergeHistory' => SpecialMergeHistory::class,
-               'ExpandTemplates' => SpecialExpandTemplates::class,
+               'ComparePages' => \SpecialComparePages::class,
+               'Export' => \SpecialExport::class,
+               'Import' => \SpecialImport::class,
+               'Undelete' => \SpecialUndelete::class,
+               'Whatlinkshere' => \SpecialWhatLinksHere::class,
+               'MergeHistory' => \SpecialMergeHistory::class,
+               'ExpandTemplates' => \SpecialExpandTemplates::class,
 
                // Other
-               'Booksources' => SpecialBookSources::class,
+               'Booksources' => \SpecialBookSources::class,
 
                // Unlisted / redirects
-               'ApiHelp' => SpecialApiHelp::class,
-               'Blankpage' => SpecialBlankpage::class,
-               'Diff' => SpecialDiff::class,
-               'EditTags' => SpecialEditTags::class,
-               'Emailuser' => SpecialEmailUser::class,
-               'Movepage' => MovePageForm::class,
-               'Mycontributions' => SpecialMycontributions::class,
-               'MyLanguage' => SpecialMyLanguage::class,
-               'Mypage' => SpecialMypage::class,
-               'Mytalk' => SpecialMytalk::class,
-               'Myuploads' => SpecialMyuploads::class,
-               'AllMyUploads' => SpecialAllMyUploads::class,
-               'PermanentLink' => SpecialPermanentLink::class,
-               'Redirect' => SpecialRedirect::class,
-               'Revisiondelete' => SpecialRevisionDelete::class,
-               'RunJobs' => SpecialRunJobs::class,
-               'Specialpages' => SpecialSpecialpages::class,
-               'PageData' => SpecialPageData::class,
+               'ApiHelp' => \SpecialApiHelp::class,
+               'Blankpage' => \SpecialBlankpage::class,
+               'Diff' => \SpecialDiff::class,
+               'EditTags' => \SpecialEditTags::class,
+               'Emailuser' => \SpecialEmailUser::class,
+               'Movepage' => \MovePageForm::class,
+               'Mycontributions' => \SpecialMycontributions::class,
+               'MyLanguage' => \SpecialMyLanguage::class,
+               'Mypage' => \SpecialMypage::class,
+               'Mytalk' => \SpecialMytalk::class,
+               'Myuploads' => \SpecialMyuploads::class,
+               'AllMyUploads' => \SpecialAllMyUploads::class,
+               'PermanentLink' => \SpecialPermanentLink::class,
+               'Redirect' => \SpecialRedirect::class,
+               'Revisiondelete' => \SpecialRevisionDelete::class,
+               'RunJobs' => \SpecialRunJobs::class,
+               'Specialpages' => \SpecialSpecialpages::class,
+               'PageData' => \SpecialPageData::class,
        ];
 
-       private static $list;
-       private static $aliases;
+       /** @var array Special page name => class name */
+       private $list;
+
+       /** @var array */
+       private $aliases;
+
+       /** @var Config */
+       private $config;
+
+       /** @var Language */
+       private $contLang;
 
        /**
-        * Reset the internal list of special pages. Useful when changing $wgSpecialPages after
-        * the internal list has already been initialized, e.g. during testing.
+        * @param Config $config
+        * @param Language $contLang
         */
-       public static function resetList() {
-               self::$list = null;
-               self::$aliases = null;
+       public function __construct( Config $config, Language $contLang ) {
+               $this->config = $config;
+               $this->contLang = $contLang;
        }
 
        /**
@@ -210,8 +236,8 @@ class SpecialPageFactory {
         *
         * @return string[]
         */
-       public static function getNames() {
-               return array_keys( self::getPageList() );
+       public function getNames() : array {
+               return array_keys( $this->getPageList() );
        }
 
        /**
@@ -219,49 +245,44 @@ class SpecialPageFactory {
         *
         * @return array
         */
-       private static function getPageList() {
-               global $wgSpecialPages;
-               global $wgDisableInternalSearch, $wgEmailAuthentication;
-               global $wgEnableEmail, $wgEnableJavaScriptTest;
-               global $wgPageLanguageUseDB, $wgContentHandlerUseDB;
-
-               if ( !is_array( self::$list ) ) {
-                       self::$list = self::$coreList;
+       private function getPageList() : array {
+               if ( !is_array( $this->list ) ) {
+                       $this->list = self::$coreList;
 
-                       if ( !$wgDisableInternalSearch ) {
-                               self::$list['Search'] = SpecialSearch::class;
+                       if ( !$this->config->get( 'DisableInternalSearch' ) ) {
+                               $this->list['Search'] = \SpecialSearch::class;
                        }
 
-                       if ( $wgEmailAuthentication ) {
-                               self::$list['Confirmemail'] = EmailConfirmation::class;
-                               self::$list['Invalidateemail'] = EmailInvalidation::class;
+                       if ( $this->config->get( 'EmailAuthentication' ) ) {
+                               $this->list['Confirmemail'] = \EmailConfirmation::class;
+                               $this->list['Invalidateemail'] = \EmailInvalidation::class;
                        }
 
-                       if ( $wgEnableEmail ) {
-                               self::$list['ChangeEmail'] = SpecialChangeEmail::class;
+                       if ( $this->config->get( 'EnableEmail' ) ) {
+                               $this->list['ChangeEmail'] = \SpecialChangeEmail::class;
                        }
 
-                       if ( $wgEnableJavaScriptTest ) {
-                               self::$list['JavaScriptTest'] = SpecialJavaScriptTest::class;
+                       if ( $this->config->get( 'EnableJavaScriptTest' ) ) {
+                               $this->list['JavaScriptTest'] = \SpecialJavaScriptTest::class;
                        }
 
-                       if ( $wgPageLanguageUseDB ) {
-                               self::$list['PageLanguage'] = SpecialPageLanguage::class;
+                       if ( $this->config->get( 'PageLanguageUseDB' ) ) {
+                               $this->list['PageLanguage'] = \SpecialPageLanguage::class;
                        }
-                       if ( $wgContentHandlerUseDB ) {
-                               self::$list['ChangeContentModel'] = SpecialChangeContentModel::class;
+                       if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
+                               $this->list['ChangeContentModel'] = \SpecialChangeContentModel::class;
                        }
 
                        // Add extension special pages
-                       self::$list = array_merge( self::$list, $wgSpecialPages );
+                       $this->list = array_merge( $this->list, $this->config->get( 'SpecialPages' ) );
 
                        // This hook can be used to disable unwanted core special pages
                        // or conditionally register special pages.
-                       Hooks::run( 'SpecialPage_initList', [ &self::$list ] );
+                       Hooks::run( 'SpecialPage_initList', [ &$this->list ] );
 
                }
 
-               return self::$list;
+               return $this->list;
        }
 
        /**
@@ -270,19 +291,18 @@ class SpecialPageFactory {
         * All registered special pages are guaranteed to map to themselves.
         * @return array
         */
-       private static function getAliasList() {
-               $contLang = MediaWikiServices::getInstance()->getContentLanguage();
-               if ( is_null( self::$aliases ) ) {
-                       $aliases = $contLang->getSpecialPageAliases();
-                       $pageList = self::getPageList();
+       private function getAliasList() : array {
+               if ( is_null( $this->aliases ) ) {
+                       $aliases = $this->contLang->getSpecialPageAliases();
+                       $pageList = $this->getPageList();
 
-                       self::$aliases = [];
+                       $this->aliases = [];
                        $keepAlias = [];
 
                        // Force every canonical name to be an alias for itself.
                        foreach ( $pageList as $name => $stuff ) {
-                               $caseFoldedAlias = $contLang->caseFold( $name );
-                               self::$aliases[$caseFoldedAlias] = $name;
+                               $caseFoldedAlias = $this->contLang->caseFold( $name );
+                               $this->aliases[$caseFoldedAlias] = $name;
                                $keepAlias[$caseFoldedAlias] = 'canonical';
                        }
 
@@ -291,24 +311,24 @@ class SpecialPageFactory {
                                foreach ( $aliases as $realName => $aliasList ) {
                                        $aliasList = array_values( $aliasList );
                                        foreach ( $aliasList as $i => $alias ) {
-                                               $caseFoldedAlias = $contLang->caseFold( $alias );
+                                               $caseFoldedAlias = $this->contLang->caseFold( $alias );
 
-                                               if ( isset( self::$aliases[$caseFoldedAlias] ) &&
-                                                       $realName === self::$aliases[$caseFoldedAlias]
+                                               if ( isset( $this->aliases[$caseFoldedAlias] ) &&
+                                                       $realName === $this->aliases[$caseFoldedAlias]
                                                ) {
                                                        // Ignore same-realName conflicts
                                                        continue;
                                                }
 
                                                if ( !isset( $keepAlias[$caseFoldedAlias] ) ) {
-                                                       self::$aliases[$caseFoldedAlias] = $realName;
+                                                       $this->aliases[$caseFoldedAlias] = $realName;
                                                        if ( !$i ) {
                                                                $keepAlias[$caseFoldedAlias] = 'first';
                                                        }
                                                } elseif ( !$i ) {
                                                        wfWarn( "First alias '$alias' for $realName conflicts with " .
                                                                "{$keepAlias[$caseFoldedAlias]} alias for " .
-                                                               self::$aliases[$caseFoldedAlias]
+                                                               $this->aliases[$caseFoldedAlias]
                                                        );
                                                }
                                        }
@@ -316,7 +336,7 @@ class SpecialPageFactory {
                        }
                }
 
-               return self::$aliases;
+               return $this->aliases;
        }
 
        /**
@@ -327,13 +347,12 @@ class SpecialPageFactory {
         * @param string $alias
         * @return array Array( String, String|null ), or array( null, null ) if the page is invalid
         */
-       public static function resolveAlias( $alias ) {
+       public function resolveAlias( $alias ) {
                $bits = explode( '/', $alias, 2 );
 
-               $caseFoldedAlias = MediaWikiServices::getInstance()->getContentLanguage()->
-                       caseFold( $bits[0] );
+               $caseFoldedAlias = $this->contLang->caseFold( $bits[0] );
                $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
-               $aliases = self::getAliasList();
+               $aliases = $this->getAliasList();
                if ( isset( $aliases[$caseFoldedAlias] ) ) {
                        $name = $aliases[$caseFoldedAlias];
                } else {
@@ -355,10 +374,10 @@ class SpecialPageFactory {
         * @param string $name Name of a special page
         * @return bool True if a special page exists with this name
         */
-       public static function exists( $name ) {
-               list( $title, /*...*/ ) = self::resolveAlias( $name );
+       public function exists( $name ) {
+               list( $title, /*...*/ ) = $this->resolveAlias( $name );
 
-               $specialPageList = self::getPageList();
+               $specialPageList = $this->getPageList();
                return isset( $specialPageList[$title] );
        }
 
@@ -368,17 +387,17 @@ class SpecialPageFactory {
         * @param string $name Special page name, may be localised and/or an alias
         * @return SpecialPage|null SpecialPage object or null if the page doesn't exist
         */
-       public static function getPage( $name ) {
-               list( $realName, /*...*/ ) = self::resolveAlias( $name );
+       public function getPage( $name ) {
+               list( $realName, /*...*/ ) = $this->resolveAlias( $name );
 
-               $specialPageList = self::getPageList();
+               $specialPageList = $this->getPageList();
 
                if ( isset( $specialPageList[$realName] ) ) {
                        $rec = $specialPageList[$realName];
 
                        if ( is_callable( $rec ) ) {
                                // Use callback to instantiate the special page
-                               $page = call_user_func( $rec );
+                               $page = $rec();
                        } elseif ( is_string( $rec ) ) {
                                $className = $rec;
                                $page = new $className;
@@ -416,18 +435,14 @@ class SpecialPageFactory {
         * Return categorised listable special pages which are available
         * for the current user, and everyone.
         *
-        * @param User|null $user User object to check permissions, $wgUser will be used
-        *        if not provided
+        * @param User $user User object to check permissions
+        *  provided
         * @return array ( string => Specialpage )
         */
-       public static function getUsablePages( User $user = null ) {
+       public function getUsablePages( User $user ) : array {
                $pages = [];
-               if ( $user === null ) {
-                       global $wgUser;
-                       $user = $wgUser;
-               }
-               foreach ( self::getPageList() as $name => $rec ) {
-                       $page = self::getPage( $name );
+               foreach ( $this->getPageList() as $name => $rec ) {
+                       $page = $this->getPage( $name );
                        if ( $page ) { // not null
                                $page->setContext( RequestContext::getMain() );
                                if ( $page->isListed()
@@ -446,10 +461,10 @@ class SpecialPageFactory {
         *
         * @return array ( string => Specialpage )
         */
-       public static function getRegularPages() {
+       public function getRegularPages() : array {
                $pages = [];
-               foreach ( self::getPageList() as $name => $rec ) {
-                       $page = self::getPage( $name );
+               foreach ( $this->getPageList() as $name => $rec ) {
+                       $page = $this->getPage( $name );
                        if ( $page && $page->isListed() && !$page->isRestricted() ) {
                                $pages[$name] = $page;
                        }
@@ -462,17 +477,13 @@ class SpecialPageFactory {
         * Return categorised listable special pages which are available
         * for the current user, but not for everyone
         *
-        * @param User|null $user User object to use or null for $wgUser
+        * @param User $user User object to use
         * @return array ( string => Specialpage )
         */
-       public static function getRestrictedPages( User $user = null ) {
+       public function getRestrictedPages( User $user ) : array {
                $pages = [];
-               if ( $user === null ) {
-                       global $wgUser;
-                       $user = $wgUser;
-               }
-               foreach ( self::getPageList() as $name => $rec ) {
-                       $page = self::getPage( $name );
+               foreach ( $this->getPageList() as $name => $rec ) {
+                       $page = $this->getPage( $name );
                        if ( $page
                                && $page->isListed()
                                && $page->isRestricted()
@@ -500,7 +511,7 @@ class SpecialPageFactory {
         *
         * @return bool|Title
         */
-       public static function executePath( Title &$title, IContextSource &$context, $including = false,
+       public function executePath( Title &$title, IContextSource &$context, $including = false,
                LinkRenderer $linkRenderer = null
        ) {
                // @todo FIXME: Redirects broken due to this call
@@ -512,7 +523,7 @@ class SpecialPageFactory {
                        $par = $bits[1];
                }
 
-               $page = self::getPage( $name );
+               $page = $this->getPage( $name );
                if ( !$page ) {
                        $context->getOutput()->setArticleRelated( false );
                        $context->getOutput()->setRobotPolicy( 'noindex,nofollow' );
@@ -587,7 +598,7 @@ class SpecialPageFactory {
         * @param LinkRenderer|null $linkRenderer (since 1.28)
         * @return string HTML fragment
         */
-       public static function capturePath(
+       public function capturePath(
                Title $title, IContextSource $context, LinkRenderer $linkRenderer = null
        ) {
                global $wgTitle, $wgOut, $wgRequest, $wgUser, $wgLang;
@@ -622,7 +633,7 @@ class SpecialPageFactory {
                $main->setLanguage( $context->getLanguage() );
 
                // The useful part
-               $ret = self::executePath( $title, $context, true, $linkRenderer );
+               $ret = $this->executePath( $title, $context, true, $linkRenderer );
 
                // Restore old globals and context
                $wgTitle = $glob['title'];
@@ -646,16 +657,15 @@ class SpecialPageFactory {
         * @param string|bool $subpage
         * @return string
         */
-       public static function getLocalNameFor( $name, $subpage = false ) {
-               $contLang = MediaWikiServices::getInstance()->getContentLanguage();
-               $aliases = $contLang->getSpecialPageAliases();
-               $aliasList = self::getAliasList();
+       public function getLocalNameFor( $name, $subpage = false ) {
+               $aliases = $this->contLang->getSpecialPageAliases();
+               $aliasList = $this->getAliasList();
 
                // Find the first alias that maps back to $name
                if ( isset( $aliases[$name] ) ) {
                        $found = false;
                        foreach ( $aliases[$name] as $alias ) {
-                               $caseFoldedAlias = $contLang->caseFold( $alias );
+                               $caseFoldedAlias = $this->contLang->caseFold( $alias );
                                $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
                                if ( isset( $aliasList[$caseFoldedAlias] ) &&
                                        $aliasList[$caseFoldedAlias] === $name
@@ -676,7 +686,7 @@ class SpecialPageFactory {
                                        if ( strcasecmp( $name, $n ) === 0 ) {
                                                wfWarn( "Found alias defined for $n when searching for " .
                                                        "special page aliases for $name. Case mismatch?" );
-                                               return self::getLocalNameFor( $n, $subpage );
+                                               return $this->getLocalNameFor( $n, $subpage );
                                        }
                                }
                        }
@@ -691,7 +701,7 @@ class SpecialPageFactory {
                        $name = "$name/$subpage";
                }
 
-               return $contLang->ucfirst( $name );
+               return $this->contLang->ucfirst( $name );
        }
 
        /**
@@ -700,8 +710,8 @@ class SpecialPageFactory {
         * @param string $alias
         * @return Title|null Title or null if there is no such alias
         */
-       public static function getTitleForAlias( $alias ) {
-               list( $name, $subpage ) = self::resolveAlias( $alias );
+       public function getTitleForAlias( $alias ) {
+               list( $name, $subpage ) = $this->resolveAlias( $alias );
                if ( $name != null ) {
                        return SpecialPage::getTitleFor( $name, $subpage );
                } else {
diff --git a/includes/specialpage/SpecialPageFactory_deprecated.php b/includes/specialpage/SpecialPageFactory_deprecated.php
new file mode 100644 (file)
index 0000000..bc0c250
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Factory for handling the special page list and generating SpecialPage objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ * @defgroup SpecialPage SpecialPage
+ */
+
+use MediaWiki\Linker\LinkRenderer;
+use MediaWiki\MediaWikiServices;
+
+// phpcs:disable MediaWiki.Files.ClassMatchesFilename.NotMatch
+/**
+ * Wrapper for backward compatibility for old callers that used static methods.
+ *
+ * @deprecated since 1.32, use the SpecialPageFactory service instead
+ */
+class SpecialPageFactory {
+       public static function getNames() : array {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getNames();
+       }
+
+       public static function resolveAlias( $alias ) : array {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->resolveAlias( $alias );
+       }
+
+       public static function exists( $name ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->exists( $name );
+       }
+
+       public static function getPage( $name ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getPage( $name );
+       }
+
+       public static function getUsablePages( User $user = null ) : array {
+               global $wgUser;
+               $user = $user ?? $wgUser;
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getUsablePages( $user );
+       }
+
+       public static function getRegularPages() : array {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getRegularPages();
+       }
+
+       public static function getRestrictedPages( User $user = null ) : array {
+               global $wgUser;
+               $user = $user ?? $wgUser;
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()->getRestrictedPages( $user );
+       }
+
+       public static function executePath( Title &$title, IContextSource &$context, $including = false,
+               LinkRenderer $linkRenderer = null
+       ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()
+                       ->executePath( $title, $context, $including, $linkRenderer );
+       }
+
+       public static function capturePath(
+               Title $title, IContextSource $context, LinkRenderer $linkRenderer = null
+       ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()
+                       ->capturePath( $title, $context, $linkRenderer );
+       }
+
+       public static function getLocalNameFor( $name, $subpage = false ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()
+                       ->getLocalNameFor( $name, $subpage );
+       }
+
+       public static function getTitleForAlias( $alias ) {
+               return MediaWikiServices::getInstance()->getSpecialPageFactory()
+                       ->getTitleForAlias( $alias );
+       }
+
+       /**
+        * No-op since 1.32, call overrideMwServices() instead
+        */
+       public static function resetList() {
+       }
+}
index 4f29082..00aa543 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * A special page that lists special pages
  *
@@ -50,7 +52,8 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
        }
 
        private function getPageGroups() {
-               $pages = SpecialPageFactory::getUsablePages( $this->getUser() );
+               $pages = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                       getUsablePages( $this->getUser() );
 
                if ( !count( $pages ) ) {
                        # Yeah, that was pointless. Thanks for coming.
index 28473aa..6e96945 100644 (file)
@@ -13,7 +13,6 @@
                "resources/src/jquery.tablesorter",
                "resources/src/jquery.tipsy",
                "resources/src/jquery/jquery.color.js",
-               "resources/src/jquery/jquery.expandableField.js",
                "resources/src/jquery/jquery.highlightText.js",
                "resources/src/jquery/jquery.mw-jump.js",
                "resources/src/mediawiki.legacy",
index cb7fb23..a74dd08 100644 (file)
        "group-autoconfirmed-member": "{{GENDER:$1|автотӀелаьцна декъашхо}}",
        "group-bot-member": "{{GENDER:$1|бот}}",
        "group-sysop-member": "{{GENDER:$1|куьйгалхо}}",
+       "group-interface-admin-member": "{{GENDER:$1|интерфейсан куьйгалхой}}",
        "group-bureaucrat-member": "{{GENDER:$1|бюрократхо}}",
        "group-suppress-member": "{{GENDER:$1|ревизор}}",
        "grouppage-user": "{{ns:project}}:Декъашхой",
        "grouppage-autoconfirmed": "{{ns:project}}:АвтотӀелаьцна декъашхой",
        "grouppage-bot": "{{ns:project}}:Боташ",
        "grouppage-sysop": "{{ns:project}}:Куьйгалхой",
+       "grouppage-interface-admin": "{{ns:project}}:Интерфейсан куьйгалхой",
        "grouppage-bureaucrat": "{{ns:project}}:Бюрократаш",
        "grouppage-suppress": "{{ns:project}}:Ревизораш",
        "right-read": "агӀонашка хьажар",
        "protectedtitles-submit": "Гайта кортош",
        "listusers": "Декъашхойн могӀам",
        "listusers-editsonly": "Цхаъ мукъане а хийцам бина декъашхой гайта",
+       "listusers-temporarygroupsonly": "Декъашхойн тобана, ханна юкъа тоьхна декъашхой гайта",
        "listusers-creationsort": "Кхоьллина хене хьаьжжина нисъяр",
        "listusers-desc": "Харжа кӀезиг хиларца",
        "usereditcount": "$1 {{PLURAL:$1|нисдар|нисдарш}}",
index c1deea2..7602df5 100644 (file)
        "exbeforeblank": "պարունակությունը մինչև մաքրումը. «$1»",
        "delete-confirm": "$1 ― ջնջում",
        "delete-legend": "Ջնջում",
-       "historywarning": "Զգուշացում. էջը, որը դուք պատրաստվում եք ջնջել ունի փոփոխությունների պատմություն։",
+       "historywarning": "Զգուշացում. էջը, որը դուք պատրաստվում եք ջնջել, ունի փոփոխությունների պատմություն։",
        "historyaction-submit": "Ցուցադրել",
        "confirmdeletetext": "Դուք պատրաստվում եք ընդմիշտ ջնջել էջը կամ պատկերը տվյալների բազայից իր փոփոխությունների պատմությամբ հանդերձ։ Խնդրում ենք հաստատել, որ դուք իրոք մտադրված եք դա անել, հասկանում եք դրա հետևանքները և գործում եք [[{{MediaWiki:Policy-url}}|կանոնադրության]] սահմաններում։",
        "actioncomplete": "Գործողությունն ավարտված է",
index f18571c..62940dd 100644 (file)
        "botpasswords": "ꯕꯣꯇ ꯄꯥꯁꯋꯔꯇ",
        "botpasswords-summary": "<em>Bot passwords</em> allow access to a user account via the API without using the account's main login credentials. The user rights available when logged in with a bot password may be restricted.\n\nIf you don't know why you might want to do this, you should probably not do it. No one should ever ask you to generate one of these and give it to them.",
        "botpasswords-disabled": "ꯕꯣꯇ ꯄꯥꯁꯋꯔꯇ ꯌꯥꯉꯟꯗꯕꯥ",
+       "botpasswords-label-appid": "ꯕꯣꯠ ꯃꯃꯤꯡ:",
        "botpasswords-label-create": "ꯁꯥꯕꯥ",
        "botpasswords-label-update": "ꯅꯧꯊꯣꯛꯍꯟꯕꯥ",
        "botpasswords-label-cancel": "ꯀꯛꯊꯠꯄꯥ",
        "resetpass-submit-cancel": "ꯀꯛꯊꯠꯄꯥ",
        "resetpass-wrong-oldpass": "ꯃꯇꯝ ꯈꯔꯥꯒꯤ ꯑꯣꯏꯅꯥ ꯀꯔꯤꯝꯇꯥ ꯌꯥꯎꯗꯦ  ꯅꯠꯇꯔꯒꯥ ꯍꯧꯖꯤꯧꯀꯤ ꯄꯥꯁꯋ꯭ꯔꯇ꯫\nꯅꯪꯅꯥ ꯄꯥꯁꯋꯑꯔꯇ ꯍꯥꯟꯅꯗꯒꯤ ꯍꯣꯡꯂꯝꯂꯅꯤ ꯅꯠꯇꯔꯒꯥ ꯍꯪꯒꯠꯂꯨ ꯉꯥꯏꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋ꯭ꯔꯇ",
        "resetpass-temp-password": "ꯉꯩꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋ꯭ꯔꯇ",
+       "resetpass-expired": "ꯅꯪꯒꯤ ꯄꯥꯁꯋ꯭ꯔꯇ ꯁꯤ ꯌꯥꯗꯔꯦ ꯫ ꯆꯥꯟꯕꯤꯗꯨꯅ ꯑꯅꯧꯕ ꯱ ꯁꯦꯝꯃꯣ ꯂꯣꯒ ꯏꯟ ꯇꯧꯅꯕ ꯫",
        "passwordreset": "ꯄꯥꯁꯋ꯭ꯇ ꯁꯦꯝꯗꯣꯛꯄꯥ",
        "passwordreset-username": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯃꯤꯡ",
        "passwordreset-domain": "ꯗꯣꯃꯦꯟ",
        "passwordreset-emailtext-ip": "Someone (probably you, from IP address $1) requested a reset of your\npassword for {{SITENAME}} ($4). The following user {{PLURAL:$3|account is|accounts are}}\nassociated with this email address:\n\n$2\n\n{{PLURAL:$3|This temporary password|These temporary passwords}} will expire in {{PLURAL:$5|one day|$5 days}}.\nYou should log in and choose a new password now. If someone else made this\nrequest, or if you have remembered your original password, and you no longer\nwish to change it, you may ignore this message and continue using your old\npassword.",
        "passwordreset-emailtext-user": "User $1 on {{SITENAME}} requested a reset of your password for {{SITENAME}}\n($4). The following user {{PLURAL:$3|account is|accounts are}} associated with this email address:\n\n$2\n\n{{PLURAL:$3|This temporary password|These temporary passwords}} will expire in {{PLURAL:$5|one day|$5 days}}.\nYou should log in and choose a new password now. If someone else made this\nrequest, or if you have remembered your original password, and you no longer\nwish to change it, you may ignore this message and continue using your old\npassword.",
        "passwordreset-emailelement": "$1 ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ\n$2 ꯉꯩꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋꯔꯇ",
+       "changeemail-oldemail": "ꯍꯧꯖꯤꯛꯀꯤ ꯏꯃꯦꯜ ꯑꯦꯗ꯭ꯔꯦꯁ:",
+       "changeemail-newemail": "ꯑꯅꯧꯕ ꯏꯃꯦꯜ ꯑꯦꯗ꯭ꯔꯦꯁ:",
        "changeemail-none": "ꯑꯃꯥꯇꯥ ꯅꯠꯇꯦ",
        "changeemail-password": "ꯅꯪꯒꯤ {{SITENAME}} ꯄꯥꯁꯋ꯭ꯔꯇ:",
        "changeemail-submit": "ꯏ-ꯃꯦꯜ ꯍꯣꯡꯕꯥ",
        "noarticletext-nopermission": "There is currently no text in this page.\nYou can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages, or <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span>, but you do not have permission to create this page.",
        "missing-revision": "The revision #$1 of the page named \"{{FULLPAGENAME}}\" does not exist.\n\nThis is usually caused by following an outdated history link to a page that has been deleted.\nDetails can be found in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
        "userpage-userdoesnotexist-view": "$1 ꯁꯤꯖꯤꯅꯅꯔꯤꯕ ꯑꯦꯀꯥꯎꯅ ꯁꯤ ꯃꯤꯡ ꯆꯟꯗꯔꯤ",
+       "updated": "(ꯅꯧꯊꯣꯛꯍꯟꯂꯦ)",
+       "note": "<ꯑꯀꯟꯕ>ꯏꯁꯤꯟꯒꯗꯕ:</ꯑꯀꯟꯕ>",
        "continue-editing": "ꯁꯦꯝꯒꯠꯄꯒꯤ ꯃꯐꯝꯗꯨꯗꯥ ꯆꯠꯂꯨ",
        "editing": "$1 ꯁꯦꯝꯒꯠꯂꯤ",
        "creating": "Creating $1",
index bda58f9..154264a 100644 (file)
        "date-range-from": "Frå dato:",
        "date-range-to": "Til dato:",
        "randomrootpage": "Tilfeldig rotside",
+       "log-action-filter-newusers": "Type kontooppretting:",
        "log-action-filter-rights": "Type endring av rettar:",
+       "log-action-filter-all": "Alle",
        "log-action-filter-delete-delete_redir": "Overskriving av omdirigering",
        "log-action-filter-delete-restore": "Attoppretting av side",
        "log-action-filter-delete-revision": "Versjonssletting",
        "log-action-filter-move-move": "Flytting utan overskriving av omdirigeringar",
        "log-action-filter-move-move_redir": "Flytting med overskriving av omdirigeringar",
+       "log-action-filter-newusers-create": "Oppretting av anonym brukar",
+       "log-action-filter-newusers-create2": "Oppretting av registrert brukar",
+       "log-action-filter-newusers-autocreate": "Automatisk oppretting",
+       "log-action-filter-newusers-byemail": "Oppretting med passord sendt på e-post",
        "log-action-filter-suppress-revision": "Versjonsundertrykking",
        "authmanager-userdoesnotexist": "Brukarkontoen «$1» er ikkje oppretta.",
        "authmanager-provider-temporarypassword": "Mellombels passord",
index e0c49ab..f9bfa77 100644 (file)
        "ns-specialprotected": "Paginile din spațiul de nume {{ns:special}} nu pot fi editate.",
        "titleprotected": "Acest titlu a fos protejat la creare de [[User:$1|$1]].\nMotivul invocat este <em>$2</em>.",
        "filereadonlyerror": "Imposibil de modificat fișierul „$1”, deoarece depozitul de fișiere „$2” este în modul „doar citire”.\n\nAdministratorul de sistem care a efectuat blocarea a furnizat explicația: „$3”.",
+       "invalidtitle": "Titlu incorect",
        "invalidtitle-knownnamespace": "Titlu invalid cu spațiul de nume „$2” și textul „$3”",
        "invalidtitle-unknownnamespace": "Titlu invalid cu numărul spațiului de nume $1 necunoscut și textul „$2”",
        "exception-nologin": "Neautentificat{{GENDER:||ă}}",
        "group-autoconfirmed": "Utilizatori autoconfirmați",
        "group-bot": "Roboți",
        "group-sysop": "Administratori",
+       "group-interface-admin": "Administratori de interfață",
        "group-bureaucrat": "Birocrați",
        "group-suppress": "Suprimători",
        "group-all": "(toți)",
        "group-autoconfirmed-member": "{{GENDER:$1|utilizator autoconfirmat|utilizatoare autoconfirmată|utilizator autoconfirmat}}",
        "group-bot-member": "{{GENDER:$1|robot}}",
        "group-sysop-member": "{{GENDER:$1|administrator}}",
+       "group-interface-admin-member": "{{GENDER:$1|administrator de interfață}}",
        "group-bureaucrat-member": "{{GENDER:$1|birocrat}}",
        "group-suppress-member": "{{GENDER:$1|suprimător|suprimătoare}}",
        "grouppage-user": "{{ns:project}}:Utilizatori",
        "grouppage-autoconfirmed": "{{ns:project}}:Utilizator autoconfirmați",
        "grouppage-bot": "{{ns:project}}:Boți",
        "grouppage-sysop": "{{ns:project}}:Administratori",
+       "grouppage-interface-admin": "{{ns:project}}:Administratori de interfață",
        "grouppage-bureaucrat": "{{ns:project}}:Birocrați",
        "grouppage-suppress": "{{ns:project}}:Suprimători",
        "right-read": "Citește pagini",
        "right-editusercss": "Modifică fișierele CSS ale altor utilizatori",
        "right-edituserjson": "Modifică fișierele JSON ale altor utilizatori",
        "right-edituserjs": "Modifică fișierele JS ale altor utilizatori",
+       "right-editsitecss": "Editează CSS global",
+       "right-editsitejson": "Editează JSON global",
+       "right-editsitejs": "Editează JavaScript global",
        "right-editmyusercss": "Modificați-vă propriile fișiere CSS",
        "right-editmyuserjson": "Modificați-vă propriile fișiere JSON",
        "right-editmyuserjs": "Modificați-vă propriile fișiere JavaScript",
        "grant-createaccount": "Creare conturi",
        "grant-createeditmovepage": "Creează, editează și redenumește pagini",
        "grant-delete": "Șterge pagini, revizii și loguri",
-       "grant-editinterface": "Editați spațiul de nume MediaWiki și CSS/JSON/JavaScript de utilizator",
+       "grant-editinterface": "Editați spațiul de nume MediaWiki și fișiere JSON globale/de utilizator",
        "grant-editmycssjs": "Editați CSS/JSON/JavaScript ale contului dv.",
        "grant-editmyoptions": "Modificați-vă preferințele de utilizator",
        "grant-editmywatchlist": "Modificați-vă lista de pagini urmărite",
+       "grant-editsiteconfig": "Editează CSS/JS global și de utilizator",
        "grant-editpage": "Editați pagini existente",
        "grant-editprotected": "Editați pagini protejate",
        "grant-highvolume": "Volum mare de editare",
        "rcfilters-filter-humans-label": "Om (nu robot)",
        "rcfilters-filter-humans-description": "Modificări făcute de oameni.",
        "rcfilters-filtergroup-reviewstatus": "Statutul reviziei",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Editări nemarcate, manual sau automat, ca patrulate.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Nepatrulate",
        "rcfilters-filter-reviewstatus-manual-description": "Modificări marcate manual ca patrulate.",
        "rcfilters-filter-reviewstatus-manual-label": "Patrulate manual",
+       "rcfilters-filter-reviewstatus-auto-description": "Editări făcute de utilizatori avansați a cărui muncă este marcată automat ca patrulată.",
        "rcfilters-filter-reviewstatus-auto-label": "Patrulate automat",
        "rcfilters-filtergroup-significance": "Semnificație",
        "rcfilters-filter-minor-label": "Modificări minore",
        "rcfilters-watchlist-showupdated": "Paginile care au fost modificate după ultima dumneavoastră vizită sunt afișate <strong>îngroșat</strong>.",
        "rcfilters-preference-label": "Ascunde versiunea îmbunătățită a Schimbărilor Recente",
        "rcfilters-preference-help": "Ascunde interfața schimbată în 2017 și toate uneltele adăugate de atunci.",
+       "rcfilters-watchlist-preference-label": "Ascunde versiunea îmbunătățită a liste de pagini urmărite",
        "rcfilters-filter-showlinkedfrom-label": "Arată schimbările pe paginile către care există legături în",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Pages la care trimite</strong> pagina selectată",
        "rcfilters-filter-showlinkedto-label": "Arată schimbările din paginile ce trimit la",
        "uploadstash-zero-length": "Fișierul are lungime zero.",
        "invalid-chunk-offset": "Decalaj de segment nevalid",
        "img-auth-accessdenied": "Acces interzis",
-       "img-auth-nopathinfo": "PATH_INFO lipsește.\nServerul dumneavoastră nu a fost setat pentru a trece aceste informații.\nS-ar putea să fie bazat pe CGI și să nu suporte img_auth.\nVedeți https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Lipsește informația privitoare la căi.\n\nServerul dumneavoastră trebuie să fie setat pentru a transmite variabilele REQUEST_URI sau PATH_INFO.\n\nDacă face deja acest lucru, încercați să activați $wgUserPathInfo.\n\nVedeți https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Adresa cerută nu este în directorul pentru încărcări configurat.",
        "img-auth-badtitle": "Nu s-a putut construi un titlu valid din \"$1\".",
        "img-auth-nologinnWL": "Nu sunteți autentificat și \"$1\" nu este pe lista albă.",
        "filehist-filesize": "Mărimea fișierului",
        "filehist-comment": "Comentariu",
        "imagelinks": "Utilizarea fișierului",
-       "linkstoimage": "{{PLURAL:$1|Următoarea pagină trimite|Următoarele $1 pagini trimit spre|Următoarele $1 de pagini trimit}} către acest fișier:",
-       "linkstoimage-more": "Mai mult de $1 {{PLURAL:$1|pagină este legată|pagini sunt legate}} de acest fișier.\nUrmătoarea listă arată {{PLURAL:$1|prima legătură|primele $1 legături}} către acest fișier.\nO [[Special:WhatLinksHere/$2|listă completă]] este disponibilă.",
+       "linkstoimage": "{{PLURAL:$1|Următoarea pagină folosește|Următoarele $1 pagini folosesc |Următoarele $1 de pagini folosesc}} acest fișier:",
+       "linkstoimage-more": "Mai mult de $1 {{PLURAL:$1|pagină folosește|pagini folosesc}} acest fișier.\nUrmătoarea listă arată {{PLURAL:$1|prima legătură|primele $1 legături}} către acest fișier.\nEste disponibilă o [[Special:WhatLinksHere/$2|listă completă]].",
        "nolinkstoimage": "Nicio pagină nu utilizează această imagine.",
        "morelinkstoimage": "Vedeți [[Special:WhatLinksHere/$1|mai multe legături]] către acest fișier.",
        "linkstoimage-redirect": "$1 (redirecționare de fișier) $2",
        "cachedspecial-refresh-now": "Ultima versiune.",
        "categories": "Categorii",
        "categories-submit": "Afișează",
-       "categoriespagetext": "{{PLURAL:$1|Următoarea categorie conține|Următoarele categorii conțin}} pagini sau fișiere.\n[[Special:UnusedCategories|Categoriile neutilizate]] nu apar aici.\nVedeți și [[Special:WantedCategories|categoriile dorite]].",
+       "categoriespagetext": "{{PLURAL:$1|Următoarea categorie|Următoarele categorii}} există pe wiki și ar putea sau nu să fie nefolosite.\nVedeți și [[Special:WantedCategories|categoriile dorite]].",
        "categoriesfrom": "Arată categoriile pornind de la:",
        "deletedcontributions": "Contribuții șterse",
        "deletedcontributions-title": "Contribuții șterse",
        "fix-double-redirects": "Actualizează toate redirecționările care trimit la titlul original",
        "move-leave-redirect": "Lasă în urmă o redirecționare",
        "protectedpagemovewarning": "'''Atenție:''' această pagină a fost protejată astfel încât poate fi redenumită doar de către administratori.\nUltima intrare în jurnal este afișată mai jos pentru referință:",
-       "semiprotectedpagemovewarning": "'''Observație: această pagină a fost protejată, putând fi redenumiră doar de către utilizatorii înregistrați.'''\nUltima intrare în jurnal este afișată mai jos pentru referință:",
+       "semiprotectedpagemovewarning": "<strong>Notă:</strong>  această pagină a fost protejată, putând fi redenumită doar de către utilizatorii autoconfirmați.\nUltima intrare în jurnal este afișată mai jos pentru referință:",
        "move-over-sharedrepo": "[[:$1]] există deja într-un depozit partajat. Redenumirea fișierului la acest titlu va suprascrie fișierul partajat și îl va face inaccesibil.",
        "file-exists-sharedrepo": "Numele ales al fișierului este deja în utilizare într-un depozit împărțit.\nAlegeți un alt nume.",
        "export": "Exportare pagini",
        "diff-form": "Diferențe",
        "diff-form-submit": "Arată diferențele",
        "permanentlink": "Legătură permanentă",
+       "permanentlink-revid": "ID versiune",
        "permanentlink-submit": "Mergi la versiunea",
        "dberr-problems": "Ne cerem scuze! Acest site întâmpină dificultăți tehnice.",
        "dberr-again": "Așteptați câteva minute și încercați din nou.",
        "htmlform-datetime-invalid": "Valoarea introdusă nu este recunoscută ca dată și timp. Încercați să folosiți formatul YYYY-MM-DD HH:MM:SS.",
        "htmlform-date-toolow": "Valoarea introdusă este anterioară primei date permise, $1.",
        "htmlform-date-toohigh": "Valoarea introdusă este posterioară ultimei date permise, $1.",
+       "htmlform-time-toolow": "Valoarea specificată este înainte de prima oră permisă, $1.",
+       "htmlform-time-toohigh": "Valoarea specificată este după ultima oră permisă, $1.",
+       "htmlform-datetime-toolow": "Valoarea specificată este înainte de prima dată permisă, $1.",
+       "htmlform-datetime-toohigh": "Valoarea specificată este după ultima dată permisă, $1.",
        "htmlform-title-badnamespace": "[[:$1]] nu se află în spațiul de nume „{{ns:$2}}”.",
        "htmlform-title-not-creatable": "„$1” este un titlu de pagină inutilizabil",
        "htmlform-title-not-exists": "$1 nu există.",
        "log-action-filter-protect-move_prot": "Mutarea protecției",
        "log-action-filter-rights-rights": "Modificare manuală",
        "log-action-filter-rights-autopromote": "Schimbare automată",
+       "log-action-filter-suppress-event": "Ștergere jurnal",
+       "log-action-filter-suppress-revision": "Ștergere versiune",
+       "log-action-filter-suppress-delete": "Ștergere pagină",
        "log-action-filter-upload-upload": "Încărcare nouă",
        "log-action-filter-upload-overwrite": "Reîncărcare",
+       "authmanager-create-disabled": "Crearea de conturi este dezactivată.",
+       "authmanager-create-from-login": "Pentru a crea contul, vă rugăm să completați câmpurile.",
        "authmanager-authplugin-setpass-failed-title": "Schimbarea parolei a eșuat",
        "authmanager-authplugin-setpass-bad-domain": "Domeniu invalid.",
        "authmanager-userdoesnotexist": "Contul de utilizator „$1” nu este înregistrat.",
        "edit-error-short": "Eroare: $1",
        "edit-error-long": "Erori:\n\n$1",
        "revid": "versiunea $1",
+       "pageid": "ID pagină $1",
+       "interfaceadmin-info": "$1\n\nPermisiunile pentru editarea de CSS/JS/JSON global au fost recent separate de dreptul <code>editinterface</code>. Dacă nu înțelegeți de ce primiți această eroare, vedeți [[mw:MediaWiki_1.32/interface-admin]].",
        "rawhtml-notallowed": "Tagurile &lt;html&gt; nu pot fi folosite în afara paginilor normale.",
        "gotointerwiki": "Se părăsește {{SITENAME}}",
        "gotointerwiki-invalid": "Titlul specificat nu este valid.",
+       "gotointerwiki-external": "Sunteți pe cale să părăsiți {{SITENAME}} pentru a vizita [[$2]], care este un alt site.\n\n'''[$1 Continuați către $1]'''",
+       "undelete-cantedit": "Nu puteți recupera această pagină pentru că nu puteți să o editați.",
+       "undelete-cantcreate": "Nu puteți recupera această pagină deoarece nu există o pagină cu acest nume și nu aveți dreptul să o creați.",
        "pagedata-title": "Datele paginii",
        "pagedata-not-acceptable": "Niciun format corespunzător găsit. Tipuri MIME acceptate: $1",
        "pagedata-bad-title": "Titlu invalid: $1.",
        "passwordpolicies-policy-passwordcannotmatchusername": "Parola nu poate fi identică cu numele de utilizator",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Parolele nu pot fi cele de pe lista neagră",
        "passwordpolicies-policy-maximalpasswordlength": "Parola trebuie să aibă cel puțin $1 {{PLURAL:$1|caracter|caractere|de caractere}}.",
-       "passwordpolicies-policy-passwordcannotbepopular": "Parola nu poate fi {{PLURAL:$1|o parolă populară|în lista celor $1 parole populare|în lista celor $1 de parole populare}}."
+       "passwordpolicies-policy-passwordcannotbepopular": "Parola nu poate fi {{PLURAL:$1|o parolă populară|în lista celor $1 parole populare|în lista celor $1 de parole populare}}.",
+       "easydeflate-invaliddeflate": "Conținutul oferit nu este comprimat corect"
 }
index 0e8e391..c4111e3 100644 (file)
        "undo-summary-username-hidden": "Поништи измену $1 скривеног корисника",
        "cantcreateaccount-text": "Отварање налога с ове IP адресе (<strong>$1</strong>) је блокирао/ла [[User:$3|$3]].\n\nРазлог који је навео/ла $3 је <em>$2</em>",
        "cantcreateaccount-range-text": "Отварање налога са IP адреса у распону <strong>$1</strong>, који укључује и вашу IP адресу (<strong>$4</strong>) је блокирао/ла [[User:$3|$3]].\n\nРазлог који је навео/ла $3 је <em>$2</em>",
-       "viewpagelogs": "Ð\9fогледаÑ\98 Ðµвиденције ове странице",
+       "viewpagelogs": "Ð\95виденције ове странице",
        "nohistory": "Не постоји историја измена ове странице.",
        "currentrev": "Актуелна ревизија",
        "currentrev-asof": "Најновија ревизија на датум $2 у $3",
        "diff-paragraph-moved-toold": "Пасус је премештен. Кликните да пређете на његово старо место.",
        "difference-missing-revision": "{{PLURAL:$2|Једна ревизија|$2 ревизије}} од ове разлике ($1) не {{PLURAL:$2|постоји|постоје}}.\n\nОво се обично дешава када пратите застарелу везу до странице која је обрисана.\nДетаље можете да пронађете у [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} евиденцији брисања].",
        "searchresults": "Резултати претраге",
+       "search-filter-title-prefix-reset": "Претражи све странице",
        "searchresults-title": "Резултати претраге за „$1“",
        "titlematches": "Наслов странице одговара",
        "textmatches": "Текст странице одговара",
        "rcfilters-filter-showlinkedto-option-label": "<strong>Странице ка којима воде везе са</strong> изабране странице",
        "rcfilters-target-page-placeholder": "Унесите име странице (или категорије)",
        "rcnotefrom": "Испод {{PLURAL:$5|је промена|су промене}} од <strong>$3, $4</strong> (до <strong>$1</strong> приказано).",
-       "rclistfromreset": "РеÑ\81еÑ\82Ñ\83Ñ\98 Ð¾Ð´Ð°Ð±Ð¸р датума",
+       "rclistfromreset": "РеÑ\81еÑ\82Ñ\83Ñ\98 Ð¸Ð·Ð±Ð¾р датума",
        "rclistfrom": "Прикажи нове промене почев од $2, $3",
        "rcshowhideminor": "$1 мање измене",
        "rcshowhideminor-show": "Прикажи",
        "badfilename": "Име датотеке је промењено у „$1“.",
        "filetype-mime-mismatch": "Проширење датотеке „.$1“ не одговара препознатом типу MIME датотеке ($2).",
        "filetype-badmime": "Датотеке MIME типа „$1“ није дозвољено слати.",
-       "filetype-bad-ie-mime": "Ð\9eва Ð´Ð°Ñ\82оÑ\82ека Ñ\81е Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð¿Ð¾Ñ\81лаÑ\82и Ð·Ð°Ñ\82о Ñ\88Ñ\82о Ð±Ð¸ Ñ\98е Ð\98нÑ\82еÑ\80неÑ\82 ÐµÐºÑ\81плоÑ\80еÑ\80 Ñ\83оÑ\87ио ÐºÐ°Ð¾ â\80\9e$1â\80\9c, Ð° Ñ\82о Ñ\98е Ð·Ð°Ð±Ñ\80аÑ\9aена Ð¸ Ð¾Ð¿Ð°Ñ\81на Ð²Ñ\80Ñ\81Ñ\82а датотеке.",
-       "filetype-unwanted-type": "„.$1“ је непожељна врста датотеке.\n{{PLURAL:$3|Пожељна врста датотеке је|Пожељне врсте датотека су}} $2.",
-       "filetype-banned-type": "'''„.$1“''' {{PLURAL:$4|је забрањена врста датотеке|су забрањене врсте датотека}}.\n{{PLURAL:$3|Дозвољена врста датотеке је|Дозвољене врсте датотека су}} $2.",
+       "filetype-bad-ie-mime": "Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ð¾Ñ\82пÑ\80емим Ð¾Ð²Ñ\83 Ð´Ð°Ñ\82оÑ\82екÑ\83 Ñ\98еÑ\80 Ð±Ð¸ Ñ\98е Ð\98нÑ\82еÑ\80неÑ\82 ÐµÐºÑ\81плоÑ\80еÑ\80 Ð¿Ñ\80епознао ÐºÐ°Ð¾ â\80\9e$1â\80\9c, Ñ\88Ñ\82о Ñ\98е Ð½ÐµÐ´Ð¾Ð·Ð²Ð¾Ñ\99ен Ð¸ Ð¿Ð¾Ñ\82енÑ\86иÑ\98ално Ð¾Ð¿Ð°Ñ\81ан Ñ\82ип датотеке.",
+       "filetype-unwanted-type": "<strong>„.$1“</strong> је непожељан тип датотеке.\n{{PLURAL:$3|Пожељан тип датотеке је|Пожељни типови датотека су}} $2.",
+       "filetype-banned-type": "<strong>„.$1“</strong> {{PLURAL:$4|није допуштен тип датотеке|нису допуштени типови датотека}}.\n{{PLURAL:$3|Дозвољен тип датотеке је|Дозвољени типови датотека су}} $2.",
        "filetype-missing": "Ова датотека нема проширење (нпр. „.jpg“).",
        "empty-file": "Послата датотека је празна.",
        "file-too-large": "Послата датотека је превелика.",
        "filename-tooshort": "Назив датотеке је прекратак.",
-       "filetype-banned": "Ð\92Ñ\80Ñ\81Ñ\82а Ð´Ð°Ñ\82оÑ\82еке Ñ\98е Ð·Ð°Ð±Ñ\80аÑ\9aена.",
+       "filetype-banned": "Ð\9eваÑ\98 Ñ\82ип Ð´Ð°Ñ\82оÑ\82еке Ñ\98е Ð·Ð°Ð±Ñ\80аÑ\9aен.",
        "verification-error": "Ова датотека није прошла проверу.",
        "hookaborted": "Измену коју сте покушали да направите је прекинуо додатак.",
        "illegal-filename": "Назив датотеке је забрањен.",
        "uploadstash-file-not-found-no-local-path": "Нема локалне путање за умањену ставку.",
        "uploadstash-file-not-found-no-object": "Не могу направити локални датотечни објекат за минијатуру.",
        "uploadstash-file-not-found-no-remote-thumb": "Добављање минијатуре није успело: $1\nАдреса = $2",
-       "uploadstash-file-not-found-missing-content-type": "Недостаје заглавље за врсту садржаја.",
+       "uploadstash-file-not-found-missing-content-type": "Недостаје заглавље за тип садржаја.",
        "uploadstash-file-not-found-not-exists": "Не могу наћи путању или ово није обична датотека.",
        "uploadstash-file-too-large": "Не могу послужити датотеку већу од $1 {{PLURAL:$1|бајта|бајтова}}",
        "uploadstash-not-logged-in": "Нико није пријављен. Датотеке морају припадати корисницима.",
        "http-timed-out": "Захтев HTTP је истекао.",
        "http-curl-error": "Грешка при отварању адресе: $1",
        "http-bad-status": "Дошло је до проблема током захтева HTTP: $1 $2",
+       "http-internal-error": "HTTP интерна грешка.",
        "upload-curl-error6": "Не могу да приступим адреси",
        "upload-curl-error6-text": "Не могу да приступим наведеном URL-у.\nПроверите да ли је URL исправан и доступан.",
        "upload-curl-error28": "Отпремање је истекло",
        "nolicense": "Није изабрано",
        "licenses-edit": "Уреди избор лиценци",
        "license-nopreview": "(преглед није доступан)",
-       "upload_source_url": "(ваÑ\88а Ð¸Ð·Ð°Ð±Ñ\80ана Ð´Ð°Ñ\82оÑ\82ека Ð¾Ð´ Ð¸Ñ\81пÑ\80авниÑ\85 Ð¸ јавно доступних адреса)",
+       "upload_source_url": "(ваÑ\88а Ð¸Ð·Ð°Ð±Ñ\80ана Ð´Ð°Ñ\82оÑ\82ека Ð¾Ð´ Ð²Ð°Ð¶ÐµÑ\9bиÑ\85, јавно доступних адреса)",
        "upload_source_file": "(ваша одабрана датотека са вашег рачунара)",
        "listfiles-delete": "обриши",
        "listfiles-summary": "Ова посебна страница приказује све отпремљене датотеке.",
        "listgrants-rights": "Права",
        "trackingcategories": "Медијавики категорије",
        "trackingcategories-summary": "Ова посебна страница је списак категорија које су део Медијавикија, оне се аутоматски ажурирају и њихови називи се могу мењати уређивањем системских порука у именском простору {{ns:8}}.",
-       "trackingcategories-msg": "Ð\9fÑ\80аÑ\9bеÑ\9aе ÐºÐ°Ñ\82егоÑ\80иÑ\98е",
+       "trackingcategories-msg": "Ð\9aаÑ\82егоÑ\80иÑ\98е Ð·Ð° Ð¿Ñ\80аÑ\9bеÑ\9aе",
        "trackingcategories-name": "Име поруке",
        "trackingcategories-desc": "Које странице се налазе у категорији",
        "restricted-displaytitle-ignored": "Странице са занемареним насловима за приказ",
        "changecontentmodel-submit": "Промени",
        "changecontentmodel-success-title": "Модел садржаја је промењен",
        "changecontentmodel-success-text": "Модел садржаја странице [[:$1]] је промењен.",
-       "changecontentmodel-cannot-convert": "Ð\9cодел Ñ\81адÑ\80жаÑ\98а Ñ\81Ñ\82Ñ\80аниÑ\86е [[:$1]] Ñ\81е Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð¿Ñ\80еÑ\82воÑ\80иÑ\82и Ñ\83 Ð²Ñ\80Ñ\81Ñ\82Ñ\83 $2.",
+       "changecontentmodel-cannot-convert": "Ð\9cодел Ñ\81адÑ\80жаÑ\98а Ñ\81Ñ\82Ñ\80аниÑ\86е [[:$1]] Ñ\81е Ð½Ðµ Ð¼Ð¾Ð¶Ðµ ÐºÐ¾Ð½Ð²ÐµÑ\80Ñ\82оваÑ\82и Ñ\83 Ñ\82ип $2.",
        "changecontentmodel-nodirectediting": "Модел садржаја $1 не подржава изравно уређивање",
        "changecontentmodel-emptymodels-title": "Нема доступних модела садржаја",
-       "changecontentmodel-emptymodels-text": "Ð\9cодел Ñ\81адÑ\80жаÑ\98а Ñ\81Ñ\82Ñ\80аниÑ\86е [[:$1]] Ñ\81е Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð¿Ñ\80еÑ\82воÑ\80иÑ\82и Ð½Ð¸ Ñ\83 Ñ\98еднÑ\83 Ð´Ñ\80Ñ\83гÑ\83 Ð²Ñ\80Ñ\81Ñ\82Ñ\83.",
+       "changecontentmodel-emptymodels-text": "Ð\9cодел Ñ\81адÑ\80жаÑ\98а Ñ\81Ñ\82Ñ\80аниÑ\86е [[:$1]] Ñ\81е Ð½Ðµ Ð¼Ð¾Ð¶Ðµ ÐºÐ¾Ð½Ð²ÐµÑ\80Ñ\82оваÑ\82и Ð½Ð¸ Ñ\83 Ñ\98едан Ð´Ñ\80Ñ\83ги Ñ\82ип.",
        "log-name-contentmodel": "Евиденција промене модела садржаја",
        "log-description-contentmodel": "Ова страница приказује измене у моделима садржаја страница и странице које су направљене са моделом садржаја који се разликује од подразумеваног.",
        "logentry-contentmodel-new": "$1 је {{GENDER:$2|направио|направила}} страницу $3 с нестандардним моделом садржаја „$5“",
        "prot_1movedto2": "је преместио [[$1]] на [[$2]]",
        "protect-badnamespace-title": "Незаштитљив именски простор",
        "protect-badnamespace-text": "Странице у овом именском простору се не могу заштитити.",
-       "protect-norestrictiontypes-text": "Ова страница се не може заштитити јер нема доступних врста ограничења.",
+       "protect-norestrictiontypes-text": "Ова страница се не може заштитити јер нема доступних типова ограничења.",
        "protect-norestrictiontypes-title": "Незаштитљива страна",
        "protect-legend": "Подешавања заштите",
        "protectcomment": "Разлог:",
        "ipb-blocklist": "Погледај постојећа блокирања",
        "ipb-blocklist-contribs": "Доприноси за {{GENDER:$1|$1}}",
        "ipb-blocklist-duration-left": "преостало: $1",
-       "unblockip": "Ð\94еблокиÑ\80аÑ\98 корисника",
+       "unblockip": "Ð\94еблокиÑ\80аÑ\9aе корисника",
        "unblockiptext": "Користите доњи образац да бисте вратили право писања раније блокираној IP адреси или корисничком имену.",
        "ipusubmit": "Уклони ову блокаду",
        "unblocked": "[[User:$1|$1]] је деблокиран",
        "thumbnail_invalid_params": "Неисправни параметри за минијатуру",
        "thumbnail_toobigimagearea": "Датотека са величинама већим од $1",
        "thumbnail_dest_directory": "Не могу да направим одредишну фасциклу",
-       "thumbnail_image-type": "Ð\92Ñ\80Ñ\81Ñ\82а Ñ\81лике Ð½Ð¸Ñ\98е Ð¿Ð¾Ð´Ñ\80жана",
+       "thumbnail_image-type": "Тип Ñ\81лике Ð½Ð¸Ñ\98е Ð¿Ð¾Ð´Ñ\80жан",
        "thumbnail_gd-library": "Недовршена подешавања графичке библиотеке: недостаје функција $1",
        "thumbnail_image-size-zero": "Изгледа да је величина датотеке нула.",
        "thumbnail_image-missing": "Датотека недостаје: $1",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|страница|странице|страница}}",
        "file-info": "величина датотеке: $1, MIME тип: $2",
        "file-info-size": "$1 × $2 пиксела, величина датотеке: $3, MIME тип: $4",
-       "file-info-size-pages": "$1 × $2 пиксела, величина: $3, MIME врста: $4, $5 {{PLURAL:$5|страница|странице|страница}}",
+       "file-info-size-pages": "$1 × $2 пиксела, величина: $3, MIME тип: $4, $5 {{PLURAL:$5|страница|странице|страница}}",
        "file-nohires": "Већа резолуција није доступна.",
        "svg-long-desc": "SVG датотека, номинално $1 × $2 пиксела, величина: $3",
        "svg-long-desc-animated": "Анимирана SVG датотека, номинално: $1 × $2 пиксела, величина: $3",
        "exif-dc-relation": "Сродни медији",
        "exif-dc-rights": "Права",
        "exif-dc-source": "Извор медија",
-       "exif-dc-type": "Ð\92Ñ\80Ñ\81Ñ\82а медија",
+       "exif-dc-type": "Тип медија",
        "exif-rating-rejected": "Одбијено",
        "exif-isospeedratings-overflow": "Веће од 65535",
        "exif-maxaperturevalue-value": "$1 APEX (f/$2)",
        "json-error-utf8": "Малформирани UTF-8 знаци, могуће је да су неисправно енкодирани",
        "json-error-recursion": "Једна или више рекурзивних референци у вредности коју треба енкодирати.",
        "json-error-inf-or-nan": "Једна или више NAN или INF вредности у вредности коју треба енкодирати",
-       "json-error-unsupported-type": "Дата је вреднос врсте која се не може енкодирати",
+       "json-error-unsupported-type": "Дата је вредност типа која се не може енкодирати",
        "headline-anchor-title": "Веза до овог одељка",
        "special-characters-group-latin": "Латиница",
        "special-characters-group-latinextended": "Проширена латиница",
        "log-action-filter-patrol": "Тип патролирања:",
        "log-action-filter-protect": "Тип заштите:",
        "log-action-filter-rights": "Тип промене корисничких права:",
-       "log-action-filter-suppress": "Ð\92Ñ\80Ñ\81Ñ\82а скривања:",
+       "log-action-filter-suppress": "Тип скривања:",
        "log-action-filter-upload": "Тип отпремања:",
        "log-action-filter-all": "Све",
        "log-action-filter-block-block": "блокирање",
        "cannotauth-not-allowed": "Није Вам дозвољено да користите ову страницу",
        "changecredentials": "Промена акредитива",
        "changecredentials-submit": "Промени",
-       "changecredentials-invalidsubpage": "â\80\9e$1â\80\9c Ð½Ð¸Ñ\98е Ð²Ð°Ð»Ð¸Ð´Ð½Ð° Ð²Ñ\80Ñ\81Ñ\82а акредитива.",
+       "changecredentials-invalidsubpage": "â\80\9e$1â\80\9c Ð½Ð¸Ñ\98е Ð²Ð°Ð¶ÐµÑ\9bи Ñ\82ип акредитива.",
        "changecredentials-success": "Ваши акредитиви су промењени.",
        "removecredentials": "Уклањање акредитива",
        "removecredentials-submit": "Уклањање акредитива",
-       "removecredentials-invalidsubpage": "â\80\9e$1â\80\9c Ð½Ð¸Ñ\98е Ð²Ð°Ð»Ð¸Ð´Ð½Ð° Ð²Ñ\80Ñ\81Ñ\82а акредитива.",
+       "removecredentials-invalidsubpage": "â\80\9e$1â\80\9c Ð½Ð¸Ñ\98е Ð²Ð°Ð¶ÐµÑ\9bи Ñ\82ип акредитива.",
        "removecredentials-success": "Ваши акредитиви су уклоњени.",
        "credentialsform-provider": "Тип акредитива:",
        "credentialsform-account": "Назив налога:",
index 85a67bf..445cfa9 100644 (file)
        "group-autoconfirmed-member": "{{GENDER:$1|bekräftad användare}}",
        "group-bot-member": "{{GENDER:$1|robot}}",
        "group-sysop-member": "{{GENDER:$1|administratör}}",
-       "group-interface-admin-member": "{{GENDER:$1|gränssnittsadministratörer}}",
+       "group-interface-admin-member": "{{GENDER:$1|gränssnittsadministratör}}",
        "group-bureaucrat-member": "{{GENDER:$1|byråkrat}}",
        "group-suppress-member": "{{GENDER:$1|censor}}",
        "grouppage-user": "{{ns:project}}:Användare",
index bcb7cea..c4590dc 100644 (file)
        "ns-specialprotected": "சிறப்புப் பக்கங்களைத் தொகுக்க முடியாது.",
        "titleprotected": "பயனர் [[User:$1|$1]] இத்தலைப்பு உருவாக்கப்படுவதை தவிர்க்கும் வகையில் தடுத்துள்ளார்.\nகொடுக்கப்பட்டக் காரணம் <em>$2</em>.",
        "filereadonlyerror": "\"$1\" கோப்பைத் திருத்த முடியவில்லை ஏனெனில் கோப்புப் பெட்டகம் \"$2\" படிக்க-மட்டும் வகையில் உள்ளது. அதனை பூட்டிய நிர்வாகி பின்வரும் விளக்கத்தை அளித்துள்ளார்: \"$3\"",
+       "invalidtitle": "செல்லத்தகாத தலைப்பு",
        "invalidtitle-knownnamespace": "பெயரிடைவெளி ' $2 '' மற்றும் உரை '' $3 '' கொன்ட தலைப்பு செல்லாது",
        "invalidtitle-unknownnamespace": "அறியப்படாத பெயரிடைவெளி $1 மற்றும் உரை $2 கொண்ட தலைப்பு செல்லாது",
        "exception-nologin": "புகுபதிகை செய்யப்படவில்லை.",
        "cannotloginnow-title": "இப்பொழுது விடுபதிகை செய்ய இயலாது.",
        "cannotloginnow-text": "$1-ஐ பயன்படுத்தும் பொழுது விடுபதிகை சாத்தியம் அல்ல.",
        "cannotcreateaccount-title": "கணக்கைத் தொடங்க முடியாது",
+       "cannotcreateaccount-text": "இவ்விக்கியில் நேரடி கணக்குத்தொடக்கம் இயக்கப்படவில்லை",
        "yourdomainname": "உங்கள் உரிமைப்பரப்பு:",
        "password-change-forbidden": "நீங்கள் விக்கிகளில் கடவுச் சொற்களை மாற்ற முடியாது",
        "externaldberror": "வெளி உறுதிப்படுத்தலில் ஏற்பட்ட தவறு காரணமாக உங்கள் வெளி கணக்கை இற்றைப்படுத்த முடியாது.",
        "userlogin-resetpassword-link": "உங்கள் கடவுச் சொல்லை மறந்து விட்டீர்களா?",
        "userlogin-helplink2": "உள்நுழைவதற்கு உதவி",
        "userlogin-loggedin": "நீங்கள் {{GENDER:$1|$1}} ஆக புகுபதியவில்லை.\nகீழ் உள்ள படிவத்தை பயன்படுத்தி இன்னொரு பயனராக புகுபதிவு செய்க.",
+       "userlogin-reauth": "{{GENDER:$1|$1}} என்பதை உறுதிசெய்ய நீங்கள் உள்புக வேண்டும்.",
        "userlogin-createanother": "மற்றொரு கணக்கு ஒன்றை உருவாக்கவும்",
        "createacct-emailrequired": "மின்னஞ்சல் முகவரி",
        "createacct-emailoptional": "மின்னஞ்சல் முகவரி (விருப்பத்தேர்வு)",
        "createacct-email-ph": "உங்கள் மின்னஞ்சல் முகவரியை உள்ளிடுக",
        "createacct-another-email-ph": "உங்கள் மின்னஞ்சல் முகவரியை உள்ளிடுக",
        "createaccountmail": "தற்காலிகமாக எழுந்தமான ஒரு கடவுச்சொல்லை பயன்படுத்துக, அதை குறித்துள்ள மின்னஞ்சலுக்கு அனுப்புக",
+       "createaccountmail-help": "மற்றவருக்காக கடவுச்சொல்லை அறிந்துக்கொள்ளாமல் கணக்கைத் தொடங்க முடியும்.",
        "createacct-realname": "உண்மைப் பெயர் (விருப்பத்தேர்வு)",
        "createacct-reason": "காரணம்",
        "createacct-reason-ph": "தாங்கள் ஏன் மற்றொரு கணக்கைத் துவங்குகிறீர்கள்?",
        "postedit-confirmation-created": "இந்தப் பக்கம் உருவாக்கபட்டுள்ளது",
        "postedit-confirmation-restored": "இந்தப் பக்கம் மீட்டமைக்கப்பட்டது.",
        "postedit-confirmation-saved": "உங்களது தொகுப்பு சேமிக்கப்பட்டது.",
+       "postedit-confirmation-published": "தங்கள் தொகுப்பு பதிப்பிக்கப்பட்டுவிட்டது.",
        "edit-already-exists": "புதிய பக்கமொன்றை உருவாக்க முடியாது.\nஇப்பக்கம் ஏற்கனவே உள்ளது.",
        "defaultmessagetext": "இயல்பிருப்பு தகவல் உரை",
        "content-failed-to-parse": "உள்ளடக்கம் $2 வகை $1 இற்காக பாகுபடுத்தல் தோல்வி: $3",
        "prefs-watchlist-edits": "விரிவாக்கப்பட்ட கவனிப்புப் பட்டியலில் காட்டவேண்டிய தொகுப்புகளின் எண்ணிக்கை:",
        "prefs-watchlist-edits-max": "(அதிக அளவான எண்: 1000)",
        "prefs-watchlist-token": "கவனிப்பு பட்டியலின் அடையாளம்:",
+       "prefs-watchlist-managetokens": "வில்லைகளை நிர்வகிக்க",
        "prefs-misc": "பலதரப்பட்டவை",
        "prefs-resetpass": "கடவுச்சொல்லை மாற்றுக",
        "prefs-changeemail": "மின்னஞ்சல் முகவரியை மாற்று / நீக்கு",
        "recentchanges-legend-heading": "<strong>குறியீட்டு விளக்கம்:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|புதிய பக்கங்கள் பட்டியலையும்]] காணவும்)",
        "recentchanges-submit": "காட்டு",
+       "rcfilters-activefilters-hide": "மறைக்க",
+       "rcfilters-activefilters-show": "காட்டு",
        "rcfilters-days-title": "அண்மைய தினங்கள்",
        "rcfilters-hours-title": "அண்மைய நேரங்கள்",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|நாள்|நாட்கள்}}",
        "rcfilters-savedqueries-apply-label": "வடிப்பானை உருவாக்குக",
        "rcfilters-savedqueries-apply-and-setdefault-label": "தன்னியல்பு வடிப்பானை உருவாக்குக",
        "rcfilters-savedqueries-cancel-label": "ரத்து செய்",
+       "rcfilters-invalid-filter": "செல்லத்தகாத வடிப்பான்",
        "rcfilters-filterlist-title": "வடிப்பான்கள்",
        "rcfilters-highlightmenu-title": "ஒரு நிறத்தை தேர்ந்தெடுக்கவும்",
        "rcfilters-filterlist-noresults": "எந்த வடிப்பானும் காணப்படவில்லை",
        "rcfilters-filter-editsbyself-description": "தங்களது தொகுப்புகள்.",
        "rcfilters-filter-editsbyother-label": "மற்றவர் தொகுப்புகள்",
        "rcfilters-filter-user-experience-level-registered-label": "பதிவுசெய்யப்பட்டது",
+       "rcfilters-filter-user-experience-level-registered-description": "உள்நுழைந்த தொகுப்பாளர்கள்.",
        "rcfilters-filter-user-experience-level-unregistered-label": "பதிவு நீக்கம் செய்யப்பட்டது",
+       "rcfilters-filter-user-experience-level-unregistered-description": "உள்புகாத தொகுப்பாளர்கள்",
        "rcfilters-filter-user-experience-level-newcomer-label": "புது வரவுகள்",
        "rcfilters-filter-user-experience-level-learner-label": "கற்போர்",
        "rcfilters-filter-user-experience-level-experienced-label": "அனுபவமுள்ள பயனர்கள்",
        "rcfilters-filter-bots-description": "தானியக்க கருவிகளால ஆன தொகுப்புகள்",
        "rcfilters-filter-humans-label": "மனிதன் (தானியங்கி அல்ல)",
        "rcfilters-filter-humans-description": "மனித தொகுப்பாளர்களால் ஆன தொகுப்பு",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "சுற்றித்திரியாதவை",
+       "rcfilters-filter-reviewstatus-auto-label": "தானியக்கமாக ரோந்திடப்பட்டது",
        "rcfilters-filtergroup-significance": "சிறப்பு",
        "rcfilters-filter-minor-label": "சிறு தொகுப்பு",
+       "rcfilters-filter-major-label": "சிறுமையில்லா தொகுப்புகள்",
+       "rcfilters-filtergroup-watchlist": "பார்க்கப்படும் பக்கங்கள்",
        "rcfilters-filtergroup-changetype": "மாற்ற வகை",
        "rcfilters-filter-pageedits-label": "பக்க தொகுப்புகள்",
        "rcfilters-filter-newpages-label": "பக்க உருவாக்கங்கள்",
+       "rcfilters-filtergroup-lastRevision": "அண்மைய திருத்தங்கள்",
        "rcfilters-filter-lastrevision-label": "அண்மைய திருத்தம்",
+       "rcfilters-filter-excluded": "தவிர்க்கப்பட்டது",
        "rcnotefrom": "கீழே காணப்படுவது <strong>$3, $4</strong> இலிருந்து செய்யப்பட்ட (<strong>$1</strong> வரைக் காட்டப்பட்டுள்ளது) {{PLURAL:$5|மாற்றமாகும்.|மாற்றங்களாகும்.}}",
        "rclistfrom": "$2, $3 முதல் இன்று வரை செய்யப்பட்ட புதிய மாற்றங்களைக் காட்டவும்",
        "rcshowhideminor": "சிறிய தொகுப்புகளை $1",
        "upload-copy-upload-invalid-domain": "இந்தக் களத்தில் இருந்து படியெடுத்துப் பதிவேற்றம் செய்யும் வசதி கிடையாது.",
        "upload-dialog-title": "கோப்பைப் பதிவேற்று",
        "upload-dialog-button-cancel": "ரத்து செய்",
+       "upload-dialog-button-back": "பின் செல்",
        "upload-dialog-button-done": "முடிந்தது",
        "upload-dialog-button-save": "சேமி",
        "upload-dialog-button-upload": "பதிவேற்று",
        "uploadstash-badtoken": "அந்த செயலுக்கான நடவடிக்கை தோல்வியடைந்தது, ஒருவேளை ஏனென்றால் உங்கள் திருத்த அறிமுகசான்றுகள் காலாவதியாகிவிட்டது. மீண்டும் முயற்சி செய்.",
        "uploadstash-errclear": "கோப்புகளை சரிசெய்தல் (Clearing) தோல்வியடைந்து விட்டது.",
        "uploadstash-refresh": "கோப்புகள் உள்ள பட்டியலை புதுப்பி",
+       "uploadstash-thumbnail": "நகப்படத்தை காட்டுக",
+       "uploadstash-bad-path": "வழி இடம்பெறவில்லை",
+       "uploadstash-bad-path-invalid": "வழி செல்லத்தாகது",
+       "uploadstash-file-not-found-no-thumb": "நகப்படத்தை பெறமுடியவில்லை",
+       "uploadstash-zero-length": "கோப்பின் நீளம் சுழியம்",
        "invalid-chunk-offset": "செல்லாத chunk offset",
        "img-auth-accessdenied": "அனுமதி மறுக்கப்பட்டது",
        "img-auth-nopathinfo": "PATH_INFO காணவில்லை.\nஉங்கள் வழங்கி இந்தத் தகவலை அனுப்ப அமைக்கப்படவில்லை\nஇது சிஜிஐ (CGI)- அடிப்படையிலானதாகவோ img_auth-ஐ ஆதரக்காததாகவோ இருக்கலாம் .\nபார்க்கவும் https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "apisandbox-reset": "வெறுமையாக்கு",
        "apisandbox-retry": "மறு முயற்சி செய்",
        "apisandbox-examples": "உதாரணங்கள்",
+       "apisandbox-add-multi": "சேர்",
        "apisandbox-results": "முடிவுகள்",
        "apisandbox-sending-request": "API வேண்டுகோள் அனுப்பப்படுகிறது...",
        "apisandbox-loading-results": "API முடிவுகள் பெறப்படுகின்றன...",
        "listgrouprights-namespaceprotection-header": "பெயர்வெளி கட்டுப்பாடு",
        "listgrouprights-namespaceprotection-namespace": "பெயர்வெளி",
        "listgrouprights-namespaceprotection-restrictedto": "பயனரை திருத்த அனுமதிக்கும் உரிமை(கள்)",
+       "listgrants": "நல்கைகள்",
        "listgrants-grant": "நல்கை",
        "listgrants-rights": "அணுக்கங்கள்",
        "trackingcategories": "பகுப்புகளை தடமறி",
        "dellogpage": "நீக்கல் பதிவு",
        "dellogpagetext": "கீழே காணப்படுவது மிக அண்மைய நீக்கல்களின் அட்டவணையாகும்.",
        "deletionlog": "நீக்கல் பதிவு",
+       "log-name-create": "பக்க உருவாக்க குறிப்பு",
        "reverted": "முன் திருத்தத்துக்கு முன்நிலையாக்கப்பட்டது",
        "deletecomment": "காரணம்:",
        "deleteotherreason": "வேறு மேலதிக காரணம்:",
        "unblocked-id": "$1 தடை நீக்கப்பட்டது",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] முடக்கப்பட்டார்.",
        "blocklist": "தடைசெய்யப்பட்ட பயனர்கள்",
+       "autoblocklist": "தன்னியக்கத் தடை",
+       "autoblocklist-submit": "தேடுக",
+       "autoblocklist-legend": "தானியக்க தடைகளை பட்டியலிடுக",
        "ipblocklist": "தடைசெய்யப்பட்ட பயனர்கள்",
        "ipblocklist-legend": "தடுக்கப்பட்ட பயனரொருவரைத் தேடு",
        "blocklist-userblocks": "கணக்கு தடுப்புகளை மறை",
index 0821219..f873f83 100644 (file)
        "readonlywarning": "<strong>Кисәтү: мәгълүматлар базасында техник эшләр башкарыла, сезнең үзгәртүләр хәзер үк саклана алмый.</strong>\nБез сезгә әлеге текстны, югалмас өчен, берәр файлга сакларга тәкъдим итәбез.\n\nМәгълүматлар базасын япкан идарәче күрсәткән сәбәп: $1",
        "protectedpagewarning": "'''Кисәтү: сез бу битне үзгәртә алмыйсыз, бу хокукка идарәчеләр гына ия.'''\nТүбәндә көндәлекнең  соңгы язуы бирелгән:",
        "semiprotectedpagewarning": "<strong>Кисәтү:</strong> бу бит якланган. Аны авторасланган кулланучылар гына үзгәртә ала.\nАста бу битнең күзәтү көндәлегендә булган соңгы язмасы бирелгән:",
-       "cascadeprotectedwarning": "<strong>Кисәтү:</strong> Бу битне идарәчеләр гына үзгәртә ала., чөнки бит {{PLURAL:$1|каскадлы яклау исемлегенә кертелгән}}:",
+       "cascadeprotectedwarning": "<strong>Кисәтү:</strong> Бу бит якланган һәм аны бары [[Special:ListGroupRights|махсус вәкаләтләре]] булган кулланучылар гына үзгәртә ала, чөнки бит {{PLURAL:$1|каскадлы яклау исемлегенә кертелгән}}:",
        "titleprotectedwarning": "'''Кисәтү: Мондый исемле бит якланган, аны үзгәртү өчен [[Special:ListGroupRights|тиешле хокукка]] ия булу зарур.'''\nАста күзәтү көндәлегендәге соңгы язма бирелгән:",
        "templatesused": "Бу биттә кулланылган {{PLURAL:$1|1=калып|калыплар}} :",
        "templatesusedpreview": "Алдан карау мөмкинлегендә кулланылган {{PLURAL:$1|1=калып|калыплар}}:",
        "diff-multi-otherusers": "({{PLURAL:$2|Башка бер кулланучының|$2 кулланучының}} {{PLURAL:$1|бер арадаш юрамасы|$1 арадаш юрамасы}} күрсәтелмәгән)",
        "diff-multi-manyusers": "($2 күбрәк {{PLURAL:$2|кулланучының|кулланучының}} {{PLURAL:$1|Бер арадаш юрамасы|$1 арадаш юрамасы}} күрсәтелмәгән)",
        "searchresults": "Эзләү нәтиҗәләре",
+       "search-filter-title-prefix-reset": "Барлык битләрне эзләү",
        "searchresults-title": "«$1» өчен эзләү нәтиҗәләре",
        "titlematches": "Бит исемнәрендә тиңдәшлек",
        "textmatches": "Бит эчтәлегендә тиңдәшлек",
        "search-category": "($1 категориясе)",
        "search-file-match": "(файл эчтәлеге белән туры килә)",
        "search-suggest": "Бәлки, сез моны эзлисез: $1",
+       "search-rewritten": "$1 нәтижәсе күрсәтелгән. $2 урынына эзләргә.",
        "search-interwiki-caption": "Тугандаш проектлар нәтиҗәсе",
        "search-interwiki-default": "$1 нәтиҗә:",
        "search-interwiki-more": "(тагын)",
        "prefs-editwatchlist-clear": "Күзәтү исемлеген чистарту",
        "prefs-watchlist-days": "Күзәтү исемлегендә күрсәтелгән көннәр саны:",
        "prefs-watchlist-days-max": "Иң күбе $1 {{PLURAL:$1|1=көн|көн}}",
-       "prefs-watchlist-edits": "Киңәйтелгән күзәтү исемлегендә күрсәтелүче төзәтмәләрнең максималь саны:",
+       "prefs-watchlist-edits": "Күзәтү исемлегендә күрсәтелүче төзәтмәләрнең максималь саны:",
        "prefs-watchlist-edits-max": "Иң күбе: 1000",
        "prefs-watchlist-token": "Күзәтү исемлеге токены:",
        "prefs-watchlist-managetokens": "Токеннар беләр идарә итү",
        "stub-threshold-disabled": "Сүнгән",
        "recentchangesdays": "Соңгы үзгәртүләрне күрсәтүче көннәр саны:",
        "recentchangesdays-max": "(иң күбе $1 {{PLURAL:$1|көн}})",
-       "recentchangescount": "Төп буларак кулланучы үзгәртүләр саны:",
+       "recentchangescount": "Төп буларак кулланучы соңгы үзгәртүләр исемелегендә, тарихта һәм көндәлектә булган үзгәртүләр саны:",
        "prefs-help-recentchangescount": "Иң күбе: 1000",
        "prefs-help-watchlist-token2": "Бу сезнең кузәтү исемлеге өчен ясалган веб-агымының серле ачкычы.\nАны белгән һәркем сезнең күзәтү исемлегегезне карый ала, шуңа да башкаларга аны күрсәтмәгез. [[Special:ResetTokens|Ачкычны ташларга теләсәгез, әлеге юрамага басыгыз]].",
        "savedprefs": "Көйләнмәләрегез сакланды.",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (шулай ук [[Special:NewPages|яңа битләр исемлеген]] карагыз)",
        "recentchanges-submit": "Күрсәт",
        "rcfilters-legend-heading": "<strong>Кыскартулар тезмәсе:&nbsp;</strong>",
+       "rcfilters-group-results-by-page": "Нәтиҗәләрне биттә төркемләргә",
        "rcfilters-activefilters": "Актив фильтрлар",
        "rcfilters-activefilters-hide": "Яшер",
        "rcfilters-activefilters-show": "Күрсәт",
        "rcfilters-limit-title": "Күрсәтү өчен үзгәртүләр",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|үзгәртү}}, $2",
+       "rcfilters-date-popup-title": "Эзләү өчен вакыт аралыгы",
        "rcfilters-days-title": "Соңгы көннәр",
        "rcfilters-hours-title": "Соңгы сәгатьләр",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|көн}}",
        "rcfilters-filter-user-experience-level-unregistered-label": "Теркәлмәгәннәр",
        "rcfilters-filter-user-experience-level-unregistered-description": "Системага кермәгән мөхәррирләр.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Яңа кулланучылар",
+       "rcfilters-filter-user-experience-level-learner-label": "Укучылар",
        "rcfilters-filter-user-experience-level-experienced-label": "Тәҗрибәле кулланучылар",
        "rcfilters-filter-user-experience-level-experienced-description": "Төзәтүләре 500 дән күбрәк һәм актив эш көннәре 30 дан артык теркәлгән мөхәррирләр",
        "rcfilters-filtergroup-automated": "Автоматлаштырылган кертем",
diff --git a/maintenance/archives/patch-recentchanges-rc_this_oldid-index.sql b/maintenance/archives/patch-recentchanges-rc_this_oldid-index.sql
new file mode 100644 (file)
index 0000000..364256b
--- /dev/null
@@ -0,0 +1,6 @@
+-- Add an index to recentchanges on rc_this_oldid
+--
+-- T139012
+--
+
+CREATE INDEX /*i*/rc_this_oldid ON /*_*/recentchanges(rc_this_oldid);
\ No newline at end of file
index f040c15..ebbd6e3 100644 (file)
@@ -1052,6 +1052,7 @@ CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp
 CREATE INDEX /*i*/rc_ns_actor ON /*_*/recentchanges (rc_namespace, rc_actor);
 CREATE INDEX /*i*/rc_actor ON /*_*/recentchanges (rc_actor, rc_timestamp);
 CREATE INDEX /*i*/rc_name_type_patrolled_timestamp ON /*_*/recentchanges (rc_namespace, rc_type, rc_patrolled, rc_timestamp);
+CREATE INDEX /*i*/rc_this_oldid ON /*_*/recentchanges (rc_this_oldid);
 
 
 CREATE TABLE /*_*/watchlist (
index b5e423d..7497c20 100644 (file)
@@ -721,6 +721,7 @@ CREATE INDEX &mw_prefix.recentchanges_i07 ON &mw_prefix.recentchanges (rc_user_t
 CREATE INDEX &mw_prefix.rc_ns_actor ON &mw_prefix.recentchanges (rc_namespace, rc_actor);
 CREATE INDEX &mw_prefix.rc_actor ON &mw_prefix.recentchanges (rc_actor, rc_timestamp);
 CREATE INDEX &mw_prefix.recentchanges_i08 ON &mw_prefix.recentchanges (rc_namespace, rc_type, rc_patrolled, rc_timestamp);
+CREATE INDEX &mw_prefix.recentchanges_i10 ON &mw_prefix.recentchanges (rc_this_oldid);
 /*$mw$*/
 CREATE TRIGGER &mw_prefix.recentchanges_seq_trg BEFORE INSERT ON &mw_prefix.recentchanges
        FOR EACH ROW WHEN (new.rc_id IS NULL)
index adf2688..db68248 100644 (file)
@@ -588,6 +588,7 @@ CREATE INDEX rc_cur_id          ON recentchanges (rc_cur_id);
 CREATE INDEX new_name_timestamp ON recentchanges (rc_new, rc_namespace, rc_timestamp);
 CREATE INDEX rc_ip              ON recentchanges (rc_ip);
 CREATE INDEX rc_name_type_patrolled_timestamp ON recentchanges (rc_namespace, rc_type, rc_patrolled, rc_timestamp);
+CREATE INDEX rc_this_oldid      ON recentchanges (rc_this_oldid);
 
 
 CREATE SEQUENCE watchlist_wl_id_seq;
index b503bba..8cda4f9 100644 (file)
@@ -1471,6 +1471,8 @@ CREATE INDEX /*i*/rc_actor ON /*_*/recentchanges (rc_actor, rc_timestamp);
 -- ApiQueryRecentChanges (T140108)
 CREATE INDEX /*i*/rc_name_type_patrolled_timestamp ON /*_*/recentchanges (rc_namespace, rc_type, rc_patrolled, rc_timestamp);
 
+-- Article.php and friends (T139012)
+CREATE INDEX /*i*/rc_this_oldid ON /*_*/recentchanges (rc_this_oldid);
 
 CREATE TABLE /*_*/watchlist (
   wl_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
index 01aace0..12a454a 100644 (file)
@@ -66,7 +66,8 @@ class UpdateSpecialPages extends Maintenance {
                                continue;
                        }
 
-                       $specialObj = SpecialPageFactory::getPage( $special );
+                       $specialObj = MediaWikiServices::getInstance()->getSpecialPageFactory()->
+                               getPage( $special );
                        if ( !$specialObj ) {
                                $this->output( "No such special page: $special\n" );
                                exit;
index 8bd37dd..264b5eb 100644 (file)
@@ -1,6 +1,17 @@
 <?php
 /**
- * Show profiling data.
+ * Simple interface for displaying request profile data stored in
+ * the wikis' primary database.
+ *
+ * See also https://www.mediawiki.org/wiki/Manual:Profiling.
+ *
+ * To add profiling information to the database:
+ *
+ * - set $wgProfiler['class'] in LocalSetings.php to a Profiler class other than ProfilerStub.
+ * - set $wgProfiler['output'] to 'db' to force the profiler to save its the
+ *   information in the database.
+ * - apply the maintenance/archives/patch-profiling.sql patch to the database.
+ * - set $wgEnableProfileInfo to true.
  *
  * Copyright 2005 Kate Turner.
  *
@@ -32,7 +43,6 @@ define( 'MW_NO_SESSION', 'warn' );
 
 ini_set( 'zlib.output_compression', 'off' );
 
-$wgEnableProfileInfo = false;
 require __DIR__ . '/includes/WebStart.php';
 
 header( 'Content-Type: text/html; charset=utf-8' );
@@ -155,7 +165,7 @@ $dbr = wfGetDB( DB_REPLICA );
 if ( !$dbr->tableExists( 'profiling' ) ) {
        echo '<p>No <code>profiling</code> table exists, so we can\'t show you anything.</p>'
                . '<p>If you want to log profiling data, enable <code>$wgProfiler[\'output\'] = \'db\'</code>'
-               . ' in your StartProfiler.php and run <code>maintenance/update.php</code> to'
+               . ' in LocalSettings.php and run <code>maintenance/update.php</code> to'
                . ' create the profiling table.'
                . '</body></html>';
        exit( 1 );
index 3cc5f4a..e912242 100644 (file)
@@ -224,9 +224,6 @@ return [
                'scripts' => 'resources/lib/jquery/jquery.cookie.js',
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'jquery.expandableField' => [
-               'scripts' => 'resources/src/jquery/jquery.expandableField.js',
-       ],
        'jquery.form' => [
                'scripts' => 'resources/lib/jquery/jquery.form.js',
        ],
diff --git a/resources/src/jquery/jquery.expandableField.js b/resources/src/jquery/jquery.expandableField.js
deleted file mode 100644 (file)
index c3d39da..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * This plugin provides functionality to expand a text box on focus to double it's current width
- *
- * Usage:
- *
- * Set options:
- *             $('#textbox').expandableField( { option1: value1, option2: value2 } );
- *             $('#textbox').expandableField( option, value );
- * Get option:
- *             value = $('#textbox').expandableField( option );
- * Initialize:
- *             $('#textbox').expandableField();
- *
- * Options:
- */
-( function ( $ ) {
-
-       $.expandableField = {
-               /**
-                * Expand the field, make the callback
-                *
-                * @param {jQuery.Event} e Event
-                * @param {Object} context
-                */
-               expandField: function ( e, context ) {
-                       context.config.beforeExpand.call( context.data.$field, context );
-                       context.data.$field
-                               .animate( { width: context.data.expandedWidth }, 'fast', function () {
-                                       context.config.afterExpand.call( this, context );
-                               } );
-               },
-               /**
-                * Condense the field, make the callback
-                *
-                * @param {jQuery.Event} e Event
-                * @param {Object} context
-                */
-               condenseField: function ( e, context ) {
-                       context.config.beforeCondense.call( context.data.$field, context );
-                       context.data.$field
-                               .animate( { width: context.data.condensedWidth }, 'fast', function () {
-                                       context.config.afterCondense.call( this, context );
-                               } );
-               },
-               /**
-                * Sets the value of a property, and updates the widget accordingly
-                *
-                * @param {Object} context
-                * @param {string} property Name of property
-                * @param {Mixed} value Value to set property with
-                */
-               configure: function ( context, property, value ) {
-                       // TODO: Validate creation using fallback values
-                       context.config[ property ] = value;
-               }
-
-       };
-
-       $.fn.expandableField = function () {
-
-               // Multi-context fields
-               var returnValue,
-                       args = arguments;
-
-               $( this ).each( function () {
-                       var key, context, timeout;
-
-                       /* Construction / Loading */
-
-                       context = $( this ).data( 'expandableField-context' );
-
-                       // TODO: Do we need to check both null and undefined?
-                       if ( context === undefined || context === null ) {
-                               context = {
-                                       config: {
-                                               // callback function for before collapse
-                                               beforeCondense: function () {},
-
-                                               // callback function for before expand
-                                               beforeExpand: function () {},
-
-                                               // callback function for after collapse
-                                               afterCondense: function () {},
-
-                                               // callback function for after expand
-                                               afterExpand: function () {},
-
-                                               // Whether the field should expand to the left or the right -- defaults to left
-                                               expandToLeft: true
-                                       }
-                               };
-                       }
-
-                       /* API */
-                       // Handle various calling styles
-                       if ( args.length > 0 ) {
-                               if ( typeof args[ 0 ] === 'object' ) {
-                                       // Apply set of properties
-                                       for ( key in args[ 0 ] ) {
-                                               $.expandableField.configure( context, key, args[ 0 ][ key ] );
-                                       }
-                               } else if ( typeof args[ 0 ] === 'string' ) {
-                                       if ( args.length > 1 ) {
-                                               // Set property values
-                                               $.expandableField.configure( context, args[ 0 ], args[ 1 ] );
-
-                                       // TODO: Do we need to check both null and undefined?
-                                       } else if ( returnValue === null || returnValue === undefined ) {
-                                               // Get property values, but don't give access to internal data - returns only the first
-                                               returnValue = ( args[ 0 ] in context.config ? undefined : context.config[ args[ 0 ] ] );
-                                       }
-                               }
-                       }
-
-                       /* Initialization */
-
-                       if ( context.data === undefined ) {
-                               context.data = {
-                                       // The width of the field in it's condensed state
-                                       condensedWidth: $( this ).width(),
-
-                                       // The width of the field in it's expanded state
-                                       expandedWidth: $( this ).width() * 2,
-
-                                       // Reference to the field
-                                       $field: $( this )
-                               };
-
-                               $( this )
-                                       .addClass( 'expandableField' )
-                                       .focus( function ( e ) {
-                                               clearTimeout( timeout );
-                                               $.expandableField.expandField( e, context );
-                                       } )
-                                       .blur( function ( e ) {
-                                               timeout = setTimeout( function () {
-                                                       $.expandableField.condenseField( e, context );
-                                               }, 250 );
-                                       } );
-                       }
-                       // Store the context for next time
-                       $( this ).data( 'expandableField-context', context );
-               } );
-               return returnValue !== undefined ? returnValue : $( this );
-       };
-
-}( jQuery ) );
index 663950a..35c6a5d 100644 (file)
@@ -6,10 +6,6 @@
  *             $( '#textbox' ).suggestions( { option1: value1, option2: value2 } );
  *             $( '#textbox' ).suggestions( option, value );
  *
- * Get option:
- *
- *             value = $( '#textbox' ).suggestions( option );
- *
  * Initialize:
  *
  *             $( '#textbox' ).suggestions();
 
        // See file header for method documentation
        $.fn.suggestions = function () {
-
                // Multi-context fields
-               var returnValue,
-                       args = arguments;
+               var args = arguments;
 
                $( this ).each( function () {
                        var context, key;
                                        if ( args.length > 1 ) {
                                                // Set property values
                                                $.suggestions.configure( context, args[ 0 ], args[ 1 ] );
-                                       } else if ( returnValue === null || returnValue === undefined ) {
-                                               // Get property values, but don't give access to internal data - returns only the first
-                                               returnValue = ( args[ 0 ] in context.config ? undefined : context.config[ args[ 0 ] ] );
                                        }
                                }
                        }
                        // Store the context for next time
                        $( this ).data( 'suggestions-context', context );
                } );
-               return returnValue !== undefined ? returnValue : $( this );
+               return this;
        };
 
        /**
index 2f7a6c8..6972165 100644 (file)
@@ -947,7 +947,9 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         * @return MediaWikiServices
         * @throws MWException
         */
-       protected function overrideMwServices( Config $configOverrides = null, array $services = [] ) {
+       protected static function overrideMwServices(
+               Config $configOverrides = null, array $services = []
+       ) {
                if ( !$configOverrides ) {
                        $configOverrides = new HashConfig();
                }
index 5606924..0e35767 100644 (file)
@@ -61,7 +61,7 @@ class PrefixSearchTest extends MediaWikiLangTestCase {
                $this->originalHandlers = TestingAccessWrapper::newFromClass( Hooks::class )->handlers;
                TestingAccessWrapper::newFromClass( Hooks::class )->handlers = [];
 
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
        }
 
        public function tearDown() {
@@ -69,7 +69,7 @@ class PrefixSearchTest extends MediaWikiLangTestCase {
 
                TestingAccessWrapper::newFromClass( Hooks::class )->handlers = $this->originalHandlers;
 
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
        }
 
        protected function searchProvision( array $results = null ) {
index fe2058f..129b7f9 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @group API
  * @group medium
@@ -107,7 +109,7 @@ class ApiQuerySiteinfoTest extends ApiTestCase {
 
        public function testSpecialPageAliases() {
                $this->assertCount(
-                       count( SpecialPageFactory::getNames() ),
+                       count( MediaWikiServices::getInstance()->getSpecialPageFactory()->getNames() ),
                        $this->doQuery( 'specialpagealiases' )
                );
        }
index 16048bf..54dc583 100644 (file)
@@ -317,7 +317,8 @@ JAVASCRIPT
                        [
                                // Regression test for T201606.
                                // Must not break between 'return' and Expression.
-                               // FIXME: Cause?
+                               // Was caused by bad state after a ternary in the expression value
+                               // for a key in an object literal.
                                <<<JAVASCRIPT
 call( {
        key: 1 ? 0 : function () {
@@ -340,7 +341,7 @@ JAVASCRIPT
                                        '(',
                                        ')',
                                        '{',
-                                       'return', 'this', // FIXME
+                                       'return this',
                                        ';',
                                        '}',
                                        '}',
index 83df61a..41c1218 100644 (file)
@@ -69,7 +69,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                $this->originalHandlers = TestingAccessWrapper::newFromClass( Hooks::class )->handlers;
                TestingAccessWrapper::newFromClass( Hooks::class )->handlers = [];
 
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
        }
 
        public function tearDown() {
@@ -77,7 +77,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
 
                TestingAccessWrapper::newFromClass( Hooks::class )->handlers = $this->originalHandlers;
 
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
        }
 
        protected function searchProvision( array $results = null ) {
index 1da6fb3..04a89d2 100644 (file)
@@ -21,22 +21,10 @@ use Wikimedia\ScopedCallback;
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  * http://www.gnu.org/copyleft/gpl.html
  *
- * @covers SpecialPageFactory
+ * @covers \MediaWiki\Special\SpecialPageFactory
  * @group SpecialPage
  */
 class SpecialPageFactoryTest extends MediaWikiTestCase {
-
-       protected function tearDown() {
-               parent::tearDown();
-
-               SpecialPageFactory::resetList();
-       }
-
-       public function testResetList() {
-               SpecialPageFactory::resetList();
-               $this->assertContains( 'Specialpages', SpecialPageFactory::getNames() );
-       }
-
        public function testHookNotCalledTwice() {
                $count = 0;
                $this->mergeMwGlobalArrayValue( 'wgHooks', [
@@ -45,9 +33,10 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                                        $count++;
                                }
                ] ] );
-               SpecialPageFactory::resetList();
-               SpecialPageFactory::getNames();
-               SpecialPageFactory::getNames();
+               $this->overrideMwServices();
+               $spf = MediaWikiServices::getInstance()->getSpecialPageFactory();
+               $spf->getNames();
+               $spf->getNames();
                $this->assertEquals( 1, $count );
        }
 
@@ -82,7 +71,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testGetPage( $spec, $shouldReuseInstance ) {
                $this->mergeMwGlobalArrayValue( 'wgSpecialPages', [ 'testdummy' => $spec ] );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                $page = SpecialPageFactory::getPage( 'testdummy' );
                $this->assertInstanceOf( SpecialPage::class, $page );
@@ -96,7 +85,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testGetNames() {
                $this->mergeMwGlobalArrayValue( 'wgSpecialPages', [ 'testdummy' => SpecialAllPages::class ] );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                $names = SpecialPageFactory::getNames();
                $this->assertInternalType( 'array', $names );
@@ -108,7 +97,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testResolveAlias() {
                $this->setContentLang( 'de' );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                list( $name, $param ) = SpecialPageFactory::resolveAlias( 'Spezialseiten/Foo' );
                $this->assertEquals( 'Specialpages', $name );
@@ -120,7 +109,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testGetLocalNameFor() {
                $this->setContentLang( 'de' );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                $name = SpecialPageFactory::getLocalNameFor( 'Specialpages', 'Foo' );
                $this->assertEquals( 'Spezialseiten/Foo', $name );
@@ -131,7 +120,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         */
        public function testGetTitleForAlias() {
                $this->setContentLang( 'de' );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
 
                $title = SpecialPageFactory::getTitleForAlias( 'Specialpages/Foo' );
                $this->assertEquals( 'Spezialseiten/Foo', $title->getText() );
@@ -146,11 +135,11 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
        ) {
                $lang = clone MediaWikiServices::getInstance()->getContentLanguage();
                $lang->mExtendedSpecialPageAliases = $aliasesList;
-               $this->setContentLang( $lang );
                $this->setMwGlobals( 'wgSpecialPages',
                        array_combine( array_keys( $aliasesList ), array_keys( $aliasesList ) )
                );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
+               $this->setContentLang( $lang );
 
                // Catch the warnings we expect to be raised
                $warnings = [];
@@ -278,7 +267,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                                }
                        ],
                ] );
-               SpecialPageFactory::resetList();
+               $this->overrideMwServices();
                SpecialPageFactory::getLocalNameFor( 'Specialpages' );
                $this->assertTrue( $called, 'Recursive call succeeded' );
        }
index d53a9b8..4a171df 100644 (file)
@@ -7,6 +7,8 @@
  * @author Antoine Musso
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @group Database
  * @covers QueryPage<extended>
@@ -43,7 +45,8 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase {
                        $class = $page[0];
                        $name = $page[1];
                        if ( !in_array( $class, $this->manualTest ) ) {
-                               $this->queryPages[$class] = SpecialPageFactory::getPage( $name );
+                               $this->queryPages[$class] =
+                                       MediaWikiServices::getInstance()->getSpecialPageFactory()->getPage( $name );
                        }
                }
        }
index 196321c..6ff2110 100644 (file)
@@ -231,7 +231,7 @@ class SpecialSearchTest extends MediaWikiTestCase {
 
                $ctx = new RequestContext;
                $sp = Title::newFromText( 'Special:Search/foo_bar' );
-               SpecialPageFactory::executePath( $sp, $ctx );
+               MediaWikiServices::getInstance()->getSpecialPageFactory()->executePath( $sp, $ctx );
                $url = $ctx->getOutput()->getRedirect();
                // some older versions of hhvm have a bug that doesn't parse relative
                // urls with a port, so help it out a little bit.
index abf1cdd..9d85fde 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Test that runs against all registered special pages to make sure that regular
  * execution of the special page does not cause a fatal error.
@@ -14,18 +16,19 @@ class SpecialPageFatalTest extends MediaWikiTestCase {
 
        public static function setUpBeforeClass() {
                parent::setUpBeforeClass();
-               SpecialPageFactory::resetList();
+               self::overrideMwServices();
        }
 
        public static function tearDownAfterClass() {
-               SpecialPageFactory::resetList();
+               self::overrideMwServices();
                parent::tearDownAfterClass();
        }
 
        public function provideSpecialPages() {
                $specialPages = [];
-               foreach ( SpecialPageFactory::getNames() as $name ) {
-                       $specialPages[$name] = [ SpecialPageFactory::getPage( $name ) ];
+               $spf = MediaWikiServices::getInstance()->getSpecialPageFactory();
+               foreach ( $spf->getNames() as $name ) {
+                       $specialPages[$name] = [ $spf->getPage( $name ) ];
                }
                return $specialPages;
        }