Merge "ApiSandbox: Fix sticky value for Webkit"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 27 Nov 2018 21:20:40 +0000 (21:20 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 27 Nov 2018 21:20:40 +0000 (21:20 +0000)
120 files changed:
RELEASE-NOTES-1.33
composer.json
includes/Revision/RenderedRevision.php
includes/Revision/RevisionRenderer.php
includes/Storage/DerivedPageDataUpdater.php
includes/api/ApiErrorFormatter.php
includes/api/ApiMain.php
includes/api/ApiMessageTrait.php
includes/api/ApiQueryLogEvents.php
includes/changetags/ChangeTags.php
includes/content/WikitextContent.php
includes/db/CloneDatabase.php
includes/installer/i18n/sv.json
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/parser/Parser.php
includes/parser/Sanitizer.php
includes/specials/forms/PreferencesFormOOUI.php
includes/specials/pagers/UsersPager.php
includes/user/User.php
languages/ConverterRule.php
languages/LanguageConverter.php
languages/i18n/ace.json
languages/i18n/ar.json
languages/i18n/arz.json
languages/i18n/ast.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frr.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/inh.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/ka.json
languages/i18n/km.json
languages/i18n/ko.json
languages/i18n/la.json
languages/i18n/lb.json
languages/i18n/lfn.json
languages/i18n/li.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/mai.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/nan.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/oc.json
languages/i18n/pl.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sah.json
languages/i18n/shn.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/tcy.json
languages/i18n/te.json
languages/i18n/th.json
languages/i18n/tr.json
languages/i18n/tt-cyrl.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/vi.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
resources/src/mediawiki.Title/Title.js
resources/src/mediawiki.ui/components/buttons.less
tests/parser/parserTests.txt
tests/phpunit/includes/Revision/RenderedRevisionTest.php
tests/phpunit/includes/Revision/RevisionRendererTest.php
tests/phpunit/includes/api/ApiErrorFormatterTest.php
tests/phpunit/includes/api/ApiMainTest.php
tests/phpunit/includes/api/ApiMessageTest.php
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/user/LocalIdLookupTest.php
tests/phpunit/includes/user/UserTest.php
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js

index 1021cb3..677b1c1 100644 (file)
@@ -55,6 +55,12 @@ production.
 === Action API changes in 1.33 ===
 * (T198913) Added 'ApiOptions' hook.
 * The JSON formatversion=2 is no longer experimental.
+* Internal API errors (those with code beginning "internal_api_error") will
+  include the exception class name in a data field named "errorclass".
+  * Class names are not guaranteed to remain stable, and in particular database
+    exceptions will now include the "Wikimedia\Rdbms\" prefix in the class name.
+  * The code including an exception class name is deprecated. In the future,
+    all internal errors will use code "internal_api_error".
 * …
 
 === Action API internal changes in 1.33 ===
@@ -68,6 +74,10 @@ production.
   Additionally, the  'APIGetDescription' and 'APIGetParamDescription' hooks have
   been removed, as their only use was to let extensions override values returned
   by getDescription() and getParamDescription(), respectively.
+* API error codes may only contain ASCII letters, numbers, underscore, and
+  hyphen. Methods such as ApiBase::dieWithError() and
+  ApiMessageTrait::setApiCode() will throw an InvalidArgumentException if
+  passed a bad code.
 * …
 
 === Languages updated in 1.33 ===
index 09c6215..d923db1 100644 (file)
@@ -42,7 +42,7 @@
                "wikimedia/html-formatter": "1.0.2",
                "wikimedia/ip-set": "1.2.0",
                "wikimedia/object-factory": "1.0.0",
-               "wikimedia/password-blacklist": "0.1.2",
+               "wikimedia/password-blacklist": "0.1.3",
                "wikimedia/php-session-serializer": "1.0.6",
                "wikimedia/purtle": "1.0.7",
                "wikimedia/relpath": "2.1.1",
index 6eee3c4..c8f56e9 100644 (file)
@@ -159,6 +159,28 @@ class RenderedRevision implements SlotRenderingProvider {
                return $this->options;
        }
 
+       /**
+        * Sets a ParserOutput to be returned by getRevisionParserOutput().
+        *
+        * @note For internal use by RevisionRenderer only! This method may be modified
+        * or removed without notice per the deprecation policy.
+        *
+        * @internal
+        *
+        * @param ParserOutput $output
+        */
+       public function setRevisionParserOutput( ParserOutput $output ) {
+               $this->revisionOutput = $output;
+
+               // If there is only one slot, we assume that the combined output is identical
+               // with the main slot's output. This is intended to prevent a redundant re-parse of
+               // the content in case getSlotParserOutput( SlotRecord::MAIN ) is called, for instance
+               // from ContentHandler::getSecondaryDataUpdates.
+               if ( $this->revision->getSlotRoles() === [ SlotRecord::MAIN ] ) {
+                       $this->slotsOutput[ SlotRecord::MAIN ] = $output;
+               }
+       }
+
        /**
         * @param array $hints Hints given as an associative array. Known keys:
         *      - 'generate-html' => bool: Whether the caller is interested in output HTML (as opposed
index e2e84b6..265ad13 100644 (file)
@@ -82,6 +82,11 @@ class RevisionRenderer {
         *      - 'audience' the audience to use for content access. Default is
         *        RevisionRecord::FOR_PUBLIC if $forUser is not set, RevisionRecord::FOR_THIS_USER
         *        if $forUser is set. Can be set to RevisionRecord::RAW to disable audience checks.
+        *      - 'known-revision-output' a combined ParserOutput for the revision, perhaps from
+        *        some cache. the caller is responsible for ensuring that the ParserOutput indeed
+        *        matched the $rev and $options. This mechanism is intended as a temporary stop-gap,
+        *        for the time until caches have been changed to store RenderedRevision states instead
+        *        of ParserOutput objects.
         *
         * @return RenderedRevision|null The rendered revision, or null if the audience checks fails.
         */
@@ -133,6 +138,10 @@ class RevisionRenderer {
 
                $renderedRevision->setSaveParseLogger( $this->saveParseLogger );
 
+               if ( isset( $hints['known-revision-output'] ) ) {
+                       $renderedRevision->setRevisionParserOutput( $hints['known-revision-output'] );
+               }
+
                return $renderedRevision;
        }
 
index b45aeba..d837a53 100644 (file)
@@ -738,17 +738,6 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                        $stashedEdit = ApiStashEdit::checkCache( $title, $mainContent, $legacyUser );
                }
 
-               if ( $stashedEdit ) {
-                       /** @var ParserOutput $output */
-                       $output = $stashedEdit->output;
-
-                       // TODO: this should happen when stashing the ParserOutput, not now!
-                       $output->setCacheTime( $stashedEdit->timestamp );
-
-                       // TODO: MCR: allow output for all slots to be stashed.
-                       $this->canonicalParserOutput = $output;
-               }
-
                $userPopts = ParserOptions::newFromUserAndLang( $user, $this->contLang );
                Hooks::run( 'ArticlePrepareTextForEdit', [ $wikiPage, $userPopts ] );
 
@@ -829,6 +818,27 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                } else {
                        $this->parentRevision = $parentRevision;
                }
+
+               $renderHints = [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ];
+
+               if ( $stashedEdit ) {
+                       /** @var ParserOutput $output */
+                       $output = $stashedEdit->output;
+
+                       // TODO: this should happen when stashing the ParserOutput, not now!
+                       $output->setCacheTime( $stashedEdit->timestamp );
+
+                       $renderHints['known-revision-output'] = $output;
+               }
+
+               // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
+               // NOTE: the revision is either new or current, so we can bypass audience checks.
+               $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
+                       $this->revision,
+                       null,
+                       null,
+                       $renderHints
+               );
        }
 
        /**
@@ -855,18 +865,7 @@ class DerivedPageDataUpdater implements IDBAccessObject {
         * @return RenderedRevision
         */
        public function getRenderedRevision() {
-               if ( !$this->renderedRevision ) {
-                       $this->assertPrepared( __METHOD__ );
-
-                       // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
-                       // NOTE: the revision is either new or current, so we can bypass audience checks.
-                       $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
-                               $this->revision,
-                               null,
-                               null,
-                               [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ]
-                       );
-               }
+               $this->assertPrepared( __METHOD__ );
 
                return $this->renderedRevision;
        }
@@ -1186,6 +1185,19 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                // Prune any output that depends on the revision ID.
                if ( $this->renderedRevision ) {
                        $this->renderedRevision->updateRevision( $revision );
+               } else {
+
+                       // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
+                       // NOTE: the revision is either new or current, so we can bypass audience checks.
+                       $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
+                               $this->revision,
+                               null,
+                               null,
+                               [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ]
+                       );
+
+                       // XXX: Since we presumably are dealing with the current revision,
+                       // we could try to get the ParserOutput from the parser cache.
                }
 
                // TODO: optionally get ParserOutput from the ParserCache here.
index 847afd8..a37ecc2 100644 (file)
@@ -58,6 +58,26 @@ class ApiErrorFormatter {
                $this->format = $format;
        }
 
+       /**
+        * Test whether a code is a valid API error code
+        *
+        * A valid code contains only ASCII letters, numbers, underscore, and
+        * hyphen and is not the empty string.
+        *
+        * For backwards compatibility, any code beginning 'internal_api_error_' is
+        * also allowed.
+        *
+        * @param string $code
+        * @return bool
+        */
+       public static function isValidApiCode( $code ) {
+               return is_string( $code ) && (
+                       preg_match( '/^[a-zA-Z0-9_-]+$/', $code ) ||
+                       // TODO: Deprecate this
+                       preg_match( '/^internal_api_error_[^\0\r\n]+$/', $code )
+               );
+       }
+
        /**
         * Return a formatter like this one but with a different format
         *
@@ -191,6 +211,7 @@ class ApiErrorFormatter {
                                if ( !isset( $options['code'] ) ) {
                                        $class = preg_replace( '#^Wikimedia\\\Rdbms\\\#', '', get_class( $exception ) );
                                        $options['code'] = 'internal_api_error_' . $class;
+                                       $options['data']['errorclass'] = get_class( $exception );
                                }
                        }
                        $params = [ wfEscapeWikiText( $exception->getMessage() ) ];
index 22232dd..bc76f8f 100644 (file)
@@ -834,7 +834,11 @@ class ApiMain extends ApiBase {
                foreach ( $requestedHeaders as $rHeader ) {
                        $rHeader = strtolower( trim( $rHeader ) );
                        if ( !isset( $allowedAuthorHeaders[$rHeader] ) ) {
-                               wfDebugLog( 'api', 'CORS preflight failed on requested header: ' . $rHeader );
+                               LoggerFactory::getInstance( 'api-warning' )->warning(
+                                       'CORS preflight failed on requested header: {header}', [
+                                               'header' => $rHeader
+                                       ]
+                               );
                                return false;
                        }
                }
@@ -1025,8 +1029,10 @@ class ApiMain extends ApiBase {
                } else {
                        // Something is seriously wrong
                        $config = $this->getConfig();
+                       // TODO: Avoid embedding arbitrary class names in the error code.
                        $class = preg_replace( '#^Wikimedia\\\Rdbms\\\#', '', get_class( $e ) );
                        $code = 'internal_api_error_' . $class;
+                       $data = [ 'errorclass' => get_class( $e ) ];
                        if ( $config->get( 'ShowExceptionDetails' ) ) {
                                if ( $e instanceof ILocalizedException ) {
                                        $msg = $e->getMessageObject();
@@ -1040,7 +1046,7 @@ class ApiMain extends ApiBase {
                                $params = [ 'apierror-exceptioncaughttype', WebRequest::getRequestId(), get_class( $e ) ];
                        }
 
-                       $messages[] = ApiMessage::create( $params, $code );
+                       $messages[] = ApiMessage::create( $params, $code, $data );
                }
                return $messages;
        }
@@ -1077,7 +1083,15 @@ class ApiMain extends ApiBase {
                // Add errors from the exception
                $modulePath = $e instanceof ApiUsageException ? $e->getModulePath() : null;
                foreach ( $this->errorMessagesFromException( $e, 'error' ) as $msg ) {
-                       $errorCodes[$msg->getApiCode()] = true;
+                       if ( ApiErrorFormatter::isValidApiCode( $msg->getApiCode() ) ) {
+                               $errorCodes[$msg->getApiCode()] = true;
+                       } else {
+                               LoggerFactory::getInstance( 'api-warning' )->error( 'Invalid API error code "{code}"', [
+                                       'code' => $msg->getApiCode(),
+                                       'exception' => $e,
+                               ] );
+                               $errorCodes['<invalid-code>'] = true;
+                       }
                        $formatter->addError( $modulePath, $msg );
                }
                foreach ( $this->errorMessagesFromException( $e, 'warning' ) as $msg ) {
@@ -1464,9 +1478,14 @@ class ApiMain extends ApiBase {
                if ( $numLagged >= ceil( $replicaCount / 2 ) ) {
                        $laggedServers = implode( ', ', $laggedServers );
                        wfDebugLog(
-                               'api-readonly',
+                               'api-readonly', // Deprecate this channel in favor of api-warning?
                                "Api request failed as read only because the following DBs are lagged: $laggedServers"
                        );
+                       LoggerFactory::getInstance( 'api-warning' )->warning(
+                               "Api request failed as read only because the following DBs are lagged: {laggeddbs}", [
+                                       'laggeddbs' => $laggedServers,
+                               ]
+                       );
 
                        $this->dieWithError(
                                'readonly_lag',
index 18b6bc4..6894d28 100644 (file)
@@ -105,12 +105,15 @@ trait ApiMessageTrait {
                        } else {
                                $this->apiCode = $key;
                        }
+
+                       // Ensure the code is actually valid
+                       $this->apiCode = preg_replace( '/[^a-zA-Z0-9_-]/', '_', $this->apiCode );
                }
                return $this->apiCode;
        }
 
        public function setApiCode( $code, array $data = null ) {
-               if ( $code !== null && !( is_string( $code ) && $code !== '' ) ) {
+               if ( $code !== null && !ApiErrorFormatter::isValidApiCode( $code ) ) {
                        throw new InvalidArgumentException( "Invalid code \"$code\"" );
                }
 
index 3cb55e4..ba04193 100644 (file)
@@ -109,9 +109,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                }
 
                if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds( [ 'tag_summary' => [ 'LEFT JOIN', 'log_id=ts_log_id' ] ] );
-                       $this->addFields( 'ts_tags' );
+                       $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'logging' ) ] );
                }
 
                if ( !is_null( $params['tag'] ) ) {
index 0e36009..c6e8e1f 100644 (file)
@@ -788,7 +788,7 @@ class ChangeTags {
        public static function modifyDisplayQuery( &$tables, &$fields, &$conds,
                &$join_conds, &$options, $filter_tag = ''
        ) {
-               global $wgUseTagFilter, $wgChangeTagsSchemaMigrationStage;
+               global $wgChangeTagsSchemaMigrationStage, $wgUseTagFilter;
 
                // Normalize to arrays
                $tables = (array)$tables;
@@ -796,6 +796,8 @@ class ChangeTags {
                $conds = (array)$conds;
                $options = (array)$options;
 
+               $fields['ts_tags'] = self::makeTagSummarySubquery( $tables );
+
                // Figure out which ID field to use
                if ( in_array( 'recentchanges', $tables ) ) {
                        $join_cond = 'ct_rc_id=rc_id';
@@ -809,20 +811,6 @@ class ChangeTags {
                        throw new MWException( 'Unable to determine appropriate JOIN condition for tagging.' );
                }
 
-               $tagTables[] = 'change_tag';
-               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                       $tagTables[] = 'change_tag_def';
-                       $join_cond_ts_tags = [ 'change_tag_def' => [ 'INNER JOIN', 'ct_tag_id=ctd_id' ] ];
-                       $field = 'ctd_name';
-               } else {
-                       $field = 'ct_tag';
-                       $join_cond_ts_tags = [];
-               }
-
-               $fields['ts_tags'] = wfGetDB( DB_REPLICA )->buildGroupConcatField(
-                       ',', $tagTables, $field, $join_cond, $join_cond_ts_tags
-               );
-
                if ( $wgUseTagFilter && $filter_tag ) {
                        // Somebody wants to filter on a tag.
                        // Add an INNER JOIN on change_tag
@@ -858,6 +846,48 @@ class ChangeTags {
                }
        }
 
+       /**
+        * Make the tag summary subquery based on the given tables and return it.
+        *
+        * @param string|array $tables Table names, see Database::select
+        *
+        * @return string tag summary subqeury
+        * @throws MWException When unable to determine appropriate JOIN condition for tagging
+        */
+       public static function makeTagSummarySubquery( $tables ) {
+               global $wgChangeTagsSchemaMigrationStage;
+
+               // Normalize to arrays
+               $tables = (array)$tables;
+
+               // Figure out which ID field to use
+               if ( in_array( 'recentchanges', $tables ) ) {
+                       $join_cond = 'ct_rc_id=rc_id';
+               } elseif ( in_array( 'logging', $tables ) ) {
+                       $join_cond = 'ct_log_id=log_id';
+               } elseif ( in_array( 'revision', $tables ) ) {
+                       $join_cond = 'ct_rev_id=rev_id';
+               } elseif ( in_array( 'archive', $tables ) ) {
+                       $join_cond = 'ct_rev_id=ar_rev_id';
+               } else {
+                       throw new MWException( 'Unable to determine appropriate JOIN condition for tagging.' );
+               }
+
+               $tagTables[] = 'change_tag';
+               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
+                       $tagTables[] = 'change_tag_def';
+                       $join_cond_ts_tags = [ 'change_tag_def' => [ 'INNER JOIN', 'ct_tag_id=ctd_id' ] ];
+                       $field = 'ctd_name';
+               } else {
+                       $field = 'ct_tag';
+                       $join_cond_ts_tags = [];
+               }
+
+               return wfGetDB( DB_REPLICA )->buildGroupConcatField(
+                       ',', $tagTables, $field, $join_cond, $join_cond_ts_tags
+               );
+       }
+
        /**
         * Build a text box to select a change tag
         *
index a7021b1..517d807 100644 (file)
@@ -25,6 +25,7 @@
  * @author Daniel Kinzler
  */
 
+use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -41,6 +42,11 @@ class WikitextContent extends TextContent {
         */
        private $hadSignature = false;
 
+       /**
+        * @var array|null Stack trace of the previous parse
+        */
+       private $previousParseStackTrace = null;
+
        public function __construct( $text ) {
                parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
        }
@@ -337,6 +343,28 @@ class WikitextContent extends TextContent {
        ) {
                global $wgParser;
 
+               $stackTrace = ( new RuntimeException() )->getTraceAsString();
+               if ( $this->previousParseStackTrace ) {
+                       // NOTE: there may be legitimate changes to re-parse the same WikiText content,
+                       // e.g. if predicted revision ID for the REVISIONID magic word mismatched.
+                       // But that should be rare.
+                       $logger = LoggerFactory::getInstance( 'DuplicateParse' );
+                       $logger->debug(
+                               __METHOD__ . ': Possibly redundant parse!',
+                               [
+                                       'title' => $title->getPrefixedDBkey(),
+                                       'rev' => $revId,
+                                       'options-hash' => $options->optionsHash(
+                                               ParserOptions::allCacheVaryingOptions(),
+                                               $title
+                                       ),
+                                       'trace' => $stackTrace,
+                                       'previous-trace' => $this->previousParseStackTrace,
+                               ]
+                       );
+               }
+               $this->previousParseStackTrace = $stackTrace;
+
                list( $redir, $text ) = $this->getRedirectTargetAndText();
                $output = $wgParser->parse( $text, $title, $options, true, true, $revId );
 
index 5f09555..d427724 100644 (file)
@@ -137,7 +137,7 @@ class CloneDatabase {
                global $wgDBprefix;
 
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-               $lbFactory->setDomainPrefix( $prefix );
+               $lbFactory->setLocalDomainPrefix( $prefix );
                $wgDBprefix = $prefix;
        }
 }
index 24f4757..e9b903c 100644 (file)
        "config-sqlite-cant-create-db": "Kunde inte skapa databasfilen <code>$1</code>.",
        "config-sqlite-fts3-downgrade": "PHP saknar stöd för FTS3, nedgraderar tabeller",
        "config-can-upgrade": "Det finns MediaWiki-tabeller i den här databasen.\nFör att uppgradera dem till MediaWiki $1, klicka på '''Fortsätt'''.",
+       "config-upgrade-error": "Ett fel uppstod när MediaWiki-tabellerna i din databas uppdaterades.\n\nFör mer information, se loggen ovan. Klicka på <strong>Fortsätt</strong> för att försöka igen.",
        "config-upgrade-done": "Uppgraderingen slutfördes.\n\nDu kan nu [$1 börja använda din wiki].\n\nOm du vill förnya din <code>LocalSettings.php</code>-fil, klicka på knappen nedan.\nDetta '''rekommenderas inte''' om du har problem med din wiki.",
        "config-upgrade-done-no-regenerate": "Uppgraderingen slutfördes.\n\nDu kan nu [$1 börja använda din wiki].",
        "config-regenerate": "Återskapa LocalSettings.php →",
index 532d818..2795883 100644 (file)
@@ -1112,11 +1112,13 @@ interface IDatabase {
        /**
         * Change the current database
         *
+        * This should not be called outside LoadBalancer for connections managed by a LoadBalancer
+        *
         * @param string $db
         * @return bool True unless an exception was thrown
         * @throws DBConnectionError If databasesAreIndependent() is true and an error occurs
         * @throws DBError
-        * @deprecated Since 1.32
+        * @deprecated Since 1.32 Use selectDomain() instead
         */
        public function selectDB( $db );
 
@@ -1125,6 +1127,8 @@ interface IDatabase {
         *
         * This will throw an error for some database types if the database unspecified
         *
+        * This should not be called outside LoadBalancer for connections managed by a LoadBalancer
+        *
         * @param string|DatabaseDomain $domain
         * @since 1.32
         * @throws DBConnectionError
index 57f60ca..7987052 100644 (file)
@@ -83,6 +83,14 @@ interface ILBFactory {
         */
        public function resolveDomainID( $domain );
 
+       /**
+        * Close all connection and redefine the local domain for testing or schema creation
+        *
+        * @param DatabaseDomain|string $domain
+        * @since 1.33
+        */
+       public function redefineLocalDomain( $domain );
+
        /**
         * Create a new load balancer object. The resulting object will be untracked,
         * not chronology-protected, and the caller is responsible for cleaning it up.
@@ -322,8 +330,9 @@ interface ILBFactory {
         * Set a new table prefix for the existing local domain ID for testing
         *
         * @param string $prefix
+        * @since 1.33
         */
-       public function setDomainPrefix( $prefix );
+       public function setLocalDomainPrefix( $prefix );
 
        /**
         * Close all open database connections on all open load balancers.
index d213dc9..9a6c224 100644 (file)
@@ -618,7 +618,15 @@ abstract class LBFactory implements ILBFactory {
                $this->indexAliases = $aliases;
        }
 
+       /**
+        * @param string $prefix
+        * @deprecated Since 1.33
+        */
        public function setDomainPrefix( $prefix ) {
+               $this->setLocalDomainPrefix( $prefix );
+       }
+
+       public function setLocalDomainPrefix( $prefix ) {
                $this->localDomain = new DatabaseDomain(
                        $this->localDomain->getDatabase(),
                        null,
@@ -626,7 +634,17 @@ abstract class LBFactory implements ILBFactory {
                );
 
                $this->forEachLB( function ( ILoadBalancer $lb ) use ( $prefix ) {
-                       $lb->setDomainPrefix( $prefix );
+                       $lb->setLocalDomainPrefix( $prefix );
+               } );
+       }
+
+       public function redefineLocalDomain( $domain ) {
+               $this->closeAll();
+
+               $this->localDomain = DatabaseDomain::newFromId( $domain );
+
+               $this->forEachLB( function ( ILoadBalancer $lb ) {
+                       $lb->redefineLocalDomain( $this->localDomain );
                } );
        }
 
index 78815f2..e1a3162 100644 (file)
@@ -136,6 +136,14 @@ interface ILoadBalancer {
         */
        public function resolveDomainID( $domain );
 
+       /**
+        * Close all connection and redefine the local domain for testing or schema creation
+        *
+        * @param DatabaseDomain|string $domain
+        * @since 1.33
+        */
+       public function redefineLocalDomain( $domain );
+
        /**
         * Get the index of the reader connection, which may be a replica DB
         *
@@ -644,8 +652,9 @@ interface ILoadBalancer {
         * Set a new table prefix for the existing local domain ID for testing
         *
         * @param string $prefix
+        * @since 1.33
         */
-       public function setDomainPrefix( $prefix );
+       public function setLocalDomainPrefix( $prefix );
 
        /**
         * Make certain table names use their own database, schema, and table prefix
index 537301c..bc51726 100644 (file)
@@ -1918,7 +1918,15 @@ class LoadBalancer implements ILoadBalancer {
                $this->indexAliases = $aliases;
        }
 
+       /**
+        * @param string $prefix
+        * @deprecated Since 1.33
+        */
        public function setDomainPrefix( $prefix ) {
+               $this->setLocalDomainPrefix( $prefix );
+       }
+
+       public function setLocalDomainPrefix( $prefix ) {
                // Find connections to explicit foreign domains still marked as in-use...
                $domainsInUse = [];
                $this->forEachOpenConnection( function ( IDatabase $conn ) use ( &$domainsInUse ) {
@@ -1950,6 +1958,12 @@ class LoadBalancer implements ILoadBalancer {
                } );
        }
 
+       public function redefineLocalDomain( $domain ) {
+               $this->closeAll();
+
+               $this->setLocalDomain( DatabaseDomain::newFromId( $domain ) );
+       }
+
        /**
         * @param DatabaseDomain $domain
         */
index 11825fa..81e23ad 100644 (file)
@@ -5066,9 +5066,10 @@ class Parser {
                        $ig->setShowFilename( false );
                }
                if ( isset( $params['caption'] ) ) {
-                       $caption = $params['caption'];
-                       $caption = htmlspecialchars( $caption );
-                       $caption = $this->replaceInternalLinks( $caption );
+                       // NOTE: We aren't passing a frame here or below.  Frame info
+                       // is currently opaque to Parsoid, which acts on OT_PREPROCESS.
+                       // See T107332#4030581
+                       $caption = $this->recursiveTagParse( $params['caption'] );
                        $ig->setCaptionHtml( $caption );
                }
                if ( isset( $params['perrow'] ) ) {
@@ -5524,6 +5525,40 @@ class Parser {
                # that are later expanded to html- so expand them now and
                # remove the tags
                $tooltip = $this->mStripState->unstripBoth( $tooltip );
+               # Compatibility hack!  In HTML certain entity references not terminated
+               # by a semicolon are decoded (but not if we're in an attribute; that's
+               # how link URLs get away without properly escaping & in queries).
+               # But wikitext has always required semicolon-termination of entities,
+               # so encode & where needed to avoid decode of semicolon-less entities.
+               # See T209236 and
+               # https://www.w3.org/TR/html5/syntax.html#named-character-references
+               # T210437 discusses moving this workaround to Sanitizer::stripAllTags.
+               $tooltip = preg_replace( "/
+                       &                       # 1. entity prefix
+                       (?=                     # 2. followed by:
+                       (?:                     #  a. one of the legacy semicolon-less named entities
+                               A(?:Elig|MP|acute|circ|grave|ring|tilde|uml)|
+                               C(?:OPY|cedil)|E(?:TH|acute|circ|grave|uml)|
+                               GT|I(?:acute|circ|grave|uml)|LT|Ntilde|
+                               O(?:acute|circ|grave|slash|tilde|uml)|QUOT|REG|THORN|
+                               U(?:acute|circ|grave|uml)|Yacute|
+                               a(?:acute|c(?:irc|ute)|elig|grave|mp|ring|tilde|uml)|brvbar|
+                               c(?:cedil|edil|urren)|cent(?!erdot;)|copy(?!sr;)|deg|
+                               divide(?!ontimes;)|e(?:acute|circ|grave|th|uml)|
+                               frac(?:1(?:2|4)|34)|
+                               gt(?!c(?:c|ir)|dot|lPar|quest|r(?:a(?:pprox|rr)|dot|eq(?:less|qless)|less|sim);)|
+                               i(?:acute|circ|excl|grave|quest|uml)|laquo|
+                               lt(?!c(?:c|ir)|dot|hree|imes|larr|quest|r(?:Par|i(?:e|f|));)|
+                               m(?:acr|i(?:cro|ddot))|n(?:bsp|tilde)|
+                               not(?!in(?:E|dot|v(?:a|b|c)|)|ni(?:v(?:a|b|c)|);)|
+                               o(?:acute|circ|grave|rd(?:f|m)|slash|tilde|uml)|
+                               p(?:lusmn|ound)|para(?!llel;)|quot|r(?:aquo|eg)|
+                               s(?:ect|hy|up(?:1|2|3)|zlig)|thorn|times(?!b(?:ar|)|d;)|
+                               u(?:acute|circ|grave|ml|uml)|y(?:acute|en|uml)
+                       )
+                       (?:[^;]|$))     #  b. and not followed by a semicolon
+                       # S = study, for efficiency
+                       /Sx", '&amp;', $tooltip );
                $tooltip = Sanitizer::stripAllTags( $tooltip );
 
                return $tooltip;
index 84f8083..f8c3bc2 100644 (file)
@@ -349,18 +349,18 @@ class Sanitizer {
 
        /**
         * Regular expression to match HTML/XML attribute pairs within a tag.
-        * Allows some... latitude. Based on,
-        * https://www.w3.org/TR/html5/syntax.html#before-attribute-value-state
-        * Used in Sanitizer::fixTagAttributes and Sanitizer::decodeTagAttributes
+        * Based on https://www.w3.org/TR/html5/syntax.html#before-attribute-name-state
+        * Used in Sanitizer::decodeTagAttributes
         * @return string
         */
        static function getAttribsRegex() {
                if ( self::$attribsRegex === null ) {
-                       $attribFirst = "[:_\p{L}\p{N}]";
-                       $attrib = "[:_\.\-\p{L}\p{N}]";
-                       $space = '[\x09\x0a\x0c\x0d\x20]';
+                       $spaceChars = '\x09\x0a\x0c\x0d\x20';
+                       $space = "[{$spaceChars}]";
+                       $attrib = "[^{$spaceChars}\/>=]";
+                       $attribFirst = "(?:{$attrib}|=)";
                        self::$attribsRegex =
-                               "/(?:^|$space)({$attribFirst}{$attrib}*)
+                               "/({$attribFirst}{$attrib}*)
                                        ($space*=$space*
                                        (?:
                                                # The attribute value: quoted or alone
@@ -368,11 +368,29 @@ class Sanitizer {
                                                | '([^']*)(?:'|\$)
                                                | (((?!$space|>).)*)
                                        )
-                               )?(?=$space|\$)/sxu";
+                               )?/sxu";
                }
                return self::$attribsRegex;
        }
 
+       /**
+        * Lazy-initialised attribute name regex, see getAttribNameRegex()
+        */
+       private static $attribNameRegex;
+
+       /**
+        * Used in Sanitizer::decodeTagAttributes to filter attributes.
+        * @return string
+        */
+       static function getAttribNameRegex() {
+               if ( self::$attribNameRegex === null ) {
+                       $attribFirst = "[:_\p{L}\p{N}]";
+                       $attrib = "[:_\.\-\p{L}\p{N}]";
+                       self::$attribNameRegex = "/^({$attribFirst}{$attrib}*)$/sxu";
+               }
+               return self::$attribNameRegex;
+       }
+
        /**
         * Return the various lists of recognized tags
         * @param array $extratags For any extra tags to include
@@ -1434,18 +1452,24 @@ class Sanitizer {
                        return [];
                }
 
-               $attribs = [];
                $pairs = [];
                if ( !preg_match_all(
                        self::getAttribsRegex(),
                        $text,
                        $pairs,
                        PREG_SET_ORDER ) ) {
-                       return $attribs;
+                       return [];
                }
 
+               $attribs = [];
                foreach ( $pairs as $set ) {
                        $attribute = strtolower( $set[1] );
+
+                       // Filter attribute names with unacceptable characters
+                       if ( !preg_match( self::getAttribNameRegex(), $attribute ) ) {
+                               continue;
+                       }
+
                        $value = self::getTagAttributeCallback( $set );
 
                        // Normalize whitespace
index bf4d9af..81abf1c 100644 (file)
@@ -227,8 +227,7 @@ class PreferencesFormOOUI extends OOUIHTMLForm {
         * @return string
         */
        function getLegend( $key ) {
-               $aliasKey = ( $key === 'optoutwatchlist' || $key === 'optoutrc' ) ? 'opt-out' : $key;
-               $legend = parent::getLegend( $aliasKey );
+               $legend = parent::getLegend( $key );
                Hooks::run( 'PreferencesGetLegend', [ $this, $key, &$legend ] );
                return $legend;
        }
index bc24d26..fbf179d 100644 (file)
@@ -142,7 +142,8 @@ class UsersPager extends AlphabeticPager {
                                'user_id' => $this->creationSort ? 'user_id' : 'MAX(user_id)',
                                'edits' => 'MAX(user_editcount)',
                                'creation' => 'MIN(user_registration)',
-                               'ipb_deleted' => 'MAX(ipb_deleted)' // block/hide status
+                               'ipb_deleted' => 'MAX(ipb_deleted)', // block/hide status
+                               'ipb_sitewide' => 'MAX(ipb_sitewide)'
                        ],
                        'options' => $options,
                        'join_conds' => [
@@ -214,7 +215,8 @@ class UsersPager extends AlphabeticPager {
                        $created = $this->msg( 'usercreated', $d, $t, $row->user_name )->escaped();
                        $created = ' ' . $this->msg( 'parentheses' )->rawParams( $created )->escaped();
                }
-               $blocked = !is_null( $row->ipb_deleted ) ?
+
+               $blocked = !is_null( $row->ipb_deleted ) && $row->ipb_sitewide === '1' ?
                        ' ' . $this->msg( 'listusers-blocked', $userName )->escaped() :
                        '';
 
index 5f772a4..40511cf 100644 (file)
@@ -2304,16 +2304,18 @@ class User implements IDBAccessObject, UserIdentity {
                if ( !$blocked ) {
                        $block = $this->getBlock( $fromReplica );
                        if ( $block ) {
-                               // A sitewide block covers everything except maybe the user's
-                               // talk page. A partial block covering the user's talk page
-                               // overrides the editownusertalk flag, however.
-                               // TODO: Do we really want a partial block on the user talk
-                               //  namespace to ignore editownusertalk?
-                               $blocked = $block->isSitewide();
-                               if ( $blocked && $title->equals( $this->getTalkPage() ) ) {
-                                       $blocked = $block->prevents( 'editownusertalk' );
-                               }
-                               if ( !$block->isSitewide() ) {
+                               // Special handling for a user's own talk page. The block is not aware
+                               // of the user, so this must be done here.
+                               if ( $title->equals( $this->getTalkPage() ) ) {
+                                       // If the block is sitewide, then whatever is set is what is honored.
+                                       if ( $block->isSitewide() ) {
+                                               $blocked = $block->prevents( 'editownusertalk' );
+                                       } else {
+                                               // If the block is partial, then only a true value is honored,
+                                               // otherwise fallback to the partial block settings.
+                                               $blocked = $block->prevents( 'editownusertalk' ) ?: $block->appliesToTitle( $title );
+                                       }
+                               } else {
                                        $blocked = $block->appliesToTitle( $title );
                                }
                        }
index 8be2d6a..4a330ad 100644 (file)
@@ -153,25 +153,27 @@ class ConverterRule {
                        $to = trim( $v[1] );
                        $v = trim( $v[0] );
                        $u = explode( '=>', $v, 2 );
+                       $vv = $this->mConverter->validateVariant( $v );
                        // if $to is empty (which is also used as $from in bidtable),
                        // strtr() could return a wrong result.
-                       if ( count( $u ) == 1 && $to !== '' && in_array( $v, $variants ) ) {
-                               $bidtable[$v] = $to;
+                       if ( count( $u ) == 1 && $to !== '' && $vv ) {
+                               $bidtable[$vv] = $to;
                        } elseif ( count( $u ) == 2 ) {
                                $from = trim( $u[0] );
                                $v = trim( $u[1] );
+                               $vv = $this->mConverter->validateVariant( $v );
                                // if $from is empty, strtr() could return a wrong result.
-                               if ( array_key_exists( $v, $unidtable )
-                                       && !is_array( $unidtable[$v] )
+                               if ( array_key_exists( $vv, $unidtable )
+                                       && !is_array( $unidtable[$vv] )
                                        && $from !== ''
-                                       && in_array( $v, $variants ) ) {
-                                       $unidtable[$v] = [ $from => $to ];
-                               } elseif ( $from !== '' && in_array( $v, $variants ) ) {
-                                       $unidtable[$v][$from] = $to;
+                                       && $vv ) {
+                                       $unidtable[$vv] = [ $from => $to ];
+                               } elseif ( $from !== '' && $vv ) {
+                                       $unidtable[$vv][$from] = $to;
                                }
                        }
                        // syntax error, pass
-                       if ( !isset( $this->mConverter->mVariantNames[$v] ) ) {
+                       if ( !isset( $this->mConverter->mVariantNames[$vv] ) ) {
                                $bidtable = [];
                                $unidtable = [];
                                break;
index 3c8d300..8fdf4f5 100644 (file)
@@ -1176,8 +1176,21 @@ class LanguageConverter {
                        //    [1] => 'zh-hant:<span style="font-size:120%;">yyy</span>'
                        //    [2] => ''
                        //  ]
-                       $pat = '/;\s*(?=';
+                       $expandedVariants = [];
                        foreach ( $this->mVariants as $variant ) {
+                               $expandedVariants[ $variant ] = 1;
+                               // Accept standard BCP 47 names for variants as well.
+                               $expandedVariants[ LanguageCode::bcp47( $variant ) ] = 1;
+                       }
+                       // Accept old deprecated names for variants
+                       foreach ( LanguageCode::getDeprecatedCodeMapping() as $old => $new ) {
+                               if ( isset( $expandedVariants[ $new ] ) ) {
+                                       $expandedVariants[ $old ] = 1;
+                               }
+                       }
+
+                       $pat = '/;\s*(?=';
+                       foreach ( $expandedVariants as $variant => $ignore ) {
                                // zh-hans:xxx;zh-hant:yyy
                                $pat .= $variant . '\s*:|';
                                // xxx=>zh-hans:yyy; xxx=>zh-hant:zzz
index 717450f..ef515eb 100644 (file)
        "ns-specialprotected": "Laman kusuih h'an jeuet geupeusaneut",
        "titleprotected": "Nan nyoe ka geupeulindông nibak neuandam lé [[User:$1|$1]].\nDalèhjih nakeuh <em>$2</em>.",
        "invalidtitle-knownnamespace": "Nan nyang hana sah ngön ruweueng nan \"$2\" ngön \"$3\"",
-       "exception-nologin": "Goh lom tamong log",
+       "exception-nologin": "Goh lom neutamöng",
        "exception-nologin-text": "Droëneuh suwah [[Special:Userlogin|neutamöng]] mangat jeuët neupeuhah laman nyoë",
        "virus-unknownscanner": "Antivirus hana geuturi:",
-       "logouttext": "'''Droeneuh ka neutubiet log.'''\n\nBeuneuteupue meunyoe na padum-padum laman nyang deuh lagèe na neutamöng log, sampoe ka lheuh neupeugléh ''cache''.",
+       "logouttext": "<strong>Droeneuh ka neuteubiet.</strong>\n\nBeu neutupeue meunyo na padum-padum laman nyang leumah lagèe na neutamöng, sampoe ka neupeugléh cache browser.",
        "cannotlogoutnow-title": "H'an jeuet teubiet jinoe",
        "welcomeuser": "Seulamat trôk teuka, $1 !",
        "welcomecreation-msg": "Akun-neuh ka geupeugöt. \nDroeneuh jeuet neugantoe {{SITENAME}} [[Special:Preferences|peuatô]] meunyö neumeuh'eut.",
        "userlogin-joinproject": "Neugabông ngön {{SITENAME}}",
        "createaccount": "Peudapeuta nan barô",
        "userlogin-resetpassword-link": "Tuwö lageuem tamöng?",
-       "userlogin-helplink2": "Beunantu tamöng log",
+       "userlogin-helplink2": "Beunantu tamöng",
        "userlogin-loggedin": "Droëneuh ka neutamöng seubagoë $1. Neungui blangko di yup keu neutamöng seubagoë ureuëng ngui la’én",
        "userlogin-createanother": "Peugöt akun laén",
        "createacct-emailrequired": "Alamat surat-e",
        "createaccounterror": "H'an jeuet peugöt akun: $1",
        "nocookiesnew": "Akun ureueng ngui nyoe ka geupeugöt, tapi droeneuh goh lom neutamöng.\n{{SITENAME}} jingui kuki keu jipeutamöng ureueng ngui.\nKuki droeneuh hana geupeuudép.\nNeupeuudép kuki dilèe, lheueh nyan neutamöng ngön nan ureueng ngui ngön lageuem tamöng barô droeneuh.",
        "noname": "Nan ureuëng ngui nyang Droënueh peutamöng hana sah.",
-       "loginsuccesstitle": "Meuhasé tamöng log",
+       "loginsuccesstitle": "Meuhasé neutamöng",
        "loginsuccess": "'''Droëneuh  jinoë ka neutamöng di {{SITENAME}} sibagoë \"$1\".'''",
        "nosuchuser": "Hana ureuëng ngui ngön nan \"$1\".\nHaraih rayek ngön haraih ubeut na peungarôh.\nNeuparéksa ijaan-neuh, atawa [[Special:CreateAccount|neupeugöt akun]].",
        "nosuchusershort": "Hana ureuëng ngui ngön nan \"$1\".\nPréksa keulayi neu’ija Droëneuh.",
        "revdelete-hide-comment": "Mohtasa neuandam",
        "revdelete-radio-same": "(bèk neugantoe)",
        "revdelete-radio-set": "Teusom",
-       "revdelete-radio-unset": "Deuih",
+       "revdelete-radio-unset": "Leumah",
        "revdelete-log": "Alasan:",
        "revdel-restore": "Gantoë neuleumah",
        "pagehist": "Riwayat laman",
index 4df3cfd..4d6a96b 100644 (file)
        "passwordtooshort": "يجب أن تتكون كلمة السر على الأقل من {{PLURAL:$1|حرف واحد|حرفين|$1 حروف|$1 حرفا|$1 حرف}}.",
        "passwordtoolong": "كلمات السر لا يجب أن تكون أطول من  {{PLURAL:$1|1 حرف|$1 حروف}}.",
        "passwordtoopopular": "لا يمكن استخدام كلمات المرور المختارة بشكل عام; يُرجَى اختيار كلمة مرور يصعب تخمينها.",
+       "passwordinlargeblacklist": "كلمة المرور التي تم إدخالها موجودة في قائمة كلمات المرور شائعة الاستخدام; الرجاء اختيار كلمة مرور فريدة.",
        "password-name-match": "يجب أن تكون كلمة المرور مختلفة عن اسم المستخدم.",
        "password-login-forbidden": "تم منع استخدام اسم المستخدم هذا وكلمة السر.",
        "mailmypassword": "أعد تعيين كلمة السر",
        "botpasswords-label-needsreset": "(تحتاج كلمة المرور إلى إعادة الضبط)",
        "botpasswords-label-appid": "اسم البوت:",
        "botpasswords-label-create": "أنشأ",
-       "botpasswords-label-update": "حدث",
+       "botpasswords-label-update": "تحدÙ\8aث",
        "botpasswords-label-cancel": "ألغ",
        "botpasswords-label-delete": "احذف",
        "botpasswords-label-resetpassword": "أعد ضبط كلمة السر",
        "prefs-editor": "محرر",
        "prefs-preview": "عرض مسبق",
        "prefs-advancedrc": "خيارات متقدمة",
-       "prefs-opt-out": "إلغاء الاشتراك في التحسينات",
        "prefs-advancedrendering": "خيارات متقدمة",
        "prefs-advancedsearchoptions": "خيارات متقدمة",
        "prefs-advancedwatchlist": "خيارات متقدمة",
        "tags-create-already-exists": "الوسم \"$1\" موجود بالفعل.",
        "tags-create-warnings-above": "{{PLURAL:$2|التحذير التالي حدث|التحذيرات التالية حدثت}} عند محاولة إنشاء الوسم \"$1\":",
        "tags-create-warnings-below": "هل تود متابعة إنشاء الوسم؟",
-       "tags-delete-title": "احذÙ\81 Ø§Ù\84Ù\88سÙ\85",
+       "tags-delete-title": "حذف الوسم",
        "tags-delete-explanation-initial": "أنت على وشك حذف الوسم \"$1\" من قاعدة البيانات.",
        "tags-delete-explanation-in-use": "ستتم إزالته من {{PLURAL:$2|$2 مراجعة او مدخلة سجل|كل $2 مراجعات و/أو مدخلات سجل}} الذي هو مطبق عليهم حاليا.",
        "tags-delete-explanation-warning": "هذا الفعل <strong>غير رجعي</strong> و <strong>لا يمكن التراجع عنه</strong>، ولا حتى بواسطة إداريي قاعدة البيانات. كن متاكدا من أن هذا هو الوسم الذي تريد حذفه.",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "لا يمكن أن تتطابق كلمة المرور مع كلمات المرور المدرجة على القائمة السوداء تحديدا",
        "passwordpolicies-policy-maximalpasswordlength": "يجب أن يكون طول كلمة المرور أقل من $1 {{PLURAL:$1|حرف|أحرف}}",
        "passwordpolicies-policy-passwordcannotbepopular": "لا يمكن أن تكون كلمة المرور {{PLURAL:$1|كلمة المرور الشائعة|في قائمة كلمات المرور الشائعة الـ$1}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "لا يمكن أن تكون كلمة المرور في قائمة كلمات المرور الـ100.000 الأكثر استخداما.",
        "easydeflate-invaliddeflate": "المحتوى المقدم لا يتم تفريغه بشكل صحيح",
        "unprotected-js": "لأسباب تتعلق بالأمان; لا يمكن تحميل جافا سكريبت من الصفحات غير المحمية; الرجاء إنشاء جافا سكريبت فقط في نطاق ميدياويكي: أو كصفحة فرعية للمستخدم"
 }
index cb249c0..177da10 100644 (file)
        "resetpass_submit": "اظبط الباسورد و ادخل",
        "changepassword-success": "الباسورد بتاعتك اتغيرت بنجاح!",
        "changepassword-throttled": "انت عملت  محاولات لوجين كتيره  ع الحساب ده.\nمن فضلك استنى $1 قبل المحاولة مرة تانيه.",
+       "botpasswords-label-update": "تحديث",
        "resetpass_forbidden": "مش ممكن تغيير الباسورد",
        "resetpass-no-info": "لازم تسجل دخولك علشان تقدر توصل للصفحة دى على طول.",
        "resetpass-submit-loggedin": "غير الباسورد",
index b3fd36a..2eb3003 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Vista previa",
        "prefs-advancedrc": "Opciones avanzaes",
-       "prefs-opt-out": "Borrase de los ameyoramientos",
        "prefs-advancedrendering": "Opciones avanzaes",
        "prefs-advancedsearchoptions": "Opciones avanzaes",
        "prefs-advancedwatchlist": "Opciones avanzaes",
index 9809108..9b8a1fa 100644 (file)
        "parser-unstrip-loop-warning": "تکرارلاما دونمه سی قبول ائدیلدی",
        "unstrip-depth-warning": "حداکثر ارجاع دستور دا unstrip تجاوز گئچیب دیر ($1)",
        "converter-manual-rule-error": "خطا ال مبدیلی قانون لاریندا",
-       "undo-success": "بو دَییشیک‌لیک گئری آلینا بیلر. لطفاً آشاغی‌داکی موقاییسه ائتمیی نظارت ائدین، حقیقتن بو دییشیک‌لیگی ائتمک ایستدیگینیزدن امین اولون و صحیفنی یازا‌راق بیر اوولکی دییشیک‌لیگی گئرییه آلین.",
+       "undo-success": "بو دَییشیک‌لیک قایتاریلا بیلر. لوطفاً آشاغی‌داکی موقایسه‌نی یوْخلاییب، دوغرودان بو دییشیک‌لیگی ائتمک ایستدیگینیزدن آرخایین اولون و صفحه‌نی ذخیره ائتمکله قاباقکی دییشیکلیگی قایتارین.",
        "undo-failure": "دییشیک‌لیک‌لرین توققوشماسی نتیجه‌سینده گئرییه قایتارما ایشی اوغورسوز اولدو.",
        "undo-norev": "دوزلیش‌لر گئری قایتاریلا بیلینمیر، چونکی اونلار یا مؤوجود دئییل، یا دا سیلینیب.",
        "undo-nochange": "نظره گلیر دَییشدیرمه قاباغجادان قایتاریلیب.",
        "showhideselectedversions": "سئچیلمیش نوسخه‌لری گؤستر/گیزلد",
        "editundo": "قایتار",
        "diff-empty": "فرقیسیز",
-       "diff-multi-sameuser": "(همن کی ایشلدیچی طرفیندن ائدیلمیش  {{PLURAL:$1|بیر دَییشلیک|$1 بیر نئچه دَییشلیک}} گوستریلمیر)",
+       "diff-multi-sameuser": "(بۇ ایشلدنین طرفیندن ائدیلمیش  {{PLURAL:$1|بیر دَییشیکلیک|$1 بیر نئچه دَییشیکلیک}} گؤستریلمیر)",
        "diff-multi-otherusers": "({{PLURAL:$1|۱ میانی نوسخه لر|$1 میانی نوسخه لر}} دَییک اولونموش {{PLURAL:$2|۱ ایشلدچی|$2 ایشلدچی}}طرفیندن گوستریلمیر)",
        "diff-multi-manyusers": "{{PLURAL:$2|بیر|$2}}-دن چوخ ایستیفاده‌چی یارادان {{PLURAL:$1|بیر|$1}} نوسخه، گؤستریلمه‌ییب‌دیر",
        "difference-missing-revision": "بو فرقین ($1) {{PLURAL:$2|بیر|$2}} نوسخه‌سی تاپیلانمادی.\n\nعموماً بو خطا، سیلینن بیر صحیفه‌یه واختی گئچمیش بیر فرق باغلانتی‌سیلا گلمک ایله آرا گلر.\n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}سیلمک سیاهی‌سی]ندا باشقا بیلگیلر اولا بیلر.",
        "rcfilters-other-review-tools": "داها یوخلاما آلتلری",
        "rcfilters-group-results-by-page": "دییشیکلیکلری صفحه‌لرینه گؤره سیرالا",
        "rcfilters-activefilters": "چالیشقان فیلترلر",
+       "rcfilters-activefilters-hide": "گیزلت",
        "rcfilters-limit-title": "دَییشدیرمه سایی‌سی",
        "rcfilters-date-popup-title": "آختاریش چاغی",
        "rcfilters-days-title": "سوْن گۆنلر",
        "rcfilters-quickfilters": "ذخیره اولونموش فیلترلر",
        "rcfilters-quickfilters-placeholder-title": "هله‌لیک هئچ بیر فیلتر ذخیره اوْلونماییبدیر",
        "rcfilters-savedqueries-defaultlabel": "ذخیره اوْلونموش فیلترلر",
+       "rcfilters-savedqueries-setdefault": "دفالت حالتده تنظیمله",
+       "rcfilters-savedqueries-new-name-placeholder": "فیلتر هدفینی آچیقلا",
+       "rcfilters-savedqueries-apply-label": "فیلتر یارات",
        "rcfilters-clear-all-filters": "بۆتون فیلترلری سیل",
        "rcfilters-show-new-changes": "اَن سون دَییشیکلیکلره باخ",
        "rcfilters-search-placeholder": "سوْن دییشیکلیکلری فیلترله (منودان سئچین یوْخسا فیلتر آدینی آختارین)",
        "rcfilters-filtergroup-automated": "اوْتوماتیک دییشدیرمه‌لر",
        "rcfilters-filter-humans-label": "اینسان (غئیر روْبات)",
        "rcfilters-filter-humans-description": "اینسان اَلی ایله دییشدیرمه‌لر",
+       "rcfilters-filter-minor-label": "کیچیک دَییشدیرمه‌لر",
        "rcfilters-filtergroup-changetype": "دَییشیکلیک نوعو",
        "rcfilters-filter-pageedits-label": "صفحه دییشدیرمه‌لری",
        "rcfilters-filter-newpages-label": "صفحه یاراتما",
index 3394558..458ca5e 100644 (file)
        "prefs-editor": "Рэдактар",
        "prefs-preview": "Папярэдні прагляд",
        "prefs-advancedrc": "Дадатковыя налады",
-       "prefs-opt-out": "Адмовіцца ад паляпшэньняў",
        "prefs-advancedrendering": "Дадатковыя налады",
        "prefs-advancedsearchoptions": "Дадатковыя налады",
        "prefs-advancedwatchlist": "Дадатковыя налады",
        "sharedupload-desc-edit": "Гэты файл паходзіць з $1 і можа выкарыстоўвацца іншымі праектамі.\nКалі спатрэбіцца, вы можаце зьмяніць апісаньне файлу на [$2 адпаведнай старонцы].",
        "sharedupload-desc-create": "Гэты файл паходзіць з $1 і можа выкарыстоўвацца іншымі праектамі.\nКалі спатрэбіцца, вы можаце зьмяніць апісаньне на [$2 адпаведнай старонцы].",
        "filepage-nofile": "Файл з гэтай назвай не існуе.",
-       "filepage-nofile-link": "Файл з гэтай назвай не існуе, але Вы можаце [$1 загрузіць яго].",
+       "filepage-nofile-link": "Файл з такой назвай не існуе, але вы можаце [$1 загрузіць яго].",
        "uploadnewversion-linktext": "Загрузіць новую вэрсію гэтага файла",
-       "shared-repo-from": "$1",
+       "shared-repo-from": "з $1",
        "shared-repo": "агульнага сховішча",
        "shared-repo-name-wikimediacommons": "Вікісховішча",
        "upload-disallowed-here": "Вы ня можаце перазапісаць гэты файл.",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль ня можа супадаць з паролямі з чорнага сьпісу",
        "passwordpolicies-policy-maximalpasswordlength": "Пароль мусіць быць даўжынёй менш за $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Пароль ня можа {{PLURAL:$1|супадаць з самым папулярным паролем|быць зь сьпісу $1 папулярных пароляў}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Пароль ня можа быць зь сьпісу 100 000 найчасьцей ужываных пароляў.",
        "easydeflate-invaliddeflate": "Пададзены зьмест ня сьціснуты адпаведным чынам",
        "unprotected-js": "З прычынаў бясьпекі JavaScript ня можа быць загружаны зь неабароненых сайтаў. Калі ласка, стварайце javascript выключна ў прасторы назваў MediaWiki: ці як падстаронку ўдзельніка"
 }
index 6edce44..ae084e0 100644 (file)
        "prefs-editor": "Рэдактар",
        "prefs-preview": "Перадпаказ",
        "prefs-advancedrc": "Пашыраныя настройкі",
-       "prefs-opt-out": "Адмова ад паляпшэнняў",
        "prefs-advancedrendering": "Пашыраныя настройкі",
        "prefs-advancedsearchoptions": "Пашыраныя настройкі",
        "prefs-advancedwatchlist": "Пашыраныя настройкі",
index a67d212..7281cdc 100644 (file)
        "prefs-editor": "Редактор",
        "prefs-preview": "Преглед",
        "prefs-advancedrc": "Разширени настройки",
-       "prefs-opt-out": "Отписване от подобренията",
        "prefs-advancedrendering": "Разширени настройки",
        "prefs-advancedsearchoptions": "Разширени настройки",
        "prefs-advancedwatchlist": "Разширени настройки",
index 777b19a..cd7d0f8 100644 (file)
        "prefs-editor": "সম্পাদক",
        "prefs-preview": "প্রাকদর্শন",
        "prefs-advancedrc": "উচ্চতর পছন্দগুলি",
-       "prefs-opt-out": "উন্নতি অনির্বাচন",
        "prefs-advancedrendering": "উচ্চতর বিকল্পগুলি",
        "prefs-advancedsearchoptions": "উচ্চতর পছন্দগুলি",
        "prefs-advancedwatchlist": "উচ্চতর বিকল্পগুলি",
index b02033e..806cdb0 100644 (file)
        "prefs-editor": "Aozer",
        "prefs-preview": "Rakwelet",
        "prefs-advancedrc": "Dibarzhioù araokaet",
-       "prefs-opt-out": "Nac'hañ ar c'hemmoù",
        "prefs-advancedrendering": "Dibarzhioù araokaet",
        "prefs-advancedsearchoptions": "Dibarzhioù araokaet",
        "prefs-advancedwatchlist": "Dibarzhioù araokaet",
index 5cc04b5..50f139e 100644 (file)
        "prefs-editor": "Uređivač",
        "prefs-preview": "Pregled",
        "prefs-advancedrc": "Napredne opcije",
-       "prefs-opt-out": "Isključivanje poboljšanja",
        "prefs-advancedrendering": "Napredne opcije",
        "prefs-advancedsearchoptions": "Napredne opcije",
        "prefs-advancedwatchlist": "Napredne opcije",
index 146a029..22d956a 100644 (file)
        "prefs-editor": "Edició",
        "prefs-preview": "Previsualització",
        "prefs-advancedrc": "Opcions avançades",
-       "prefs-opt-out": "Renuncia a les millores",
        "prefs-advancedrendering": "Opcions avançades",
        "prefs-advancedsearchoptions": "Opcions avançades",
        "prefs-advancedwatchlist": "Opcions avançades",
index 6394cc7..98e7866 100644 (file)
        "prefs-editor": "Тадар",
        "prefs-preview": "Хьалххе хьажар",
        "prefs-advancedrc": "Кхин гӀирс нисбар",
-       "prefs-opt-out": "Дика кечъяр цаэшар",
        "prefs-advancedrendering": "Кхин гӀирс нисбар",
        "prefs-advancedsearchoptions": "Кхин гӀирс нисбар",
        "prefs-advancedwatchlist": "Кхин гӀирс нисбар",
index 0bc33d1..4a56710 100644 (file)
        "prefs-editor": "دەستکاریکەر",
        "prefs-preview": "پێشبینین",
        "prefs-advancedrc": "ھەڵبژاردەکانی پێشکەوتوو",
-       "prefs-opt-out": "گەڕاندنەوەی چاکسازییەکان",
        "prefs-advancedrendering": "هەڵبژاردە پێشکەوتووەکان",
        "prefs-advancedsearchoptions": "هەڵبژاردە پێشکەوتووەکان",
        "prefs-advancedwatchlist": "هەڵبژاردە پێشکەوتووەکان",
index af00619..1a2ef9d 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Náhled",
        "prefs-advancedrc": "Rozšířené možnosti",
-       "prefs-opt-out": "Nepoužívat vylepšení",
        "prefs-advancedrendering": "Rozšířené možnosti",
        "prefs-advancedsearchoptions": "Rozšířené možnosti",
        "prefs-advancedwatchlist": "Rozšířené možnosti",
index 424dbe1..bf079bd 100644 (file)
        "prefs-editor": "Redigeringsprogrammet",
        "prefs-preview": "Forhåndsvisning",
        "prefs-advancedrc": "Avancerede indstillinger",
-       "prefs-opt-out": "Vælg ikke at få forbedringer",
        "prefs-advancedrendering": "Avancerede indstillinger",
        "prefs-advancedsearchoptions": "Avancerede indstillinger",
        "prefs-advancedwatchlist": "Avancerede indstillinger",
index 23935a2..036bd08 100644 (file)
        "prefs-editor": "Bearbeitungsprogramm",
        "prefs-preview": "Vorschau",
        "prefs-advancedrc": "Erweiterte Optionen",
-       "prefs-opt-out": "Von den Verbesserungen abmelden",
        "prefs-advancedrendering": "Erweiterte Optionen",
        "prefs-advancedsearchoptions": "Erweiterte Optionen",
        "prefs-advancedwatchlist": "Erweiterte Optionen",
index 95de070..07ace65 100644 (file)
        "prefs-editor": "Συντάκτης",
        "prefs-preview": "Προεπισκόπηση",
        "prefs-advancedrc": "Προηγμένες επιλογές",
-       "prefs-opt-out": "Απόρριψη βελτιώσεων",
        "prefs-advancedrendering": "Προηγμένες επιλογές",
        "prefs-advancedsearchoptions": "Προηγμένες επιλογές",
        "prefs-advancedwatchlist": "Προηγμένες επιλογές",
index 72e6716..b2a755d 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Preview",
        "prefs-advancedrc": "Advanced options",
-       "prefs-opt-out": "Opt out of improvements",
        "prefs-advancedrendering": "Advanced options",
        "prefs-advancedsearchoptions": "Advanced options",
        "prefs-advancedwatchlist": "Advanced options",
index 5be4e7c..94ce631 100644 (file)
@@ -53,7 +53,8 @@
                        "Rafaneta",
                        "NMaia",
                        "Joao Xavier",
-                       "Surfo"
+                       "Surfo",
+                       "YvesNevelsteen"
                ]
        },
        "tog-underline": "Substrekado de ligiloj:",
        "passwordtooshort": "Pasvortoj devas esti longaj almenaŭ  $1 {{PLURAL:$1|1 signon|$1 signojn}}.",
        "passwordtoolong": "Pasvorto ne povas esti pli longa ol {{PLURAL:$1|1 signo|$1 signoj}}.",
        "passwordtoopopular": "Ne eblas uzi kutimajn pasvortojn. Bonvolu uzi pasvorton, kiu estas malpli facile divenebla.",
+       "passwordinlargeblacklist": "La enigita pasvorto estas en listo de tre ofte uzita pasvortojn. Bonvolu elekti pli unikan pasvorton.",
        "password-name-match": "Via pasvorto devas nepre malsami vian salutnomon.",
        "password-login-forbidden": "Estas malpermesite uzi tiun ĉi salutnomon kaj pasvorton.",
        "mailmypassword": "Refari pasvorton",
        "blocked-notice-logextract": "Ĉi tiu uzanto estas ĉi-momente forbarita.\nLa lasta protokolero estas jene montrata por via referenco:",
        "clearyourcache": "<strong>Notu:</strong>Post konservado, vi forviŝu la kaŝmemoron de via foliumilo por vidi la ŝanĝojn. \n* <strong>Firefox / Safari:</strong> Premu majuskligan klavon klakante <em>Reŝarĝi</em>, aŭ premu aŭ <em>Stir-F5</em> aŭ <em>Stir-R</em> (<em>⌘-R</em> kun Makintoŝo)\n* <strong>Google Chrome:</strong> Premu <em>Stir-majuskligklavon-R</em> (<em>⌘-Majuskligklavo-R</em> kun Makintoŝo)\n* <strong>Interreta Esplorilo</strong>: Premu <em>Stir</em> klakante <em>Refreŝu</em>, aŭ premu <em>Stir-F5</em> \n* <strong>Opera:</strong> Iru al <em>menuo →  parametroj</em> (<em>Opera →  Agordoj</em> per Makintoŝa) kaj tiam al <em>privateco kaj sekureco →  Nuligi retuman datenon → kaŝmemorataj bildoj kaj dosieroj</em>.",
        "usercssyoucanpreview": "'''Konsileto:''' Uzu la butonon \"Antaŭrigardi\" por provi vian novan CSS-kodon antaŭ konservado.",
+       "userjsonyoucanpreview": "<strong>Konsileto:</strong> Uzu la butonon \"{{int:showpreview}}\" por provi vian novan JSON antaŭ konservado.",
        "userjsyoucanpreview": "'''Konsileto:''' Uzu la butonon \"{{int:showpreview}}\" por provi vian novan Ĝavaskriptan kodon antaŭ konservado.",
        "usercsspreview": "'''Notu ke vi nur antaŭvidas vian uzanto-CSS.\nĜi ne jam estis konservita!'''",
+       "userjsonpreview": "<strong>Memoru ke vi nun nur provas kaj antaŭrigardas vian JSON. Ĝi ne estas jam konservita!</strong>",
        "userjspreview": "'''Memoru ke vi nun nur provas kaj antaŭrigardas vian uzantan Ĝavaskripton, ĝi ne estas jam konservita'''",
        "sitecsspreview": "'''Konsciu ke vi nur antaŭrigardas tiun ĉi CSS.'''\n'''Ĝi ne jam estis savita!''",
+       "sitejsonpreview": "<strong>Memoru ke vi nun nur provas kaj antaŭrigardas vian JSON-agordojn. Ĝi ne estas jam konservita!</strong>",
        "sitejspreview": "'''Konsciu ke vi nur antaŭrigardas tiun ĉi Ĝavaskripta kodon''. ''Ĝi ne jam estis konservita''.",
        "userinvalidconfigtitle": "<strong>Averto:</strong> Ne ekzistas etoso \"$1\".\nRememoru ke individuaj .css-aj, .json-aj kaj .js-aj paĝoj uzas minusklan titolon, ekz. {{ns:user}}:Foo/vector.css kontraŭe al {{ns:user}}:Foo/Vector.css.",
        "updated": "(Ĝisdatigita)",
        "prefs-dateformat": "Data formato",
        "prefs-timeoffset": "Tempa deŝovo",
        "prefs-advancedediting": "Ĝeneralaj opcioj",
+       "prefs-developertools": "Iloj por programistoj",
        "prefs-editor": "Redaktilo",
        "prefs-preview": "Antaŭrigardo",
        "prefs-advancedrc": "Progresaj opcioj",
        "prefs-advancedwatchlist": "Progresaj opcioj",
        "prefs-displayrc": "Montraj opcioj",
        "prefs-displaywatchlist": "Montraj opcioj",
+       "prefs-changesrc": "Ŝanĝoj montritaj",
+       "prefs-changeswatchlist": "Ŝanĝoj montritaj",
+       "prefs-pageswatchlist": "Atentataj paĝoj",
        "prefs-tokenwatchlist": "Ĵetono",
        "prefs-diffs": "Diferencoj",
        "prefs-help-prefershttps": "Ĉi tiu agordo ekefikos je via sekva ensaluto.",
        "editinguser": "Ŝanĝado de uzantorajtoj de la {{GENDER:$1|uzanto}} <strong>[[User:$1|$1]]</strong> $2",
        "viewinguserrights": "Vidi uzantorajtojn de {{GENDER:$1|uzanto}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Redakti grupojn de uzantoj",
-       "userrights-viewusergroup": "Vidi grupojn de uzantoj",
+       "userrights-viewusergroup": "Vidi {{GENDER:$1|user}}-grupojn",
        "saveusergroups": "Konservi grupojn de {{GENDER:$1|uzantoj}}",
        "userrights-groupsmember": "Membro de:",
        "userrights-groupsmember-auto": "Implica membro de:",
        "rcfilters-filter-editsbyself-description": "Viaj kontribuoj.",
        "rcfilters-filter-editsbyother-label": "ŝanĝoj faritaj de aliuloj",
        "rcfilters-filter-editsbyother-description": "Ĉiuj ŝanĝoj, escepte de viaj.",
-       "rcfilters-filtergroup-userExpLevel": "Spertonivelo (nur por registritaj uzantoj)",
+       "rcfilters-filtergroup-userExpLevel": "Registriĝo kaj spertonivelo de uzanto",
        "rcfilters-filter-user-experience-level-registered-label": "Registritaj",
        "rcfilters-filter-user-experience-level-registered-description": "Ensalutitaj redaktantoj.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Neregistritaj",
        "rcfilters-filter-minor-description": "Redaktoj kiujn la aŭtoro markis kiel \"redakteto\".",
        "rcfilters-filter-major-label": "Redaktoj kiujn la aŭtoro ne markis kiel \"redakteto\".",
        "rcfilters-filter-major-description": "Redaktoj kiujn la aŭtoro ne markis kiel \"redakteto\".",
+       "rcfilters-filter-watchlist-watched-label": "Sur atentaro",
+       "rcfilters-filter-watchlist-watched-description": "Ŝanĝoj al paĝoj sur via atentaro.",
+       "rcfilters-filter-watchlist-watchednew-label": "Nova ŝanĝoj en la atentaro",
+       "rcfilters-filter-watchlist-watchednew-description": "Ŝanĝoj al priatentataj paĝoj kiujn vi ne vizitis ekde kiam la ŝanĝoj okazis.",
+       "rcfilters-filter-watchlist-notwatched-label": "Ne sur la atentaro",
+       "rcfilters-filter-watchlist-notwatched-description": "Ĉio krom ŝanĝoj al viaj priatentataj paĝoj.",
+       "rcfilters-filtergroup-watchlistactivity": "Agado en la atentaro",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Nevidataj ŝanĝoj",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Ŝanĝoj al paĝoj kiujn vi ne vizitis ekde kiam la ŝanĝoj okazis.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Viditaj ŝanĝoj",
+       "rcfilters-filter-watchlistactivity-seen-description": "Ŝanĝoj al paĝoj kiujn vi vizitis ekde kiam la ŝanĝoj okazis.",
        "rcfilters-filtergroup-changetype": "Tipo de ŝanĝo",
        "rcfilters-filter-pageedits-label": "Redaktoj de paĝoj",
        "rcfilters-filter-pageedits-description": "Redaktoj al vikia enhavo, diskutoj, kategoriaj priskriboj…",
        "rcfilters-filter-categorization-description": "Registroj de paĝoj aldonitaj aŭ forigitaj de kategorioj",
        "rcfilters-filter-logactions-label": "Registritaj agoj",
        "rcfilters-filter-logactions-description": "Administraciaj agoj, kontaj kreoj, paĝaj forigoj, alŝutoj…",
+       "rcfilters-filtergroup-lastRevision": "Lastaj revizioj",
+       "rcfilters-filter-lastrevision-label": "Lasta revizio",
+       "rcfilters-filter-lastrevision-description": "Nur la plej lasta ŝanĝo al paĝo.",
+       "rcfilters-filter-previousrevision-label": "Ne la lasta revizio",
+       "rcfilters-filter-previousrevision-description": "Ĉiuj ŝanĝoj kiu ne estas la \"lasta revizio\".",
+       "rcfilters-filter-excluded": "Ekskludita",
+       "rcfilters-liveupdates-button": "Aŭtomata ĝisdatigo",
+       "rcfilters-liveupdates-button-title-on": "Malŝalti aŭtomatajn ĝisdatigojn",
+       "rcfilters-liveupdates-button-title-off": "Montri novajn ŝanĝojn dum ili okazas",
        "rcfilters-watchlist-markseen-button": "Marku ĉiujn ŝanĝojn viditaj",
+       "rcfilters-watchlist-edit-watchlist-button": "Redakti vian atentaron",
+       "rcfilters-watchlist-showupdated": "Ŝanĝoj en paĝo, kiun vi ne vizitis post la ŝanĝo, aperas <strong>graslitere</strong>, kun nigra disketo.",
        "rcnotefrom": "Malsupre estas la {{PLURAL:$5|ŝanĝo|ŝanĝoj}} ekde <strong>$3, $4</strong> (montrante ĝis <strong>$1</strong>).",
        "rclistfrom": "Montri novajn ŝanĝojn ekde \"$3 $2\"",
        "rcshowhideminor": "$1 etajn redaktojn",
        "uploadstash-exception": "Ne eblas alŝuti en kaŝkonservejon ($1): \"$2\".",
        "invalid-chunk-offset": "Malvalida deŝovo de dosierpeco",
        "img-auth-accessdenied": "Atingo malpermisita",
-       "img-auth-nopathinfo": "Mankas PATH_INFO (informo pri dosiervojo).\nVia servilo ne estas konfigurita por sendi ĉi tiun informon.\nEble ĝi estas CGI-bazita kaj ne subtenas img_auth.\nVidu https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization (angle).",
+       "img-auth-nopathinfo": "Mankas informo pri vojo.\nVia servilo estu agordita por sendi la variablojn REQUEST_URI kaj/aŭ PATH_INFO.\nSe ĝi jam estas, provu aktivigon de $wgUsePathInfo.\nVidu https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Petita vojo ne estas en la konfigurita alŝuta dosierujo.",
        "img-auth-badtitle": "Ne povas konstrui validan titolon de \"$1\".",
        "img-auth-nologinnWL": "Vi ne estas ensalutita kaj \"$1\" ne estas en la blankalisto.",
        "fix-double-redirects": "Ĝisdatigi iujn alidirektilojn kiuj direktas al la originala titolo",
        "move-leave-redirect": "Forlasi alidirektilon",
        "protectedpagemovewarning": "'''Averto:''' Ĉi tiu paĝo estis ŝlosita tiel nur uzantoj kun administranto-rajtoj povas movi ĝin.\nJen la lasta protokolero por via referenco:",
-       "semiprotectedpagemovewarning": "'''Averto:''' Ĉi tiu paĝo estis ŝlosita tiel ĝi estas nur movebla de registritaj uzantoj.\nJen la lasta protokolero por via referenco:",
+       "semiprotectedpagemovewarning": "<strong>Averto:</strong> Ĉi tiu paĝo estis ŝlosita tiel, ke ĝin povas movi nur aŭtomate konfirmitaj uzantoj.\nJen por vi la plej nova protokolero:",
        "move-over-sharedrepo": "[[:$1]] ekzistas en komuna dosierujo. Movado de dosiero al ĉi tiu titolo anstataŭigos la komunan dosieron.",
        "file-exists-sharedrepo": "La elektita dosiernomo jam estas uzita en komun dosierujo.\nBonvolu elekti alian nomon.",
        "export": "Elporti paĝojn",
        "tags-create-reason": "Kialo:",
        "tags-create-submit": "Krei",
        "tags-create-no-name": "Vi devas specifi nomon de etikedo.",
-       "tags-create-invalid-chars": "Etikednomoj maldevas enhavi komojn (<code>,</code>) aŭ suprenstrekojn (<code>/</code>).",
+       "tags-create-invalid-chars": "La nomoj de etikedoj ne havu komojn (<code>,</code>), vertikalajn strekojn <code>|</code> aŭ suprenstrekojn (<code>/</code>).",
        "tags-create-invalid-title-chars": "Etikednomoj maldevas enhavi signojn, kiuj ne povas esti uzitaj en paĝo-titoloj.",
        "tags-create-already-exists": "La markilo \"$1\" jam ekzistas.",
        "tags-create-warnings-above": "Dum provo krei la etikedon \"$1\" estis {{PLURAL:$2|trafita jena atentigo|trafitaj jenaj atentigoj}}:",
        "special-characters-title-endash": "mallonga streketo",
        "special-characters-title-emdash": "longa streketo",
        "special-characters-title-minus": "minus-signo",
-       "mw-widgets-abandonedit": "Ĉu vi vere volas foriri redaktan reĝimon sen konservo?",
+       "mw-widgets-abandonedit": "Ĉu vi vere volas forlasi la redaktan reĝimon sen konservo?",
        "mw-widgets-abandonedit-discard": "Forĵeti redaktojn",
        "mw-widgets-abandonedit-keep": "Redakti plu",
        "mw-widgets-abandonedit-title": "Ĉu vi certas?",
index bfc5b2c..5ca68d0 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Previsualización",
        "prefs-advancedrc": "Opciones avanzadas",
-       "prefs-opt-out": "Renunciar a las mejoras",
        "prefs-advancedrendering": "Opciones avanzadas",
        "prefs-advancedsearchoptions": "Opciones avanzadas",
        "prefs-advancedwatchlist": "Opciones avanzadas",
index c16f510..484579e 100644 (file)
        "prefs-editor": "Toimeti",
        "prefs-preview": "Eelvaade",
        "prefs-advancedrc": "Täpsemad eelistused",
-       "prefs-opt-out": "Täiustustest äraütlemine",
        "prefs-advancedrendering": "Täpsemad eelistused",
        "prefs-advancedsearchoptions": "Täpsemad eelistused",
        "prefs-advancedwatchlist": "Täpsemad eelistused",
index e69c96d..a9c05f6 100644 (file)
        "prefs-editor": "Editorea",
        "prefs-preview": "Aurreikusi",
        "prefs-advancedrc": "Aukera aurreratuak",
-       "prefs-opt-out": "Hobekuntzarik gabeko Opt",
        "prefs-advancedrendering": "Aukera aurreratuak",
        "prefs-advancedsearchoptions": "Aukera aurreratuak",
        "prefs-advancedwatchlist": "Aukera aurreratuak",
index 3871d18..689e2a0 100644 (file)
        "prefs-editor": "ویرایشگر",
        "prefs-preview": "پیش‌نمایش",
        "prefs-advancedrc": "گزینه‌های پیشرفته",
-       "prefs-opt-out": "گزینه برای بهبود",
        "prefs-advancedrendering": "گزینه‌های پیشرفته",
        "prefs-advancedsearchoptions": "گزینه‌های پیشرفته",
        "prefs-advancedwatchlist": "گزینه‌های پیشرفته",
index c57c642..a5974bb 100644 (file)
        "prefs-editor": "Muokkain",
        "prefs-preview": "Esikatselu",
        "prefs-advancedrc": "Lisäasetukset",
-       "prefs-opt-out": "Jättäydy pois uudistuksista",
        "prefs-advancedrendering": "Lisäasetukset",
        "prefs-advancedsearchoptions": "Lisäasetukset",
        "prefs-advancedwatchlist": "Lisäasetukset",
index 1b5fe10..1716146 100644 (file)
        "prefs-editor": "Éditeur",
        "prefs-preview": "Aperçu",
        "prefs-advancedrc": "Options avancées",
-       "prefs-opt-out": "Refuser les améliorations",
        "prefs-advancedrendering": "Options avancées",
        "prefs-advancedsearchoptions": "Options avancées",
        "prefs-advancedwatchlist": "Options avancées",
index e00f3d7..4f467dc 100644 (file)
        "prefs-editor": "Skriiwer",
        "prefs-preview": "Föörskau",
        "prefs-advancedrc": "Ütjwidjet mögelkhaiden",
-       "prefs-opt-out": "Faan ferbeedrangen ufmelde",
        "prefs-advancedrendering": "Ütjwidjet mögelkhaiden",
        "prefs-advancedsearchoptions": "Ütjwidjet mögelkhaiden",
        "prefs-advancedwatchlist": "Ütjwidjet mögelkhaiden",
index 505bc0d..9db517b 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Vista previa",
        "prefs-advancedrc": "Opcións avanzadas",
-       "prefs-opt-out": "Excluír de melloras",
        "prefs-advancedrendering": "Opcións avanzadas",
        "prefs-advancedsearchoptions": "Opcións avanzadas",
        "prefs-advancedwatchlist": "Opcións avanzadas",
index cd70fb7..d091092 100644 (file)
        "prefs-editor": "חלון העריכה",
        "prefs-preview": "תצוגה מקדימה",
        "prefs-advancedrc": "אפשרויות מתקדמות",
-       "prefs-opt-out": "ביטול שיפורים",
        "prefs-advancedrendering": "אפשרויות מתקדמות",
        "prefs-advancedsearchoptions": "אפשרויות מתקדמות",
        "prefs-advancedwatchlist": "אפשרויות מתקדמות",
index 26b3f17..0488f2c 100644 (file)
        "prefs-editor": "सम्पादक",
        "prefs-preview": "पूर्वावलोकन",
        "prefs-advancedrc": "उन्नत विकल्प",
-       "prefs-opt-out": "बदलावों के बहार का विकल्प",
        "prefs-advancedrendering": "उन्नत विकल्प",
        "prefs-advancedsearchoptions": "उन्नत विकल्प",
        "prefs-advancedwatchlist": "उन्नत विकल्प",
index 69a6d28..0abf3a2 100644 (file)
        "prefs-editor": "Uređivač",
        "prefs-preview": "Prikaži kako će izgledati",
        "prefs-advancedrc": "Napredne mogućnosti",
-       "prefs-opt-out": "Izuzimanje od poboljšanja",
        "prefs-advancedrendering": "Napredne mogućnosti",
        "prefs-advancedsearchoptions": "Napredne mogućnosti",
        "prefs-advancedwatchlist": "Napredne mogućnosti",
index 641c395..3327882 100644 (file)
        "prefs-editor": "Szerkesztő",
        "prefs-preview": "Előnézet",
        "prefs-advancedrc": "Haladó beállítások",
-       "prefs-opt-out": "Fejlesztések kikapcsolása",
        "prefs-advancedrendering": "Haladó beállítások",
        "prefs-advancedsearchoptions": "Haladó beállítások",
        "prefs-advancedwatchlist": "Haladó beállítások",
index a49a433..bdad332 100644 (file)
        "noarticletext": "Ներկայումս այս էջում որևէ տեքստ չկա։\nԴուք կարող եք [[Special:Search/{{PAGENAME}}|որոնել այս անվանումը]] այլ էջերում, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} որոնել համապատասխան տեղեկամատյանները] կամ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ստեղծել նոր էջ այս անվանմամբ]</span>։",
        "noarticletext-nopermission": "Ներկայումս այս էջում որևէ տեքստ չկա։\nԴուք կարող եք [[Special:Search/{{PAGENAME}}|որոնել այս անվանունը]] այլ էջերում կամ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} որոնել այն տեղեկամատյաններում]</span>։ Դուք չունեք թույլտվություն ստեղծել այս էջը։",
        "userpage-userdoesnotexist": "«<nowiki>$1</nowiki>» անվանմամբ մասնակից գոյություն չունի։\nԽնդրում ենք հավաստիանալ նրանում, թե արդյոք ուզում եք ստեղծել/խմբագրել այս էջը։",
-       "userpage-userdoesnotexist-view": "«$1» Õ¡Õ¶Õ¾Õ¡Õ¶Õ´Õ¡Õ´Õ¢ Õ£Ö\80Õ¡Õ¶Ö\81Õ¾Õ¡Õ® Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ«Ö\81 Õ¹Õ¯Õ¡Ö\89",
+       "userpage-userdoesnotexist-view": "«$1» անվամբ գրանցված մասնակից չկա։",
        "blocked-notice-logextract": "Այս մասնակիցը ներկա պահին արգելափակված է։\nՍտորև ներկայացված է արգելափակման տեղեկամատյանի վերջին գրառումը.",
        "clearyourcache": "'''Ծանուցում. Հիշելուց հետո կատարված փոփոխությունները տեսնելու համար մաքրեք ձեր զննարկիչի հիշապահեստը. '''\n'''Mozilla / Firefox / Safari'''՝ ''Ctrl+Shift+R''  (''Cmd+Shift+R'' Mac OS X-ում)\n'''Konqueror'''՝ ''F5''\n'''Opera'''՝ ''Tools→Preferences'' ընտրացանկից։\n'''Internet Explorer'''՝ ''Ctrl+F5''",
        "usercssyoucanpreview": "'''Հուշում.''' Էջը հիշելուց առաջ օգտվեք «{{int:showpreview}}» կոճակից՝ ձեր նոր CSS-նիշքը ստուգելու համար։",
        "prefs-signature": "Ստորագրություն",
        "prefs-dateformat": "Ամսաթվի ձևաչափ",
        "prefs-timeoffset": "Ժամային տարբերություն",
-       "prefs-advancedediting": "Ընդլայնված ընրանքներ",
+       "prefs-advancedediting": "Ընդլայնված ընտրանքներ",
        "prefs-editor": "Խմբագիր",
        "prefs-preview": "Նախադիտել",
-       "prefs-advancedrc": "Ընդլայնված ընրանքներ",
-       "prefs-advancedrendering": "Ընդլայնված ընրանքներ",
-       "prefs-advancedsearchoptions": "Ընդլայնված ընրանքներ",
-       "prefs-advancedwatchlist": "Ընդլայնված ընրանքներ",
+       "prefs-advancedrc": "Ընդլայնված ընտրանքներ",
+       "prefs-advancedrendering": "Ընդլայնված ընտրանքներ",
+       "prefs-advancedsearchoptions": "Ընդլայնված ընտրանքներ",
+       "prefs-advancedwatchlist": "Ընդլայնված ընտրանքներ",
        "prefs-displayrc": "Ցուցադրման ընտրանքներ",
        "prefs-displaywatchlist": "Ցուցադրման ընտրանքներ",
        "prefs-diffs": "Տարբերություններ",
        "license-nopreview": "(Նախադիտումը մատչելի չէ)",
        "upload_source_url": " (գործուն, հանրամատչելի URL-հասցե)",
        "upload_source_file": " (նիշք ձեր համակարգչի վրա)",
-       "listfiles_search_for": "Õ\88Ö\80Õ¸Õ¶Õ¥Õ¬ ÕºÕ¡Õ¿Õ¯Õ¥Ö\80Õ« Õ¡Õ¶Õ¾Õ¡Õ¶Õ´Õ¡Õ´Õ¢.",
+       "listfiles_search_for": "Որոնել պատկերի անվամբ.",
        "imgfile": "նիշք",
        "listfiles": "Նիշքերի ցանկ",
        "listfiles_date": "Օր/Ժամ",
index f3b1683..a0b2d6a 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Previsualisation",
        "prefs-advancedrc": "Optiones avantiate",
-       "prefs-opt-out": "Non incorporar meliorationes",
        "prefs-advancedrendering": "Optiones avantiate",
        "prefs-advancedsearchoptions": "Optiones avantiate",
        "prefs-advancedwatchlist": "Optiones avantiate",
index 0bc134c..786339e 100644 (file)
        "prefs-editor": "Penyunting",
        "prefs-preview": "Pratayang",
        "prefs-advancedrc": "Opsi lanjutan",
-       "prefs-opt-out": "Memilih keluar dari perbaikan",
        "prefs-advancedrendering": "Opsi lanjutan",
        "prefs-advancedsearchoptions": "Opsi lanjutan",
        "prefs-advancedwatchlist": "Opsi lanjutan",
index 058bcbe..b13c7c1 100644 (file)
        "prefs-developertools": "Кийчдархочун кечалаш",
        "prefs-preview": "Хьалххе бIаргтохар",
        "prefs-advancedrc": "Кхыдола шердаь оттамаш",
-       "prefs-opt-out": "Алсамдалар тӀацаэцар",
        "prefs-advancedrendering": "Кхыдола шердаь оттамаш",
        "prefs-advancedsearchoptions": "Шердаь оттамаш",
        "prefs-advancedwatchlist": "Кхыдола шердаь оттамаш",
index 8940fb6..03ba77d 100644 (file)
        "prefs-editor": "Ritsjóri",
        "prefs-preview": "Forskoðun",
        "prefs-advancedrc": "Háþróaðir möguleikar",
-       "prefs-opt-out": "Hafna endurbótum",
        "prefs-advancedrendering": "Háþróaðir möguleikar",
        "prefs-advancedsearchoptions": "Háþróaðir möguleikar",
        "prefs-advancedwatchlist": "Háþróaðir möguleikar",
index 34ff7dc..7231d39 100644 (file)
        "passwordtooshort": "Le password devono contenere almeno {{PLURAL:$1|1 carattere|$1 caratteri}}.",
        "passwordtoolong": "La password non può contenere più di {{PLURAL:$1|1 carattere|$1 caratteri}}.",
        "passwordtoopopular": "Password comuni non possono essere usate. Scegli una password più difficile da indovinare.",
+       "passwordinlargeblacklist": "La password inserita è nell'elenco delle password utilizzate più comunemente. Si prega di scegliere una password più unica.",
        "password-name-match": "La password deve essere diversa dal nome utente.",
        "password-login-forbidden": "L'uso di questo nome utente e password è stato proibito.",
        "mailmypassword": "Reimposta password",
        "prefs-editor": "Editore",
        "prefs-preview": "Anteprima",
        "prefs-advancedrc": "Opzioni avanzate",
-       "prefs-opt-out": "Disattivazione dei miglioramenti",
        "prefs-advancedrendering": "Opzioni avanzate",
        "prefs-advancedsearchoptions": "Opzioni avanzate",
        "prefs-advancedwatchlist": "Opzioni avanzate",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "La password non può corrispondere a password specificate nell'elenco delle password proibite",
        "passwordpolicies-policy-maximalpasswordlength": "La password deve essere lunga meno di $1 {{PLURAL:$1|carattere|caratteri}}",
        "passwordpolicies-policy-passwordcannotbepopular": "La password non può essere {{PLURAL:$1|la password più popolare|nell'elenco delle $1 password più popolari}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "La password non può essere nell'elenco delle 100 000 password utilizzate più comunemente.",
        "unprotected-js": "Per motivi di sicurezza, non è possibile caricare JavaScript da pagine non protette. Crea javascript solo nel namespace MediaWiki o come sottopagina Utente"
 }
index ca3f978..ab933ca 100644 (file)
        "prefs-editor": "エディター",
        "prefs-preview": "プレビュー",
        "prefs-advancedrc": "詳細の設定",
-       "prefs-opt-out": "改善の使用を断る",
        "prefs-advancedrendering": "詳細の設定",
        "prefs-advancedsearchoptions": "詳細設定",
        "prefs-advancedwatchlist": "詳細の設定",
index 0a454f9..15a7a4f 100644 (file)
        "prefs-editor": "რედაქტორი",
        "prefs-preview": "წინასწარი გადახედვა",
        "prefs-advancedrc": "გაფართოებული პარამეტრები",
-       "prefs-opt-out": "გაუმჯობესების გამორიცხვა",
        "prefs-advancedrendering": "გაფართოებული პარამეტრები",
        "prefs-advancedsearchoptions": "გაფართოებული პარამეტრები",
        "prefs-advancedwatchlist": "გაფართოებული კონფიგურაციები",
index d78e8a2..ab618c0 100644 (file)
        "prefs-editor": "ឧបករណ៍កែប្រែ",
        "prefs-preview": "ឧបករណ៍មើលជាមុន",
        "prefs-advancedrc": "ជម្រើសថ្នាក់ខ្ពស់",
-       "prefs-opt-out": "ជម្រើសមិនប្រើមុខងារជឿនលឿន",
        "prefs-advancedrendering": "ជម្រើសថ្នាក់ខ្ពស់",
        "prefs-advancedsearchoptions": "ជម្រើសថ្នាក់ខ្ពស់",
        "prefs-advancedwatchlist": "ជម្រើសថ្នាក់ខ្ពស់",
index c4e4798..4a381f3 100644 (file)
        "prefs-editor": "편집기",
        "prefs-preview": "미리 보기",
        "prefs-advancedrc": "고급 옵션",
-       "prefs-opt-out": "개선 기능에 참여하지 않음",
        "prefs-advancedrendering": "고급 옵션",
        "prefs-advancedsearchoptions": "고급 옵션",
        "prefs-advancedwatchlist": "고급 옵션",
index 8dcda29..bde1da2 100644 (file)
        "deletereason-dropdown": "*Causae deletionum communes\n** Spam\n** Vandalismus\n** Violatio verborum privatorum\n** Desiderium auctoris\n** Redirectio fracta",
        "delete-edit-reasonlist": "Causas deletionum recensere",
        "rollback": "Reverti mutationes",
-       "rollbacklink": "reverti",
+       "rollbacklink": "Plura statim revertere",
        "rollbacklinkcount": "reverti {{PLURAL:$1|unam recensionem|$1 recensiones}}",
        "rollbacklinkcount-morethan": "reverti plus quam {{PLURAL:$1|unam recensionem|$1 recensiones}}",
        "rollbackfailed": "Reversum defecit",
index 67f9963..700ae7c 100644 (file)
        "prefs-editor": "Editeur",
        "prefs-preview": "Kucken ouni ofzespäicheren",
        "prefs-advancedrc": "Méi Optiounen",
-       "prefs-opt-out": "Verbesserungen net méi benotzen",
        "prefs-advancedrendering": "Méi Optiounen",
        "prefs-advancedsearchoptions": "Méi Optiounen",
        "prefs-advancedwatchlist": "Méi Optiounen",
index 095dca9..094cbd1 100644 (file)
        "prefs-editor": "Editador",
        "prefs-preview": "Previde",
        "prefs-advancedrc": "Elejes avansada",
-       "prefs-opt-out": "No partisipa en bonis",
        "prefs-advancedrendering": "Elejes avansada",
        "prefs-advancedsearchoptions": "Elejes avansada",
        "prefs-advancedwatchlist": "Elejes avansada",
index bcbcc0b..e490d21 100644 (file)
        "prefs-editor": "Bewirker",
        "prefs-preview": "Veurbesjouwing",
        "prefs-advancedrc": "Wiejer instèllinger",
-       "prefs-opt-out": "Neet mitdoen aan de verbeteringe",
        "prefs-advancedrendering": "Wiejer instèllinger",
        "prefs-advancedsearchoptions": "Wiejer instèllinger",
        "prefs-advancedwatchlist": "Wiejer instèllinger",
index 0429e32..0887611 100644 (file)
        "prefs-editor": "Redaktorius",
        "prefs-preview": "Peržiūra",
        "prefs-advancedrc": "Papildomi nustatymai",
-       "prefs-opt-out": "Atsisakyti patobulinimų",
        "prefs-advancedrendering": "Papildomi nustatymai",
        "prefs-advancedsearchoptions": "Papildomi nustatymai",
        "prefs-advancedwatchlist": "Papildomi nustatymai",
index d06513a..fd6e131 100644 (file)
        "prefs-editor": "Redaktors",
        "prefs-preview": "Priekšskatījums",
        "prefs-advancedrc": "Papildu iespējas",
-       "prefs-opt-out": "Atteikties no uzlabojumiem",
        "prefs-advancedrendering": "Papildu iespējas",
        "prefs-advancedsearchoptions": "Papildu iespējas",
        "prefs-advancedwatchlist": "Papildu iespējas",
        "rcfilters-filtergroup-lastRevision": "Pašreizējās versijas",
        "rcfilters-filter-lastrevision-label": "Pašreizējā versija",
        "rcfilters-filter-lastrevision-description": "Tikai nesenākā lapas izmaiņa.",
-       "rcfilters-filter-previousrevision-label": "Agrākas versijas",
+       "rcfilters-filter-previousrevision-label": "Ne pēdējā versija",
        "rcfilters-filter-previousrevision-description": "Visas izmaiņas, kas nav lapas pēdējā izmaiņa.",
        "rcfilters-exclude-button-off": "Izslēgt izvēlētos",
        "rcfilters-view-tags": "Iezīmētie labojumi",
        "rcfilters-watchlist-markseen-button": "Atzīmēt visas izmaiņas kā apskatītas",
        "rcfilters-watchlist-edit-watchlist-button": "Labot manu uzraugāmo lapu sarakstu",
        "rcfilters-watchlist-showupdated": "Izmaiņas lapās, kuras nav apmeklētas kopš izmaiņu veikšanas, ir <strong>trekninātā rakstā</strong>.",
-       "rcfilters-preference-label": "Paslēpt uzlaboto pēdējo izmaiņu versiju",
+       "rcfilters-preference-label": "Izmantot saskarni bez JavaScript atbalsta",
        "rcfilters-target-page-placeholder": "Ievadi lapas nosaukumu (vai kategoriju)",
        "rcnotefrom": "Zemāk {{PLURAL:$5|redzamas izmaiņas|redzama izmaiņa|redzamas izmaiņas}} kopš <strong>$3, $4</strong> (parādītas ne vairāk kā <strong>$1</strong>).",
        "rclistfromreset": "Atiestatīt datuma izvēli",
        "speciallogtitlelabel": "Mērķis (nosaukums vai {{ns:user}}:lietotājvārds dalībniekam):",
        "log": "Reģistri",
        "logeventslist-submit": "Rādīt",
+       "logeventslist-patrol-log": "Pārbaudes reģistrs",
+       "logeventslist-tag-log": "Iezīmju žurnāls",
        "all-logs-page": "Visi publiski pieejamie reģistri",
        "alllogstext": "Visi pieejamie {{grammar:akuzatīvs{{SITENAME}}}} reģistri.\nTu vari sašaurināt aplūkojamo reģistru, izvēloties reģistra veidu, lietotāja vārdu vai reģistrēto lapu. Visi teksta lauki izšķir lielos un mazos burtus.",
        "logempty": "Reģistrā nav atbilstošu ierakstu.",
        "uctop": "pēdējā izmaiņa",
        "month": "No mēneša (un senāki):",
        "year": "No gada (un senāki):",
+       "date": "No datuma (un senāki):",
        "sp-contributions-newbies": "Rādīt jauno lietotāju devumu",
        "sp-contributions-newbies-sub": "Jaunie lietotāji",
        "sp-contributions-newbies-title": "Jauno dalībnieku devums",
        "logentry-delete-delete": "$1 {{GENDER:$2|izdzēsa}} lapu $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|izdzēsa}} pāradresāciju $3 pārrakstot",
        "logentry-delete-restore": "$1 {{GENDER:$2|atjaunoja}} lapu $3 ($4)",
+       "restore-count-revisions": "{{PLURAL:$1|$1 versijas|$1 versija|$1 versijas}}",
        "restore-count-files": "{{PLURAL: $1|$1 faili|$1 fails|$1 faili}}",
        "logentry-delete-revision": "$1 {{GENDER:$2|nomainīja}} $5 {{PLURAL:$5|versiju|versijas|versiju}} redzamību lapai $3: $4",
        "logentry-suppress-delete": "$1 {{GENDER:$2|cenzēja}} lapu $3",
        "revdelete-unrestricted": "noņemt administratoriem ierobežojumus",
        "logentry-block-block": "$1 {{GENDER:$2|nobloķēja}} {{GENDER:$4|$3}} ar beigu termiņu $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|atbloķēja}} {{GENDER:$4|$3}}",
+       "logentry-import-interwiki": "$1 {{GENDER:$2|importēja}} $3 no citas vikivietnes",
        "logentry-move-move": "$1 {{GENDER:$2|pārvietoja}} lapu $3 uz $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|pārvietoja}} lapu $3 uz $4, neatstājot pāradresāciju",
        "logentry-move-move_redir": "$1 {{GENDER:$2|pārvietoja}} lapu $3 uz $4, atstājot pāradresāciju",
index 173b798..0aa70fb 100644 (file)
        "views": "覽",
        "toolbox": "多寶",
        "tool-link-userrights": "{{GENDER:$1|職權}}",
+       "tool-link-userrights-readonly": "權界",
        "tool-link-emailuser": "{{GENDER:$1|遺書}}",
        "imagepage": "述",
        "mediawikipage": "觀訊",
        "editusergroup": "治社",
        "editinguser": "正纂簿<strong>[[User:$1|$1]]</strong>之權",
        "userrights-editusergroup": "治社",
+       "userrights-viewusergroup": "權界",
        "saveusergroups": "定之",
        "userrights-groupsmember": "有員:",
        "userrights-groupsmember-auto": "固有員:",
index ce95f67..23be18d 100644 (file)
@@ -24,7 +24,8 @@
                        "Tulsi Bhagat",
                        "Macofe",
                        "राम प्रसाद जोशी",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Haribanshi"
                ]
        },
        "tog-underline": "लिङ्कके रेखाङ्कित करी:",
        "savechanges": "रक्षण करी",
        "publishpage": "पृष्ठ प्रकाशित करी",
        "publishchanges": "परिवर्तन प्रकाशित करी",
+       "savearticle-start": "पन्नाक रक्षण करू",
        "preview": "पूर्वावलोकन",
        "showpreview": "पूर्वप्रदर्शन",
        "showdiff": "परिवर्तन देखाबी",
        "revdelete-unsuppress": "पुनर्स्थापित संशोधन लेल प्रतिबन्ध हटाबी",
        "revdelete-log": "कारण:",
        "revdelete-submit": "चयनित {{PLURAL:$1|संसोधन|संसोधनसभ}} पर लागू करी",
-       "revdelete-success": "'''संशोधन दृश्यता सफलतापूर्वक अद्यतन कएल गेल।'''",
+       "revdelete-success": "संशोधन दृश्यता सफलतापूर्वक अद्यतन कएल गेल।",
        "revdelete-failure": "संशोधन दृश्यता अद्यतन नै कएल जा सकल: $1",
-       "logdelete-success": "'''वृत्तलेख दृश्यता सफलतासँ निर्धारित भेल।'''",
+       "logdelete-success": "वृत्तलेख दृश्यता सफलतासँ निर्धारित भेल।",
        "logdelete-failure": "'''वृत्तलेख दृश्यता निर्धारित नै भऽ सकल।'''$1",
        "revdel-restore": "दृष्टिकुशलता बदली",
        "pagehist": "पन्नाक इतिहास",
        "username": "{{GENDER:$1|प्रयोगकर्तानाम}}:",
        "prefs-memberingroups": "निम्नलिखित {{PLURAL:$1|समूह|समूहसभ}}क {{GENDER:$2|सदस्य}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 ($2 तक)",
        "prefs-registration": "पञ्जीकरणक समए:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "असली नाम:",
        "prefs-dateformat": "तिथि प्रारूप",
        "prefs-timeoffset": "समए संशोधक",
        "prefs-advancedediting": "विशिष्ट विकल्प सभ",
+       "prefs-developertools": "डेवलपर उपकरण",
        "prefs-editor": "सम्पादक",
        "prefs-preview": "पूर्वावलोकन",
        "prefs-advancedrc": "विशिष्ट विकल्पसभ",
        "prefs-advancedwatchlist": "विशिष्ट विकल्पसभ",
        "prefs-displayrc": "दृश्य विकल्पसभ",
        "prefs-displaywatchlist": "दृश्य विकल्पसभ",
+       "prefs-changesrc": "बदलेलहा देखाल",
        "prefs-tokenwatchlist": "टोकन",
        "prefs-diffs": "अन्तर",
        "prefs-help-prefershttps": "इ प्राथमिकता अहाँके फेर स सम्प्रवेश करलाक बाद प्रभाव पडत।",
        "userrights": "प्रयोक्ता अधिकारक प्रबन्धन",
        "userrights-lookup-user": "प्रयोक्ता समूहसभक प्रबन्ध करी",
        "userrights-user-editname": "एकटा प्रयोक्तानाम लिखी:",
-       "editusergroup": "{{GENDER:$1|सदस्य}} समूहसभक सम्पादन करी",
+       "editusergroup": "प्रयोगकर्ता समूह देखालजाय",
        "editinguser": "सदस्य '''[[User:$1|$1]]''' $2 क अधिकार बदलि\n{{GENDER:$1|सदस्य}}क सदस्य अधिकार बदलल जा रहल अछि <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "प्रयोगकर्ता समूह सम्पादित करी",
        "saveusergroups": "{{GENDER:$1|सदस्य}} समूह सङ्ग्रह करी",
        "group-autoconfirmed": "स्वतःअनुमोदित प्रयोक्ता",
        "group-bot": "स्वचालक",
        "group-sysop": "प्रबन्धक",
+       "group-interface-admin": "इंटरफ़ेस प्रशासक",
        "group-bureaucrat": "अधिकारी",
        "group-suppress": "नुकाबए वाला",
        "group-all": "(सभ)",
        "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": "पन्ना सभ पढ़ू",
        "grant-createaccount": "खाता खोलल जाए",
        "grant-createeditmovepage": "निर्माण, सम्पादन, आ स्थानान्तरण करनाए",
        "grant-delete": "लेख, अवतरण आ लग हटेनाए",
-       "grant-editinterface": "मिडियाविकि नामस्थान आ सदस्य सिएसएस/जेएस सम्पादित करनाए",
+       "grant-editinterface": "मिडियाविकि नामस्थान आ सदस्य सिएसएस/जेएस सम्पादित",
        "grant-editmycssjs": "अपन सदस्य सिएसएस/जेएस सम्पादित करी",
        "grant-editmyoptions": "अपन सदस्य पसन्द सम्पादित करी",
        "grant-editmywatchlist": "अपन साकांक्षसूची सम्पादित करी",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|नव पन्नसभक सूची]] सेहो देखी)",
        "recentchanges-submit": "देखाबी",
        "rcfilters-legend-heading": "<strong>सङ्केतक सूची:</strong>",
+       "rcfilters-activefilters-hide": "नुकाबी",
+       "rcfilters-activefilters-show": "देखाबी",
+       "rcfilters-limit-title": "परिणाम देखाबी",
+       "rcfilters-savedqueries-rename": "नाम बदलु",
+       "rcfilters-savedqueries-setdefault": "मूल के रूप मे राखु",
+       "rcfilters-savedqueries-remove": "मेटाबी",
+       "rcfilters-savedqueries-new-name-label": "नाम",
+       "rcfilters-savedqueries-new-name-placeholder": "फ़िल्टर के उद्देश्य बताबु",
+       "rcfilters-savedqueries-apply-label": "फ़िल्टर बनाबु",
+       "rcfilters-savedqueries-cancel-label": "रद्द करु",
+       "rcfilters-clear-all-filters": "फ़िल्टरसभ मिटाबु",
+       "rcfilters-filterlist-title": "चलनीसभ",
+       "rcfilters-highlightmenu-title": "रंग चुनु",
+       "rcfilters-filter-editsbyself-label": "अहाक बदलावसभ",
+       "rcfilters-filter-editsbyself-description": "अहाक अपन योगदान।",
+       "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-newcomer-label": "अपरिचित",
+       "rcfilters-filter-user-experience-level-learner-label": "शिक्षार्थिसभ",
+       "rcfilters-filter-user-experience-level-experienced-label": "अनुभवी सदस्यसभ",
+       "rcfilters-filter-bots-label": "स्वचालक",
+       "rcfilters-filter-bots-description": "स्वचालित औजार से करलहा सम्पादनसभ।",
+       "rcfilters-filtergroup-reviewstatus": "पुनरीक्षण स्थिति",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "अपरीक्षित",
+       "rcfilters-filter-reviewstatus-auto-label": "सवापरिक्षित",
+       "rcfilters-filter-minor-label": "छोट सम्पादन",
+       "rcfilters-filter-watchlist-watched-label": "साकांक्षसूची",
+       "rcfilters-filter-watchlistactivity-seen-label": "परिवर्तन सभ चुनु",
+       "rcfilters-filtergroup-changetype": "बदल क प्रकार:",
+       "rcfilters-filter-pageedits-label": "पन्नाक संपादनसभ",
        "rcnotefrom": "नीचाँमे '''$2''' सँ भेल परिवर्तन अछि ('''$1''' धरि देखाएल)।",
        "rclistfrom": "$3 $2 सँ शुरू भेल नव परिवर्तन देखी",
        "rcshowhideminor": "$1 अल्प सम्पादन",
index f564730..be7811b 100644 (file)
        "passwordtooshort": "Лозинката мора да има најмалку {{PLURAL:$1|1 знак|$1 знаци}}.",
        "passwordtoolong": "Лозинката не треба да има повеќе од {{PLURAL:$1|1 знак|$1 знаци}}.",
        "passwordtoopopular": "Не се допуштаат пречесто застапени лозинки. Изберете потешка лозинка за погодување.",
+       "passwordinlargeblacklist": "Внесената лозинка е меѓу најчесто користените. Изберете поинаква.",
        "password-name-match": "Лозинката мора да се разликува од корисничкото име.",
        "password-login-forbidden": "Употребата на ова корисничко име и лозинка е забранета.",
        "mailmypassword": "Нова лозинка",
        "prefs-editor": "Уредник",
        "prefs-preview": "Преглед",
        "prefs-advancedrc": "Напредни нагодувања",
-       "prefs-opt-out": "Отпиши ме од подобрувањата",
        "prefs-advancedrendering": "Напредни нагодувања",
        "prefs-advancedsearchoptions": "Напредни нагодувања",
        "prefs-advancedwatchlist": "Напредни нагодувања",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Лозинката не смее да биде од оние на црниот список",
        "passwordpolicies-policy-maximalpasswordlength": "Лозинката не треба да има повеќе од $1 {{PLURAL:$1|знак|знаци}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Лозинката не треба да биде {{PLURAL:$1|најзастапената|од списокот на $1 најзастапени лозинки}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Лозинката не може да биде меѓу 100.000-те најчести лозинки.",
        "easydeflate-invaliddeflate": "Содржината не е соодветно прочистена",
        "unprotected-js": "JavaScript не може да се вчита од незаштитени страници од безбедносни причини. Создавајте JavaScript само во именскиот простор МедијаВики: или како корисничка потстраница"
 }
index 4738e1a..901ca80 100644 (file)
        "prefs-editor": "എഡിറ്റർ",
        "prefs-preview": "എങ്ങനെയുണ്ടെന്ന് കാണൽ",
        "prefs-advancedrc": "വിപുലമായ ഉപാധികൾ",
-       "prefs-opt-out": "പുതുക്കലുകൾ ഒഴിവാക്കുക",
        "prefs-advancedrendering": "വിപുലമായ ഉപാധികൾ",
        "prefs-advancedsearchoptions": "വിപുലമായ ഉപാധികൾ",
        "prefs-advancedwatchlist": "വിപുലമായ ഉപാധികൾ",
index 35d8d01..e1c7db0 100644 (file)
        "watchlistedit-normal-done": "Í-keng uì lí ê kám-sī-toaⁿ soá {{PLURAL:$1|ia̍h}} cháu:",
        "watchlisttools-edit": "Khoàⁿ koh kái kàm-sī-toaⁿ",
        "watchlisttools-raw": "Kái chhiⁿ ê kàm-sī-toaⁿ",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|thó-lūn]])",
        "duplicate-defaultsort": "'''Thê-chhíⁿ lí:'''Siat-piān ê pâi-lia̍t hong-sek \"$2\" thè-oāⁿ chìn-chêng ê siat-piān ê pâi-lia̍t hong-sek \"$1\".",
        "version": "Pán-pún",
        "specialpages": "Te̍k-sû-ia̍h",
index efd9af2..3c05a60 100644 (file)
        "prefs-editor": "Editore",
        "prefs-preview": "Anteprimma",
        "prefs-advancedrc": "Opziune avanzate",
-       "prefs-opt-out": "Stuta miglioramente",
        "prefs-advancedrendering": "Opziune avanzate",
        "prefs-advancedsearchoptions": "Opziune avanzate",
        "prefs-advancedwatchlist": "Opziune avanzate",
        "rcfilters-filter-watchlist-notwatched-label": "Nun sta ncopp'ê ppaggene cuntrullate",
        "rcfilters-filtergroup-lastRevision": "Ùrdeme verziune",
        "rcfilters-filter-lastrevision-label": "Verzione 'e mmo",
+       "rcfilters-watchlist-markseen-button": "Segna tutt'ê cagni comme visti",
        "rcfilters-watchlist-edit-watchlist-button": "Càgna 'e lista tuia d'ê paggene cuntrullate",
+       "rcfilters-watchlist-showupdated": "'E càgne 'e ppaggene ca nun hê visto songo signati 'n <strong>niro</strong> e c'ê ppalluccelle chiene.",
+       "rcfilters-target-page-placeholder": "Scrivi 'o nomme 'e na paggene (o na categuria)",
        "rcnotefrom": "Ccà abbascio {{PLURAL:$5|è alencato 'o cagnamiento appurtato|song' alincate 'e cagnamiente appurtate}} 'a <strong>$3, $4</strong> (mmustate nfin'a <strong>$1</strong>).",
        "rclistfrom": "Faje vedé 'e cagnamiénte fatte a partì 'a $3 $2",
        "rcshowhideminor": "$1 'e cagnamiénte piccerille",
        "uploadstash-refresh": "Agghiuorna l'elenco d' 'e file",
        "uploadstash-thumbnail": "vide miniatura",
        "uploadstash-exception": "Nun s'è pututo sarvà 'a càrreca dint' 'a stash ($1): \"$2\".",
+       "uploadstash-bad-path-unknown-type": "Tipo \"$1\" scanosciuto",
+       "uploadstash-bad-path-bad-format": "'A chiave \"$1\" nun sta scritta bona.",
+       "uploadstash-file-not-found": "N'aggio truvato 'a chiave \"$1\".",
+       "uploadstash-file-not-found-no-thumb": "Nun pozzo fà 'a fiùrella.",
+       "uploadstash-file-not-found-no-remote-thumb": "N'aggio truvato 'a figurella: $1 URL = $2",
        "invalid-chunk-offset": "Distanza d' 'a parte nun valida",
        "img-auth-accessdenied": "Acciesso negato",
        "img-auth-nopathinfo": "PATH_INFO mancante.\n'O server nun è mpustato pe' passà sta nfurmazione.\nPuò darse ca, essenno basato ncopp'a CGI, nun putesse suppurtà img_auth.\nVide https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "http-timed-out": "Richieste HTTP fore tiempo.",
        "http-curl-error": "Errore analizzanno l'URL: $1",
        "http-bad-status": "C'è stato nu probblema pe' tramente ca se faceva 'a richiesta HTTP: $1, $2",
+       "http-internal-error": "Errore interno HTTP.",
        "upload-curl-error6": "Nun se riesce 'arrevà a l'URL",
        "upload-curl-error6-text": "A l'URL c'avete scritto nun se può arrevà.\nPe' piacere, cuntrullate ca l'URL è curretta e ca 'o sito è appicciato.",
        "upload-curl-error28": "Fore tiempo p' 'a carreca",
        "listfiles_size": "Dimenzione",
        "listfiles_description": "Descrizzione",
        "listfiles_count": "Verziune",
-       "listfiles-show-all": "Nclude 'e verziune viecchie 'e ll'immaggene",
+       "listfiles-show-all": "Nclude 'e verziune viecchie 'e ffiùre",
        "listfiles-latestversion": "Verzione 'e mo",
        "listfiles-latestversion-yes": "Sì",
        "listfiles-latestversion-no": "No",
        "apisandbox-dynamic-error-exists": "Nu parametro denommenato \"$1\" esiste già.",
        "apisandbox-deprecated-parameters": "Parametri obsoleti",
        "apisandbox-fetch-token": "Auto-ghienche 'o token",
+       "apisandbox-add-multi": "Azzecca",
        "apisandbox-submit-invalid-fields-title": "Cocche campo nun è buono",
        "apisandbox-submit-invalid-fields-message": "Pe' piacere curriggite 'e campe nzegnàte e tentate n'ata vota.",
        "apisandbox-results": "Rezurtate",
        "apisandbox-loading-results": "Ricezione d' 'e risultate 'e ll'API 'ncurzo...",
        "apisandbox-results-error": "N'errore cumparette pe' tramente ca se steva carrecanno na risposta 'e query API: $1.",
        "apisandbox-request-url-label": "URL addimannata:",
+       "apisandbox-request-json-label": "Spiata JSON:",
        "apisandbox-request-time": "Tiempo addimannato: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Curregge 'e token e manna n'ata vota",
        "apisandbox-results-fixtoken-fail": "Scassaje a se piglià 'o token \"$1\".",
        "apisandbox-alert-field": "'O valore int'a stu campo nun è valido.",
        "apisandbox-continue": "Annanze",
        "apisandbox-continue-clear": "Pulezza",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries continuarrà] l'urtima spiata; {{int:apisandbox-continue-clear}} pulezzarrà 'e parametri pe 'i annanzi.",
+       "apisandbox-param-limit": "Scrivi <kbd>max</kbd> p'ausà 'o limmete massimo.",
        "apisandbox-multivalue-all-namespaces": "$1 (Tutt'ê namespace)",
        "apisandbox-multivalue-all-values": "$1 (Tutt'ê valuri)",
        "booksources": "Funte libbrarie",
        "booksources-search": "Ascìa",
        "booksources-text": "Ccà abbascio ce sta na lista 'e cullegamiente a l'ati site ca venneno libbre nuove e viecchie, ca putessero pure avé cchiù nfurmaziune ncopp' 'e libbre ca jate ascianno:",
        "booksources-invalid-isbn": "L'ISBN c'avete miso nun pare bbuono; cuntrolla si ce sta cocch'errore quanno stavate cupianno stu nummero d' 'a fonte origginale.",
+       "magiclink-tracking-rfc": "Paggene c'ausano jonte RFC affattorate",
+       "magiclink-tracking-rfc-desc": "Sta paggena ausa jonte RFC affattorate. Vire [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] p' 'a migrazione.",
+       "magiclink-tracking-pmid": "Paggene c'ausano jonte RMID affattorate",
+       "magiclink-tracking-pmid-desc": "Sta paggena ausa jonte PMID affattorate. Vire [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] p' 'a migrazione.",
+       "magiclink-tracking-isbn": "Paggene c'ausano jonte ISBN affattorate",
+       "magiclink-tracking-isbn-desc": "Sta paggena ausa jonte ISBN affattorate. Vire [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] p' 'a migrazione.",
        "specialloguserlabel": "Mplementatore:",
        "speciallogtitlelabel": "Destinazione (titolo o {{ns:user}}:cunto utente pe' ll'utente):",
        "log": "Logs",
        "cachedspecial-refresh-now": "Vide l'urdeme.",
        "categories": "Categurìe",
        "categories-submit": "Faje vedé",
-       "categoriespagetext": "{{PLURAL:$1|'A categurìa 'nnecata 'e seguito cuntiene|'E categurìe 'nnecate 'e seguito cuntengono}} paggene o file multimediale.\n'E [[Special:UnusedCategories|categurìe vuote]] nun song mostrate ccà.\nVere anche 'e [[Special:WantedCategories|categurìe richieste]].",
+       "categoriespagetext": "{{PLURAL:$1|'A categurìa 'nnecata 'e seguito esiste|'E categurìe 'nnecate 'e seguito esistono}} ncopp'a sta wiki, ca s'ausano o no.\nVire purzì 'e [[Special:WantedCategories|categurìe richieste]].",
        "categoriesfrom": "Fà vedè 'e categurìe partenno 'a:",
        "deletedcontributions": "Contribbute utente scancellate",
        "deletedcontributions-title": "Contribbute utente scancellate",
        "activeusers-intro": "Chest'è n'elenco d'utente c'hanno fatto cierti tipe d'attività nfin'a $1 {{PLURAL:$1|juorno|ghiuorne}} fa.",
        "activeusers-count": "$1 {{PLURAL:$1|cagnamiento|cagnamiente}} int'a l'urdeme {{PLURAL:$3|ghiuorne}}",
        "activeusers-from": "Fà vedè l'utente partenno 'a:",
+       "activeusers-groups": "Fa verè l'utenti ca stanno int'ê gruppi:",
+       "activeusers-excludegroups": "Nun fa verè ll'utenti che stanno int'ê gruppi:",
        "activeusers-noresult": "Nisciun'utente truvato.",
        "activeusers-submit": "Mmusta cunte attive",
        "listgrouprights": "Deritte d' 'e gruppe utente",
        "emailccsubject": "Copia d' 'a mmasciata tua 'a $1: $2",
        "emailsent": "Mmasciata e-mail mannata",
        "emailsenttext": "'A mmasciata d' 'a toja s'è mannata.",
-       "emailuserfooter": "Chista mmasciata e-mail è stata {{GENDER:$1|mannata}} 'a $1 a {{GENDER:$2|$2}} p' 'a funziona \"{{int:emailuser}}\" 'e {{SITENAME}}.",
+       "emailuserfooter": "Chista mmasciata e-mail venette {{GENDER:$1|mannata}} 'a $1 a {{GENDER:$2|$2}} p' 'a funziona \"{{int:emailuser}}\" 'e {{SITENAME}}. Si {{GENDER:$2|ttu}} risponni a st'e-mail, l'e-mail {{GENDER:$2|toia}} sarrà mannata a {{GENDER:$1|chi t'ha scritto}}, mustranno 'o 'ndirizzo 'e posta {{GENDER:$2|tuoio}} a {{GENDER:$1|}}.",
        "usermessage-summary": "Lassanno na mmasciata 'e sistema.",
        "usermessage-editor": "Mmasciatore d' 'o sistema",
        "watchlist": "Paggene cuntrullate",
        "enotif_body_intro_moved": "'A paggena $1 'e {{SITENAME}} è stata cagnata 'e posto ncopp'a $PAGEEDITDATE 'a {{gender:$2|$2}}, vedite $3 p' 'a verzione 'e mo.",
        "enotif_body_intro_restored": "'A paggena $1 'e {{SITENAME}} è stata arripigliata ncopp'a $PAGEEDITDATE 'a {{gender:$2|$2}}, vedite $3 p' 'a verzione 'e mo.",
        "enotif_body_intro_changed": "'A paggena $1 'e {{SITENAME}} è stata cagnata ncopp'a $PAGEEDITDATE 'a {{gender:$2|$2}}, vedite $3 p' 'a verzione 'e mo.",
-       "enotif_lastvisited": "Vedite $1 pe' tutt' 'e cagnamiente 'a ll'urdema visita vuosta.",
-       "enotif_lastdiff": "Vedite $1 pe' vedè stu cagnamiento.",
+       "enotif_lastvisited": "Vedite $1 pe' tutt' 'e cagnamiente 'a ll'urdema visita vuosta",
+       "enotif_lastdiff": "Pe vedè stu cagnamiento, vire $1.",
        "enotif_anon_editor": "Utente anonimo $1",
        "enotif_body": "Caro $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nRiepilego 'e cagnamiente: $PAGESUMMARY $PAGEMINOREDIT\n\nCuntattate l'autore:\ne-mail: $PAGEEDITOR_EMAIL\nncopp' 'o sito: $PAGEEDITOR_WIKI\n\nNun se mannarranno ati notifiche si facite cocch'at'attività senza venì a sta paggena.\nPutite pure cagnà 'e mpustaziune 'e notifeca pe' tutt' 'e paggene cuntrullate dint' 'a l'elenco.\n\nStatteve Bbuon, 'o sistema 'e notifiche ncopp' 'a {{SITENAME}} vuosto\n\n--\nPe' cagnà 'e mpustaziune d' 'e notifiche 'e mmasciate elettroniche, jate ccà: {{canonicalurl:{{#special:Preferences}}}}\n\nPe' cagnà 'e mpustaziune 'e l'elenco 'e paggene cuntrullate vuoste jate ccà: {{canonicalurl:{{#special:EditWatchlist}}}}\n\nPe' scancellà l'elenco 'e paggene cuntrullate vedite $UNWATCHURL\n\nSegnalaziune e at'assistenze:\n$HELPPAGE",
        "enotif_minoredit": "Chisto è nu cagnamiénto piccerillo",
        "modifiedarticleprotection": "'o livello 'e prutezione è stato cagnato pe' \"[[$1]]\"",
        "unprotectedarticle": "sprutetto 'a \"[[$1]]\"",
        "movedarticleprotection": "'mpustaziune 'e protezzione spustate 'a \"[[$2]]\" a \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Pruteggette}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Cagnaje 'a prutezione}} pe \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Levaie 'a protezione}} 'a \"[[$1]]\"",
        "protect-title": "Cagna 'o livello 'e prutezione pe' \"[[$1]]\"",
        "protect-title-notallowed": "Fà vedé 'o livello 'e prutezione pe' \"$1\"",
        "prot_1movedto2": "ha spustato [[$1]] a [[$2]]",
        "uctop": "attuale",
        "month": "D' 'o mese (e pure cchiù primma):",
        "year": "'E ll'anno (e primma):",
+       "date": "'A data (e tanno)",
        "sp-contributions-newbies": "Mosta solo 'e contribbute dde nove utente",
        "sp-contributions-newbies-sub": "Pe' l'utente nuove",
        "sp-contributions-newbies-title": "Contribbute 'a l'utente nuove",
        "sp-contributions-blocklog": "blocche",
        "sp-contributions-suppresslog": "contribbute utente scancellate",
-       "sp-contributions-deleted": "contribbute d'utente scancellate",
+       "sp-contributions-deleted": "contribbute 'e l'{{GENDER:$1|utente}} scancellate",
        "sp-contributions-uploads": "carreche",
        "sp-contributions-logs": "riggistre",
        "sp-contributions-talk": "Chiàcchiera",
index 82efe94..bf2be0c 100644 (file)
        "passwordtooshort": "Passord må ha minst {{PLURAL:$1|ett tegn|$1 tegn}}.",
        "passwordtoolong": "Passord kan ikke overskride {{PLURAL:$1|1 character|$1 characters}}.",
        "passwordtoopopular": "Hyppig brukte passord kan ikke brukes. Vennligst bruk et mer unikt passord.",
+       "passwordinlargeblacklist": "Passordet du skrev inn er på en liste over veldig vanlige passord. Velg et mer unikt passord.",
        "password-name-match": "Passord og brukernavn kan ikke være det samme.",
        "password-login-forbidden": "Bruken av dette brukernavnet og passordet er forbudt.",
        "mailmypassword": "Tilbakestill passord",
        "prefs-editor": "Tekstbehandling",
        "prefs-preview": "Forhåndsvisning",
        "prefs-advancedrc": "Avanserte alternativ",
-       "prefs-opt-out": "Velg å ikke få forbedret utgave",
        "prefs-advancedrendering": "Avanserte alternativer",
        "prefs-advancedsearchoptions": "Avanserte alternativer",
        "prefs-advancedwatchlist": "Avanserte alternativer",
        "rcfilters-watchlist-markseen-button": "Merk alle endringer som sett.",
        "rcfilters-watchlist-edit-watchlist-button": "Rediger listen over sider du overvåker",
        "rcfilters-watchlist-showupdated": "Endringer til sider du ikke har besøkt siden endringene ble gjort vises med <strong>fet</strong> skrift.",
-       "rcfilters-preference-label": "Skjul den forbedrede versjonen av siste endringer",
-       "rcfilters-preference-help": "Fjerner grensesnittendringen fra 2017 og alle verktøyene som ble lagt fra og med da.",
-       "rcfilters-watchlist-preference-label": "Skjul den forbedrede versjonen av overvåkningslisten",
-       "rcfilters-watchlist-preference-help": "Ruller tilbake det omarbeidede grensesnittet fra 2017 og alle verktøy som ble lagt til da og etterpå.",
+       "rcfilters-preference-label": "Bruk grensesnitt uten JavaScript",
+       "rcfilters-preference-help": "Laster siste endringer uten filtre eller markeringsfunksjonalitet.",
+       "rcfilters-watchlist-preference-label": "Bruk grensesnitt uten JavaScript",
+       "rcfilters-watchlist-preference-help": "Laster overvåkningslisten uten filtre eller markeringsfunksjonalitet.",
        "rcfilters-filter-showlinkedfrom-label": "Vis endringer på sider som lenkes fra",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Sider som lenkes fra</strong> den valgte siden",
        "rcfilters-filter-showlinkedto-label": "Vis endringer på sider som lenker til",
        "logentry-block-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingen av {{GENDER:$4|$3}} med en utløpstid på $5 $6",
        "logentry-partialblock-block": "$1 {{GENDER:$2|blokkerte}} {{GENDER:$4|$3}} fra å redigere {{PLURAL:$8|siden|sidene}} $7 med en utløpstid på $5 $6",
        "logentry-partialblock-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingene for {{GENDER:$4|$3}} og forhindret redigeringen av {{PLURAL:$8|siden|sidene}} $7 med en utløpstid på $5 $6",
-       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blokkerte}} {{GENDER:$4|$3}} fra handlinger som ikke er redigering med en utløpstid på $5 $6",
-       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingene for {{GENDER:$4|$3}} for handlinger som ikke er redigering med en utløpstid på $5 $6",
+       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blokkerte}} {{GENDER:$4|$3}} fra visse handlinger som ikke er redigering med en utløpstid på $5 $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingene for {{GENDER:$4|$3}} for visse handlinger som ikke er redigering med en utløpstid på $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|blokkerte}} {{GENDER:$4|$3}} med en utløpstid på $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingen for {{GENDER:$4|$3}} med en utløpstid på $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importert}} $3 gjennom filopplastning",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Passordet kan ikke matche spesifikt svartelistede passord",
        "passwordpolicies-policy-maximalpasswordlength": "Passordet kan maksimalt være på $1 {{PLURAL:$1|tegn}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Passordet kan ikke være {{PLURAL:$1|det populære passordet|i lista over $1 populære passord}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Passord kan ikke være i listen over de vanligste 100&nbsp;000 passordene.",
        "easydeflate-invaliddeflate": "Det gitte innholdet er ikke riktig komprimert",
        "unprotected-js": "Av sikkerhetsårsaker kan ikke JavaScript lastes fra ubeskyttede sider. Bare skap JavaScript i MediaWiki-navnerommet eller som en brukerunderside"
 }
index e47a88c..52db680 100644 (file)
        "prefs-editor": "Tekstverwerker",
        "prefs-preview": "Voorvertoning",
        "prefs-advancedrc": "Gevorderde instellingen",
-       "prefs-opt-out": "Niet deelnemen aan verbeteringen",
        "prefs-advancedrendering": "Gevorderde instellingen",
        "prefs-advancedsearchoptions": "Gevorderde instellingen",
        "prefs-advancedwatchlist": "Gevorderde instellingen",
        "rcfilters-savedqueries-apply-label": "Filter aanmaken",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Standaard filter aanmaken",
        "rcfilters-savedqueries-cancel-label": "Annuleren",
-       "rcfilters-savedqueries-add-new-title": "Huidige filter instellingen opslaan",
+       "rcfilters-savedqueries-add-new-title": "Huidige filterinstellingen opslaan",
        "rcfilters-savedqueries-already-saved": "Deze filters zijn al opgeslagen. Wijzig uw instellingen om een nieuw Filter op te slaan.",
        "rcfilters-restore-default-filters": "Standaard filters terugzetten",
        "rcfilters-clear-all-filters": "Alle filters verwijderen",
index f10f482..2b6a657 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Apercebut",
        "prefs-advancedrc": "Opcions avançadas",
-       "prefs-opt-out": "Refusar los melhoraments",
        "prefs-advancedrendering": "Opcions avançadas",
        "prefs-advancedsearchoptions": "Opcions avançadas",
        "prefs-advancedwatchlist": "Opcions avançadas",
index 9184978..7b13c9d 100644 (file)
        "prefs-editor": "Edytor",
        "prefs-preview": "Podgląd",
        "prefs-advancedrc": "Zaawansowane",
-       "prefs-opt-out": "Rezygnacja z ulepszeń",
        "prefs-advancedrendering": "Zaawansowane",
        "prefs-advancedsearchoptions": "Zaawansowane",
        "prefs-advancedwatchlist": "Zaawansowane",
index a7adeb9..9527fb8 100644 (file)
        "prefs-editor": "سمونگر",
        "prefs-preview": "مخليدنه",
        "prefs-advancedrc": "پرمختللې خوښنې",
-       "prefs-opt-out": "د پرمختګونو څخه لرې کول",
        "prefs-advancedrendering": "پرمختللې خوښنې",
        "prefs-advancedsearchoptions": "پرمختللې خوښنې",
        "prefs-advancedwatchlist": "پرمختللې خوښنې",
index c15990f..4af6002 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Pré-visualizar",
        "prefs-advancedrc": "Opções avançadas",
-       "prefs-opt-out": "Excluir melhorias",
        "prefs-advancedrendering": "Opções avançadas",
        "prefs-advancedsearchoptions": "Opções avançadas",
        "prefs-advancedwatchlist": "Opções avançadas",
index 1559cb4..84c33e2 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Antevisão",
        "prefs-advancedrc": "Opções avançadas",
-       "prefs-opt-out": "Excluir de melhoramentos",
        "prefs-advancedrendering": "Opções avançadas",
        "prefs-advancedsearchoptions": "Opções avançadas",
        "prefs-advancedwatchlist": "Opções avançadas",
index 182dc42..26fed94 100644 (file)
        "prefs-editor": "Used in [[Special:Preferences]], tab \"Editing\" ({{int:prefs-editing}}).\n\n{{Identical|Editor}}",
        "prefs-preview": "Used in [[Special:Preferences]], tab \"Editing\".\n{{Identical|Preview}}",
        "prefs-advancedrc": "Used in [[Special:Preferences]], tab \"Recent changes\".\n{{Identical|Advanced options}}",
-       "prefs-opt-out": "Used in [[Special:Preferences]], tabs \"Recent changes\" and \"Watchlist\".",
        "prefs-advancedrendering": "Used in [[Special:Preferences]], tab \"Appearence\".\n{{Identical|Advanced options}}",
        "prefs-advancedsearchoptions": "Used in [[Special:Preferences]], tab \"Search options\".\n{{Identical|Advanced options}}",
        "prefs-advancedwatchlist": "Used in [[Special:Preferences]], tab \"Watchlist\".\n{{Identical|Advanced options}}",
index 7e22928..0053dcc 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Previzualizare",
        "prefs-advancedrc": "Opțiuni avansate",
-       "prefs-opt-out": "Dezactivați îmbunătățirile",
        "prefs-advancedrendering": "Opțiuni avansate",
        "prefs-advancedsearchoptions": "Opțiuni avansate",
        "prefs-advancedwatchlist": "Opțiuni avansate",
index a3b97b9..119ba84 100644 (file)
        "changepassword-throttled": "Tu è pruvate 'nu sacche de vote a trasè.\nPe piacere aspitte $1 apprime de pruvà arrete.",
        "botpasswords": "Password d'u bot",
        "botpasswords-disabled": "Le passuord bot so disabbilitate.",
+       "botpasswords-no-central-id": "Pe ausà 'na passuor bot, a trasè a 'nu utende cendralizzate.",
        "botpasswords-existing": "Passuord de le bot esistende",
        "botpasswords-createnew": "Ccreje 'na passuord nove pu bot",
        "botpasswords-editexisting": "Cange 'na passuord d'u bot ca esiste ggià",
        "prefs-editor": "Cangiatore",
        "prefs-preview": "Andeprime",
        "prefs-advancedrc": "Opzione avanzate",
-       "prefs-opt-out": "Disattivazzione de le miglioraminde",
        "prefs-advancedrendering": "Opzione avanzate",
        "prefs-advancedsearchoptions": "Opzione avanzate",
        "prefs-advancedwatchlist": "Opzione avanzate",
index b34945e..a51e986 100644 (file)
        "passwordtooshort": "Пароль должен состоять не менее, чем из $1 {{PLURAL:$1|символа|символов}}.",
        "passwordtoolong": "Пароль не может содержать более {{PLURAL:$1|1=$1 символа|$1 символов}}.",
        "passwordtoopopular": "Часто выбираемые пароли не могут быть использованы. Пожалуйста, выберите пароль, который сложнее угадать.",
+       "passwordinlargeblacklist": "Введённый пароль является одним из часто используемых. Пожалуйста, выберите другой.",
        "password-name-match": "Введённый пароль должен отличаться от имени участника.",
        "password-login-forbidden": "Использование этого имени участника и пароля запрещено.",
        "mailmypassword": "Сбросить пароль",
        "prefs-editor": "Редактор",
        "prefs-preview": "Предварительный просмотр",
        "prefs-advancedrc": "Расширенные настройки",
-       "prefs-opt-out": "Отказ от улучшений",
        "prefs-advancedrendering": "Расширенные настройки",
        "prefs-advancedsearchoptions": "Расширенные настройки",
        "prefs-advancedwatchlist": "Расширенные настройки",
        "tooltip-whatlinkshere-invert": "Установите этот флажок, чтобы Скрыть ссылки от страниц в выбранном пространстве имен.",
        "namespace_association": "Связанное пространство",
        "tooltip-namespace_association": "Установите эту отметку, чтобы также включить пространство имён обсуждения (или предметное), связанное с выбранным пространством имён",
-       "blanknamespace": "(основное)",
+       "blanknamespace": "(Ð\9eсновное)",
        "contributions": "Вклад {{GENDER:$1|участника|участницы}}",
        "contributions-title": "Вклад {{GENDER:$1|участника|участницы}} $1",
        "mycontris": "Вклад",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль не может совпадать ни с одним паролем, внесённым в чёрный список",
        "passwordpolicies-policy-maximalpasswordlength": "Пароль должен быть короче $1 {{PLURAL:$1|символа|символов}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Пароль не может соответствовать {{PLURAL:$1|самому часто используемому паролю|какому-либо из $1 самых часто используемых паролей}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Пароль не может соответствовать какому-либо из 100 000 самых часто используемых паролей.",
        "easydeflate-invaliddeflate": "Предоставленное содержимое не спущено надлежащим образом",
        "unprotected-js": "По соображениям безопасности JavaScript нельзя загружать с незащищенных страниц. Пожалуйста, создавайте скрипты только в пространстве имён MediaWiki: или как подстраницы участника."
 }
index 6e8fad7..790adba 100644 (file)
        "prefs-editor": "Эрэдээктэр",
        "prefs-preview": "Инники көрүү",
        "prefs-advancedrc": "Дириҥэтиллибит туруоруулар",
-       "prefs-opt-out": "Тупсарыыттан батыныы",
        "prefs-advancedrendering": "Дириҥэтиллибит туруоруулар",
        "prefs-advancedsearchoptions": "Дириҥэтиллибит туруоруулар",
        "prefs-advancedwatchlist": "Дириҥэтиллибит туруоруулар",
index 8f166b7..dcbd6f7 100644 (file)
        "grant-uploadfile": "လူတ်ႇၶိုၼ်ႈ ၾၢႆႇဢၼ်မႂ်ႇ",
        "grant-basic": "သုၼ်ႇပိုၼ်ႉထၢၼ်",
        "grant-viewdeleted": "တူၺ်း ၾၢႆႇလႄႈ ၼႃႈလိၵ်ႈ ၸိူဝ်းမွတ်ႇပႅတ်ႈယဝ်ႉ။",
-       "grant-viewmywatchlist": "တူၺ်း သဵၼ်ႈမၢႆပႂ်ႉတူၺ်း ႁင်းၶွင်ၵဝ်ႇ",
+       "grant-viewmywatchlist": "á\80\90á\80°á\81ºá\80ºá\80¸ á\80\9eá\80µá\81¼á\80ºá\82\88á\80\99á\81¢á\82\86á\80\95á\82\82á\80ºá\82\89á\80\90á\80°á\81ºá\80ºá\80¸ á\82\81á\80\84á\80ºá\80¸á\81¶á\80½á\80\84á\80ºá\81¸á\80\9dá\80ºá\82\88á\81µá\80\9dá\80ºá\82\87",
        "newuserlogpage": "သၢႆမၢႆလွင်ႈၵေႃႇသၢင်ႈ ၽူႈၸႂ်ႉတိုဝ်း",
        "newuserlogpagetext": "ဢၼ်ၼႆႉပဵၼ် သဵၼ်ႈမၢႆ လွင်ႈၵေႃႇသၢင်ႈ ၽူႈၸႂ်ႉတိုဝ်း။",
        "rightslog": "သဵၼ်ႈမၢႆ သုၼ်ႇလႆႈ ၽူႈၸႂ်ႉတိုဝ်း",
index 1890bf8..cf33426 100644 (file)
        "prefs-editor": "Používateľ",
        "prefs-preview": "Náhľad",
        "prefs-advancedrc": "Rozšírené možnosti",
-       "prefs-opt-out": "Nepoužívať vylepšenia",
        "prefs-advancedrendering": "Rozšírené možnosti",
        "prefs-advancedsearchoptions": "Rozšírené možnosti",
        "prefs-advancedwatchlist": "Rozšírené možnosti",
index d3fa68b..5c13b34 100644 (file)
        "prefs-editor": "Urejevalnik",
        "prefs-preview": "Predogled",
        "prefs-advancedrc": "Napredne možnosti",
-       "prefs-opt-out": "Izključite se iz izboljšav",
        "prefs-advancedrendering": "Napredne možnosti",
        "prefs-advancedsearchoptions": "Napredne možnosti",
        "prefs-advancedwatchlist": "Napredne možnosti",
index edcb84a..7c52923 100644 (file)
        "passwordtooshort": "Лозинка мора имати најмање {{PLURAL:$1|један знак|$1 знака|$1 знакова}}.",
        "passwordtoolong": "Лозинке не могу бити дуже од {{PLURAL:$1|$1 знака|$1 знакова}}.",
        "passwordtoopopular": "Није могуће користити често одабране лозинке. Одаберите лозинку коју је теже погодити.",
+       "passwordinlargeblacklist": "Унесена лозинка је на листи веома често коришћених лозинки. Одаберите јединственију лозинку.",
        "password-name-match": "Лозинка се мора разликовати од корисничког имена.",
        "password-login-forbidden": "Коришћење овог корисничког имена и лозинке је забрањено.",
        "mailmypassword": "Ресетуј лозинку",
        "prefs-editor": "Уређивач",
        "prefs-preview": "Претпреглед",
        "prefs-advancedrc": "Напредне опције",
-       "prefs-opt-out": "Онемогућавање побољшања",
        "prefs-advancedrendering": "Напредне опције",
        "prefs-advancedsearchoptions": "Напредне опције",
        "prefs-advancedwatchlist": "Напредне опције",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Лозинка се не може подударати са лозинкама на црном списку",
        "passwordpolicies-policy-maximalpasswordlength": "Лозинка мора да буде краћа од $1 {{PLURAL:$1|знака|знакова}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Лозинка не може да буде {{PLURAL:$1|популарна лозинка|на списку $1 популарних лозинки}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Лозинка не може да буде на листи 100.000 најчешће коришћених лозинки.",
        "unprotected-js": "Из безбедносних разлога, JavaScript не може да се учита са незаштићене странице. Само направите JavaScript у именском простору „Медијавики:” или као корисничку подстраницу"
 }
index eae87b8..51c385c 100644 (file)
        "prefs-editor": "Uređivač",
        "prefs-preview": "Pretpregled",
        "prefs-advancedrc": "Napredne opcije",
-       "prefs-opt-out": "Onemogućavanje poboljšanja",
        "prefs-advancedrendering": "Napredne opcije",
        "prefs-advancedsearchoptions": "Napredne opcije",
        "prefs-advancedwatchlist": "Napredne opcije",
index 57a0005..c7aec27 100644 (file)
        "prefs-editor": "Éditor",
        "prefs-preview": "Pratayang",
        "prefs-advancedrc": "Pilihan lengkep",
-       "prefs-opt-out": "Nyisihkeun ropéaan",
        "prefs-advancedrendering": "Pilihan lengkep",
        "prefs-advancedsearchoptions": "Pilihan lengkep",
        "prefs-advancedwatchlist": "Pilihan lengkep",
index 401459c..8e3fd94 100644 (file)
        "passwordtooshort": "Lösenord måste innehålla minst {{PLURAL:$1|$1 tecken}}.",
        "passwordtoolong": "Lösenord kan inte vara längre än {{PLURAL:$1|1 tecken|$1 tecken}}.",
        "passwordtoopopular": "Vanliga lösenord kan inte användas. Välj ett lösenord som är svårare att gissa.",
+       "passwordinlargeblacklist": "Det angivna lösenordet är med i en lista över mycket vanliga lösenord. Välj ett unikare lösenord.",
        "password-name-match": "Ditt lösenord måste vara olikt ditt användarnamn.",
        "password-login-forbidden": "Användningen av dessa användarnamn och lösenord har förbjudits.",
        "mailmypassword": "Återställ lösenord",
        "prefs-editor": "Redigerare",
        "prefs-preview": "Förhandsvisa",
        "prefs-advancedrc": "Avancerade alternativ",
-       "prefs-opt-out": "Välj bort förbättringar",
        "prefs-advancedrendering": "Avancerade alternativ",
        "prefs-advancedsearchoptions": "Avancerade alternativ",
        "prefs-advancedwatchlist": "Avancerade alternativ",
        "rcfilters-watchlist-markseen-button": "Markera alla ändringar som sedda",
        "rcfilters-watchlist-edit-watchlist-button": "Redigera din lista över bevakade sidor",
        "rcfilters-watchlist-showupdated": "Sidor som har ändrats sedan ditt senaste besök visas i <strong>fetstil</strong> med färgmarkering.",
-       "rcfilters-preference-label": "Dölj den förbättrade versionen av Senaste ändringar",
-       "rcfilters-preference-help": "Stänger det nydesignade gränssnittet från 2017 och alla verktyg som lades till från och med då.",
-       "rcfilters-watchlist-preference-label": "Dölj det förbättrade versionen av bevakningslistan",
-       "rcfilters-watchlist-preference-help": "Rullar tillbaka det omdesignade gränssnittet från 2017 och alla verktyg som lades till då och efteråt.",
+       "rcfilters-preference-label": "Använd gränssnitt som inte använder JavaScript",
+       "rcfilters-preference-help": "Läser in senaste ändringarna utan filter eller markeringsfunktionalitet.",
+       "rcfilters-watchlist-preference-label": "Använd gränssnitt som inte använder JavaScript",
+       "rcfilters-watchlist-preference-help": "Läser in bevakningslistan utan filter eller markeringsfunktionalitet.",
        "rcfilters-filter-showlinkedfrom-label": "Visa ändringar på sidor som länkas från",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Sidor som länkas från</strong> den valda sidan",
        "rcfilters-filter-showlinkedto-label": "Visa ändringar på sidor som länkar till",
        "logentry-block-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningar för {{GENDER:$4|$3}} med en varaktighet på $5 $6",
        "logentry-partialblock-block": "$1 {{GENDER:$2|blockerade}} {{GENDER:$4|$3}} från att redigera {{PLURAL:$8||sidorna}} $7 med en varaktighet på $5 $6",
        "logentry-partialblock-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningarna för {{GENDER:$4|$3}} som förhindrar redigeringar på {{PLURAL:$8||sidorna}} $7 med en varaktighet på $5 $6",
-       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blockerade}} {{GENDER:$4|$3}} från icke-redigerande handlingar med en varaktighet på $5 $6",
-       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningarna för {{GENDER:$4|$3}} för icke-redigerande handlingar med en varaktighet på $5 $6",
+       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blockerade}} {{GENDER:$4|$3}} från specificerade icke-redigerande handlingar med en varaktighet på $5 $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningarna för {{GENDER:$4|$3}} för specificerade icke-redigerande handlingar med en varaktighet på $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|blockerade}} {{GENDER:$4|$3}} med en varaktighet på $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningar för {{GENDER:$4|$3}} med en varaktighet på $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importerade}} $3 genom filuppladdning",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Lösenordet kan inte matcha specifikt svartlistade lösenord",
        "passwordpolicies-policy-maximalpasswordlength": "Lösenordet måste vara högst $1 {{PLURAL:$1|tecken}} långt",
        "passwordpolicies-policy-passwordcannotbepopular": "Lösenordet kan inte vara {{PLURAL:$1|det populäraste lösenordet|i listan över de $1 populäraste lösenorden}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Lösenordet kan inte vara med i listan över de 100 000 vanligaste lösenorden.",
        "easydeflate-invaliddeflate": "Innehåll som tillhandahålls är inte helt komprimerat",
        "unprotected-js": "Av säkerhetsskäl kan inte JavaScript läsas in från oskyddade sidor. Skapa endast JavaScript i namnrymden MediaWiki: eller som en användarundersida."
 }
index fa77b2b..f22f0f5 100644 (file)
        "wrongpasswordempty": "ಖಾಲಿ ಪ್ರವೇಶ ಪದ ಕೊರ್ತರ್. ನನ ಒರ ಪ್ರಯತ್ನ ಮಲ್ಪುಲೆ.",
        "passwordtooshort": "ಪ್ರವೇಶ ಪದಟ್ ಕನಿಷ್ಟ {{PLURAL:$1|೧ ಅಕ್ಷರ|$1 ಅಕ್ಷರರೊಳೆನ್}} ಉಪ್ಪೊಡ್",
        "passwordtoolong": "ಪ್ರವೇಸೊ ಪದೊಟು ಕನಿಸ್ಟೊ {{PLURAL:$1|೧ ಅಕ್ಷರ|$1 ಅಕ್ಷರರೊಲು}} ಉಪ್ಪೊಡ್",
+       "passwordinlargeblacklist": "ಸೇರಾಯಿನ ಪ್ರವೇಶಪದ ಅತಿ ಸಾಮಾನ್ಯವಾದ್ ಬಳಕೆ ಮಲ್ಪುನ ಪ್ರವೇಶಪದೊಕುಲೆನ ಒಂಜಿ ಪಟ್ಟಿಡ್ ಉಂಡು.ದಯಮಲ್ತ್ ಬೇತೆ ಅನನ್ಯ ಪ್ರವೇಶಪದೊನು ಆಯ್ಕೆ ಮಲ್ಪುಲೆ.",
        "password-name-match": "ಇರೆನ್ ಪ್ರವೇಶಪದ ಬಳಕೆದಾರೆನ ಪುದರ್‘ಡ್‘ದ್ ಬೇತೆ ಉಪ್ಪೊಡು",
        "password-login-forbidden": "ಈ ಪ್ರವೇಶಪದ ಬೊಕ್ಕ ಬಳಕೆದಾರೆರೆನ ಪುದರ್‘ನ್ ನಿಷಿದ್ಧ ಮಲ್ತ್‘ದ್ಂಡ್",
        "mailmypassword": "ಪ್ರವೇಸೊ ಪದೊನ್ ಪಿರ ಸ್ತಾಪನೆ ಮಲ್ಪುಲೆ",
        "mw-widgets-usersmultiselect-placeholder": "ನನಾತ್ ಸೇರಲೇ...",
        "date-range-from": "ತಾರಿಕ್‌ಡ್ದ್:",
        "date-range-to": "ತಾರಿಕ್ ಮುಟ:",
-       "randomrootpage": "ಒವ್ವಾಂಡಲ ಮೂಲಪುಟೊ"
+       "randomrootpage": "ಒವ್ವಾಂಡಲ ಮೂಲಪುಟೊ",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "ಪ್ರವೇಶಪದ ಅತಿ ಸಾಮಾನ್ಯವಾದ್ ಬಳಕೆ ಮಲ್ಪುನ ೧೦೦,೦೦೦ ಪದೊಕುಲೆನ ಪಟ್ಟಿಡ್ ಉಪ್ಪರೆ ಬಲ್ಲಿ."
 }
index 7683075..0d8a411 100644 (file)
        "prefs-editor": "రచయిత",
        "prefs-preview": "మునుజూపు",
        "prefs-advancedrc": "ఉన్నత ఎంపికలు",
-       "prefs-opt-out": "మెరుగుదలల నుండి తప్పుకోండి",
        "prefs-advancedrendering": "ఉన్నత ఎంపికలు",
        "prefs-advancedsearchoptions": "ఉన్నత ఎంపికలు",
        "prefs-advancedwatchlist": "ఉన్నత ఎంపికలు",
index b64d777..6856062 100644 (file)
        "prefs-editor": "ตัวแก้ไข",
        "prefs-preview": "การแสดงตัวอย่าง",
        "prefs-advancedrc": "ตัวเลือกขั้นสูง",
-       "prefs-opt-out": "เลือกไม่ปรับปรุง",
        "prefs-advancedrendering": "ตัวเลือกขั้นสูง",
        "prefs-advancedsearchoptions": "ตัวเลือกขั้นสูง",
        "prefs-advancedwatchlist": "ตัวเลือกขั้นสูง",
index aab8a07..e9698e3 100644 (file)
        "prefs-editor": "Editör",
        "prefs-preview": "Önizleme",
        "prefs-advancedrc": "Gelişmiş seçenekler",
-       "prefs-opt-out": "İyileştirmeleri devre dışı bırak",
        "prefs-advancedrendering": "Gelişmiş seçenekler",
        "prefs-advancedsearchoptions": "Gelişmiş seçenekler",
        "prefs-advancedwatchlist": "Gelişmiş seçenekler",
index 63a9e59..015d275 100644 (file)
        "prefs-editor": "Мөхәррир",
        "prefs-preview": "Алдан карау",
        "prefs-advancedrc": "Киңәйтелгән көйләүләр",
-       "prefs-opt-out": "Яхшыртулардан баш тарту",
        "prefs-advancedrendering": "Киңәйтелгән көйләүләр",
        "prefs-advancedsearchoptions": "Киңәйтелгән көйләүләр",
        "prefs-advancedwatchlist": "Киңәйтелгән көйләүләр",
index 6191408..36ddafd 100644 (file)
        "prefs-editor": "Редактор",
        "prefs-preview": "Попередній перегляд",
        "prefs-advancedrc": "Розширені налаштування",
-       "prefs-opt-out": "Відмовитись від покращень",
        "prefs-advancedrendering": "Розширені налаштування",
        "prefs-advancedsearchoptions": "Розширені налаштування",
        "prefs-advancedwatchlist": "Розширені налаштування",
index 0a857dc..1c36714 100644 (file)
        "cantcreateaccount-text": "[[User:$3|$3]] نے اس آئی پی پتہ (<strong>$1</strong>) کی کھاتہ سازی پر پابندی لگا رکھی ہے۔\n\n$3 نے «<em>$2</em>» وجہ بیان کی ہے",
        "cantcreateaccount-range-text": "[[User:$3|$3]] نے <strong>$1</strong> رینج کے آئی پی پتوں پر جس میں آپ کا آئی پی پتہ (<strong>$4</strong>) بھی موجود ہے پر پابندی لگا دی ہے۔\n\n$3 نے «<em>$2</em>» وجہ بیان کی ہے",
        "viewpagelogs": "اس صفحہ کے نوشتے دیکھیں",
-       "nohistory": "اِس صفحہ کیلئے کوئی تدوینی تاریخچہ موجود نہیں ہے.",
+       "nohistory": "اس صفحہ کا ترمیمی تاریخچہ موجود نہیں ہے۔",
        "currentrev": "تازہ ترین نسخہ",
        "currentrev-asof": "حالیہ نسخہ بمطابق $1",
        "revisionasof": "نسخہ بمطابق $1",
        "history-feed-title": "تاریخچہ ترمیم",
        "history-feed-description": "ویکی پر اِس صفحہ کا تاریخچۂ نظرثانی",
        "history-feed-item-nocomment": "بہ $2 $1",
-       "history-feed-empty": "درخواست شدہ صفحہ موجود نہیں.\nیا تو یہ ویکی سے حذف کیا گیا ہے اور یا اِس کا نام تبدیل کردیا گیا ہے.\nآپ متعلقہ نئے صفحات کیلئے [[Special:Search|ویکی پر تلاش]] کرسکتے ہیں.",
+       "history-feed-empty": "درخواست کردہ صفحہ موجود نہیں۔\nممکن ہے کہ اسے ویکی سے حذف کر دیا گیا ہو یا اِس کا نام تبدیل کردیا گیا ہو۔\nآپ متعلقہ نئے صفحات کو [[Special:Search|ویکی پر تلاش]] کرسکتے ہیں۔",
        "history-edit-tags": "منتخب نظرثانیوں کے ٹیگوں میں ترمیم کریں",
        "rev-deleted-comment": "(تبصرہ حذف کی گيا ہے)",
        "rev-deleted-user": "(صارف نام حذف کیا گيا ہے)",
        "prefs-editor": "خانہ ترمیم",
        "prefs-preview": "نمائش",
        "prefs-advancedrc": "اضافی اختیارات",
-       "prefs-opt-out": "اصلاحات سے گریز",
        "prefs-advancedrendering": "اضافی اختیارات",
        "prefs-advancedsearchoptions": "اعلی اختیارات",
        "prefs-advancedwatchlist": "اضافی اختیارات",
index 50cb787..301980c 100644 (file)
        "prefs-editor": "Trình soạn",
        "prefs-preview": "Xem trước",
        "prefs-advancedrc": "Tùy chọn nâng cao",
-       "prefs-opt-out": "Quyết định không sử dụng các cải thiện",
        "prefs-advancedrendering": "Tùy chọn nâng cao",
        "prefs-advancedsearchoptions": "Tùy chọn nâng cao",
        "prefs-advancedwatchlist": "Tùy chọn nâng cao",
index 4253652..569a3c8 100644 (file)
        "prefs-editor": "编辑",
        "prefs-preview": "预览",
        "prefs-advancedrc": "高级选项",
-       "prefs-opt-out": "关闭改进功能",
        "prefs-advancedrendering": "高级选项",
        "prefs-advancedsearchoptions": "高级选项",
        "prefs-advancedwatchlist": "高级选项",
index af948bf..89e8e8d 100644 (file)
        "passwordtooshort": "您的密碼至少需要 $1 個字元。",
        "passwordtoolong": "密碼不能超過 {{PLURAL:$1|1 個字元|$1 個字元}}。",
        "passwordtoopopular": "不能使用普遍選擇的密碼。請選擇更難猜出的密碼",
+       "passwordinlargeblacklist": "所輸入密碼被列在常用密碼的清單裡,請改用較獨特的密碼。",
        "password-name-match": "您的密碼不可以跟使用者名稱相同。",
        "password-login-forbidden": "此使用者名稱和密碼已被禁止使用。",
        "mailmypassword": "重設密碼",
        "prefs-editor": "編輯器",
        "prefs-preview": "預覽",
        "prefs-advancedrc": "進階選項",
-       "prefs-opt-out": "關閉改進功能",
        "prefs-advancedrendering": "進階選項",
        "prefs-advancedsearchoptions": "進階選項",
        "prefs-advancedwatchlist": "進階選項",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "密碼不可以同於被列入黑名單的特定密碼",
        "passwordpolicies-policy-maximalpasswordlength": "密碼必須小於 $1 個{{PLURAL:$1|字元|字元}}長度",
        "passwordpolicies-policy-passwordcannotbepopular": "密碼不可以是{{PLURAL:$1|常用密碼內容|在清單中的編號 $1 常用密碼}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "不能採用列在 100000 個最常用到密碼清單當中的密碼。",
        "easydeflate-invaliddeflate": "提供的內容未被正常的壓縮",
        "unprotected-js": "基於安全因素,JavaScript 不能從未保護的頁面來載入。建立 JavaScript 請僅在 MediaWiki 的:命名空間或使用者子頁面"
 }
index 0bcb2b6..44baa8b 100644 (file)
 
        /**
         * Check if a given namespace is a talk namespace
+        *
+        * See MWNamespace::isTalk in PHP
+        *
         * @param {number} namespaceId Namespace ID
         * @return {boolean} Namespace is a talk namespace
         */
                return !!( namespaceId > NS_MAIN && namespaceId % 2 );
        };
 
+       /**
+        * Check if signature buttons should be shown in a given namespace
+        *
+        * See MWNamespace::wantSignatures in PHP
+        *
+        * @param {number} namespaceId Namespace ID
+        * @return {boolean} Namespace is a signature namespace
+        */
+       Title.wantSignaturesNamespace = function ( namespaceId ) {
+               return this.isTalkNamespace( namespaceId ) ||
+                       mw.config.get( 'wgExtraSignatureNamespaces' ).indexOf( namespaceId ) !== -1;
+       };
+
        /**
         * Whether this title exists on the wiki.
         *
index ecdcc46..b7175d0 100644 (file)
@@ -21,8 +21,7 @@
        }
 
        &:active,
-       &.is-on,
-       &.mw-ui-checked {
+       &.is-on {
                background-color: @activeColor;
                border-color: @activeColor;
                box-shadow: none;
@@ -35,8 +34,7 @@
 
                // Make sure disabled buttons don't have hover and active states
                &:hover,
-               &:active,
-               &.mw-ui-checked {
+               &:active {
                        background-color: @colorGray12;
                        color: #fff;
                        border-color: @colorGray12;
        }
 
        &:active,
-       &.is-on,
-       &.mw-ui-checked {
+       &.is-on {
                background-color: @colorGray12;
                color: @colorGray1;
                border-color: @colorGray7;
                        box-shadow: none;
                }
 
-               &:active,
-               &.mw-ui-checked {
+               &:active {
                        background-color: transparent;
                        color: @colorButtonTextActive;
                        border-color: transparent;
                                color: @colorProgressiveHighlight;
                        }
 
-                       &:active,
-                       &.mw-ui-checked {
+                       &:active {
                                color: @colorProgressiveActive;
                        }
 
                                color: @colorDestructiveHighlight;
                        }
 
-                       &:active,
-                       &.mw-ui-checked {
+                       &:active {
                                color: @colorDestructiveActive;
                        }
 
index e034fec..d65e49a 100644 (file)
@@ -1435,7 +1435,7 @@ Non-word characters don't terminate tag names
 !! end
 
 ###
-### See tests/parser/parserTestsParserHook.php for the <tåg> extension)
+### See tests/parser/ParserTestParserHook.php for the <tåg> extension)
 ### This checks that HTML5 tags (with non-word characters in the tag
 ### name) make it safely through the parser -- the Sanitizer will
 ### munge them later, as it should.
@@ -2834,7 +2834,7 @@ two">hi</pre>
 <pre class="one two">hi</pre>
 
 !! html/parsoid
-<pre typeof="mw:Extension/pre" about="#mwt2" class="one two" data-mw='{"name":"pre","attrs":{"class":"one two"},"body":{"extsrc":"hi"}}'>hi</pre>
+<pre class="one two" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"class":"one two"},"body":{"extsrc":"hi"}}'>hi</pre>
 !! end
 
 !! test
@@ -2869,7 +2869,7 @@ parsoid=wt2html
 <pre>x</pre>
 &lt;pre <table></table>
 !! html/parsoid
-<pre typeof="mw:Transclusion mw:Extension/pre" about="#mwt2" data-parsoid='{"stx":"html","a":{"&lt;pre":null},"sa":{"&lt;pre":""},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre &lt;pre>x&lt;/pre>"}},"i":0}}]}'>x</pre>
+<pre typeof="mw:Extension/pre mw:Transclusion" about="#mwt2" data-parsoid='{"stx":"html","a":{"&lt;pre":null},"sa":{"&lt;pre":""},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre &lt;pre>x&lt;/pre>"}},"i":0}}]}'>x</pre>
 
 <pre data-parsoid='{"stx":"html","src":"&lt;pre &lt;/table>","tagWidths":[13,0],"a":{"&lt;":null,"table":null},"sa":{"&lt;":"","table":""},"fostered":true,"autoInsertedEnd":true}'></pre><table data-parsoid='{"stx":"html","autoInsertedEnd":true}'></table>
 !! end
@@ -3681,7 +3681,7 @@ array (
  <pre class="123">hi</pre>
 
 !! html/parsoid
- <pre typeof="mw:Extension/pre" about="#mwt2" class="123" data-mw='{"name":"pre","attrs":{"class":"123"},"body":{"extsrc":"hi"}}'>hi</pre>
+ <pre class="123" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"class":"123"},"body":{"extsrc":"hi"}}'>hi</pre>
 !! end
 
 !!test
@@ -6273,8 +6273,6 @@ parsoid=wt2html
 
 !! end
 
-# Note that the PHP parser output appears to be broken when the table
-# end tag is not separated by a space from the style attribute
 !! test
 A table with stray table end tags on start tag line (wt2html)
 !! options
@@ -6294,13 +6292,13 @@ parsoid=wt2html
 |foo
 |}
 !! html/php+tidy
-<table style="&quot;color:">
+<table style="color: red;">
 
 </table><table style="color: red;">
 <tbody><tr>
 <td>foo
 </td></tr></tbody></table>
-<table style="&quot;color:" id="foo">
+<table style="color: red;" id="foo">
 <tbody><tr>
 <td>foo
 </td></tr></tbody></table>
@@ -6925,9 +6923,9 @@ Don't break on | in extension attribute in template
 
 <references />
 !! html/parsoid
-<p><sup about="#mwt2" class="mw-ref" id="cite_ref-hi|ho_1-0" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref name=\"hi|ho\">ha&lt;/ref>"}},"i":0}}]}'><a href="./Main_Page#cite_note-hi|ho-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p>
+<p><sup about="#mwt2" class="mw-ref" id="cite_ref-hi|ho_1-0" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref name=\"hi|ho\">ha&lt;/ref>"}},"i":0}}]}'><a href="./Parser_test#cite_note-hi|ho-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-hi|ho-1" id="cite_note-hi|ho-1"><a href="./Main_Page#cite_ref-hi|ho_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-hi|ho-1" class="mw-reference-text">ha</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-hi|ho-1" id="cite_note-hi|ho-1"><a href="./Parser_test#cite_ref-hi|ho_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-hi|ho-1" class="mw-reference-text">ha</span></li></ol>
 !! end
 
 ## We don't support roundtripping of these attributes in Parsoid.
@@ -7100,9 +7098,9 @@ T107652: <ref>s in templates that also generate table cell attributes should be
 <references />
 !! html/parsoid
 <table>
-<tbody><tr><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_7","href":"./Template:Table_attribs_7"},"params":{},"i":0}}]}'>Foo<sup class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></s></td></tr>
+<tbody><tr><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_7","href":"./Template:Table_attribs_7"},"params":{},"i":0}}]}'>Foo<sup class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Parser_test#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></s></td></tr>
 </tbody></table>
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
 !! end
 
 !! test
@@ -8044,6 +8042,8 @@ Link containing % as a double hex sequence interpreted to hex sequence
 ## Example for such a section: == < ==
 !! test
 Link containing "#<" and "#>" % as a hex sequences- these are valid section anchors
+!! options
+title=[[Main Page]]
 !! config
 wgFragmentMode=[ 'html5', 'legacy' ]
 !! wikitext
@@ -8822,6 +8822,8 @@ Interwiki link with fragment (T4130)
 
 !! test
 Link scenarios with escaped fragments
+!! options
+title=[[Main Page]]
 !! config
 wgFragmentMode=[ 'html5', 'legacy' ]
 !! wikitext
@@ -9648,17 +9650,14 @@ Handling html with a div self-closing tag
 <div title=bar />
 <div title=bar/>
 <div title=bar/ >
-!! html/php
-<p>&lt;div title /&gt;
-&lt;div title/&gt;
-</p>
-<div>
-<p>&lt;div title=bar /&gt;
-&lt;div title=bar/&gt;
-</p>
-<div title="bar/"></div>
-</div>
-
+!! html/php+tidy
+<div title=""></div>
+<div title=""></div>
+<div title="">
+<div title="bar"></div>
+<div title="bar"></div>
+<div title="bar/">
+</div></div>
 !! html/parsoid
 <div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
 <div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
@@ -9699,10 +9698,10 @@ Handling html with a br self-closing tag
 <br title=bar />
 <br title=bar/>
 <br title=bar/ >
-!! html/php
+!! html/php+tidy
 <p><br title="" />
 <br title="" />
-<br />
+<br title="" />
 <br title="bar" />
 <br title="bar" />
 <br title="bar/" />
@@ -9717,6 +9716,18 @@ Handling html with a br self-closing tag
 </p>
 !! end
 
+!! test
+Quoted attributes without spaces
+!! options
+parsoid=wt2html
+!! wikitext
+<div class="foo"style="color:red">red</div>
+!! html/php+tidy
+<div class="foo" style="color:red">red</div>
+!! html/parsoid
+<div class="foo" style="color:red">red</div>
+!! end
+
 !! test
 Horizontal ruler (should it add that extra space?)
 !! wikitext
@@ -11024,7 +11035,7 @@ wgRestrictDisplayTitle=false
 <i>Parser test</i>
 
 !! html/parsoid
-<meta property="mw:PageProp/displaytitle" content="Main Page" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"src":"{{DISPLAYTITLE:&#39;&#39;{{PAGENAME}}&#39;&#39;}}"}' data-mw='{"attribs":[[{"txt":"content"},{"html":"DISPLAYTITLE:&lt;i data-parsoid=&#39;{\"dsr\":[15,31,2,2]}&#39;>&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[17,29,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"PAGENAME\",\"function\":\"pagename\"},\"params\":{},\"i\":0}}]}&#39;>Main Page&lt;/span>&lt;/i>"}]]}'/>
+<meta property="mw:PageProp/displaytitle" content="Parser test" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"src":"{{DISPLAYTITLE:&#39;&#39;{{PAGENAME}}&#39;&#39;}}"}' data-mw='{"attribs":[[{"txt":"content"},{"html":"DISPLAYTITLE:&lt;i data-parsoid=&#39;{\"dsr\":[15,31,2,2]}&#39;>&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[17,29,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"PAGENAME\",\"function\":\"pagename\"},\"params\":{},\"i\":0}}]}&#39;>Parser test&lt;/span>&lt;/i>"}]]}'/>
 !! end
 
 # NOTE: mw:ExpandedAttrs is not the best typeof here. mw:Transclusion is better.
@@ -12725,7 +12736,7 @@ array (
 <li><span typeof="mw:Nowiki">foo-{bar}bat</span></li>
 <li><span typeof="mw:Transclusion mw:Nowiki" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;nowiki>foo-{bar}bat&lt;/nowiki>"}},"i":0}}]}'>foo-{bar}bat</span></li>
 <li><pre typeof="mw:Extension/pre" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"foo-{bar}bat"}}'>foo-{bar}bat</pre></li>
-<li><pre typeof="mw:Transclusion mw:Extension/pre" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre>foo-{bar}bat&lt;/pre>"}},"i":0}}]}'>foo-{bar}bat</pre></li>
+<li><pre typeof="mw:Extension/pre mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre>foo-{bar}bat&lt;/pre>"}},"i":0}}]}'>foo-{bar}bat</pre></li>
 </ul>
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"foo-{bar}bat"}}'></pre> <pre typeof="mw:Extension/tag mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;tag>foo-{bar}bat&lt;/tag>"}},"i":0}}]}'></pre>
 !! end
@@ -13647,11 +13658,11 @@ Templates: Wiki Tables: 7. Fosterable <ref>s should get fostered
 
 <references />
 !! html/parsoid
-<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"PartialTable","href":"./Template:PartialTable"},"params":{},"i":0}},"&lt;ref>foo&lt;/ref>\n|}"]}'><sup about="#mwt3" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p><table about="#mwt2">
+<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"PartialTable","href":"./Template:PartialTable"},"params":{},"i":0}},"&lt;ref>foo&lt;/ref>\n|}"]}'><sup about="#mwt3" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Parser_test#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p><table about="#mwt2">
 <tbody>
 </tbody></table>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 !! end
 
 !! test
@@ -13827,6 +13838,7 @@ Parser Functions: 2. Nested use (only outermost should be marked up)
 !! test
 Template nested in extension tag in template
 !! options
+title=[[Main Page]]
 language=zh
 !! wikitext
 {{echo|hi<ref>[[ho|{{echo|hi}}]]</ref>}}
@@ -13834,10 +13846,10 @@ language=zh
 {{echo|hi<ref>-{ho|{{echo|hi}}}-</ref>}}
 <references />
 !! html/parsoid
-<p><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[[ho|{{echo|hi}}]]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Wikipedia:首页#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup>
-<span about="#mwt8" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[http://test.com?q={{echo|ho}}]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt8" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-2"}}'><a href="./Wikipedia:首页#cite_note-2" style="counter-reset: mw-Ref 2;"><span class="mw-reflink-text">[2]</span></a></sup>
-<span about="#mwt13" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>-{ho|{{echo|hi}}}-&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt13" class="mw-ref" id="cite_ref-3" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-3"}}'><a href="./Wikipedia:首页#cite_note-3" style="counter-reset: mw-Ref 3;"><span class="mw-reflink-text">[3]</span></a></sup></p>
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt17" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Wikipedia:首页#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><a rel="mw:WikiLink" href="./Ho" title="Ho">hi</a></span></li><li about="#cite_note-2" id="cite_note-2"><a href="./Wikipedia:首页#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text"><a rel="mw:ExtLink" class="external autonumber" href="http://test.com?q=ho"></a></span></li><li about="#cite_note-3" id="cite_note-3"><a href="./Wikipedia:首页#cite_ref-3" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-3" class="mw-reference-text"><span typeof="mw:LanguageVariant" data-mw-variant='{"filter":{"l":["ho"],"t":"hi"}}'></span></span></li></ol>
+<p><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[[ho|{{echo|hi}}]]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup>
+<span about="#mwt8" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[http://test.com?q={{echo|ho}}]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt8" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-2"}}'><a href="./Main_Page#cite_note-2" style="counter-reset: mw-Ref 2;"><span class="mw-reflink-text">[2]</span></a></sup>
+<span about="#mwt13" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>-{ho|{{echo|hi}}}-&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt13" class="mw-ref" id="cite_ref-3" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-3"}}'><a href="./Main_Page#cite_note-3" style="counter-reset: mw-Ref 3;"><span class="mw-reflink-text">[3]</span></a></sup></p>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt17" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><a rel="mw:WikiLink" href="./Ho" title="Ho">hi</a></span></li><li about="#cite_note-2" id="cite_note-2"><a href="./Main_Page#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text"><a rel="mw:ExtLink" class="external autonumber" href="http://test.com?q=ho"></a></span></li><li about="#cite_note-3" id="cite_note-3"><a href="./Main_Page#cite_ref-3" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-3" class="mw-reference-text"><span typeof="mw:LanguageVariant" data-mw-variant='{"filter":{"l":["ho"],"t":"hi"}}'></span></span></li></ol>
 !! end
 
 ###
@@ -15471,6 +15483,37 @@ File:Foobar.jpg|link=Foo<nowiki>''s_bar''</nowiki>s|caption
 </ul>
 !! end
 
+!! test
+HTML entity prefix in link markup (T209236)
+!! wikitext
+[[File:Foobar.jpg|link=https://example.com?foo&params=bar]]
+
+<!-- consistency with gallery extension -->
+<gallery>
+File:Foobar.jpg|link=https://example.com?foo&params=bar
+</gallery>
+!! html/php+tidy
+<p><a href="https://example.com?foo&amp;params=bar" rel="nofollow"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p>
+<ul class="gallery mw-gallery-traditional">
+               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="https://example.com?foo&amp;params=bar"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+                       <div class="gallerytext">
+                       </div>
+               </div></li>
+</ul>
+!! html/parsoid
+<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="https://example.com?foo&amp;params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
+
+<!-- consistency with gallery extension -->
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=https://example.com?foo&amp;params=bar\n"}}'>
+<li class="gallerybox">
+<div class="thumb"><figure-inline typeof="mw:Image"><a href="https://example.com?foo&amp;params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
+<div class="gallerytext"></div>
+</li>
+</ul>
+!! end
+
 !! test
 Image with table with attributes in caption
 !! options
@@ -16418,9 +16461,9 @@ T93580: 1. Templated <ref> inside block images
 
 <references />
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"Caption with templated ref: {{echo|&lt;ref>foo&lt;/ref>}}"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>Caption with templated ref: <sup about="#mwt5" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref>foo&lt;/ref>"}},"i":0}}]}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"Caption with templated ref: {{echo|&lt;ref>foo&lt;/ref>}}"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>Caption with templated ref: <sup about="#mwt5" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref>foo&lt;/ref>"}},"i":0}}]}'><a href="./Parser_test#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></figcaption></figure>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
 !! end
 
 !! test
@@ -16430,9 +16473,9 @@ T93580: 2. <ref> inside inline images
 
 <references />
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: &lt;ref>foo&lt;/ref>"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,78,5,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"attrs\":{},\"body\":{\"id\":\"mw-reference-text-cite_note-1\"}}&#39;>&lt;a href=\"./Main_Page#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: &lt;ref>foo&lt;/ref>"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,78,5,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"attrs\":{},\"body\":{\"id\":\"mw-reference-text-cite_note-1\"}}&#39;>&lt;a href=\"./Parser_test#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 !! end
 
 !! test
@@ -16442,9 +16485,9 @@ T93580: 3. Templated <ref> inside inline images
 
 <references />
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: {{echo|&lt;ref>{{echo|foo}}&lt;/ref>}}"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Transclusion  mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,96,null,null],\"pi\":[[{\"k\":\"1\"}]]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&amp;lt;ref>{{echo|foo}}&amp;lt;/ref>\"}},\"i\":0}}]}&#39;>&lt;a href=\"./Main_Page#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: {{echo|&lt;ref>{{echo|foo}}&lt;/ref>}}"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Transclusion  mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,96,null,null],\"pi\":[[{\"k\":\"1\"}]]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&amp;lt;ref>{{echo|foo}}&amp;lt;/ref>\"}},\"i\":0}}]}&#39;>&lt;a href=\"./Parser_test#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 !! end
 
 ###
@@ -17779,12 +17822,12 @@ section 6
 <h2 id="Underscore-Entity_between_Text">Underscore-Entity<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#95;","srcContent":"_"}'>_</span>between<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#95;","srcContent":"_"}'>_</span>Text</h2>
 <p>section 6</p>
 
-<p><a rel="mw:WikiLink" href="./Main_Page#Space_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Space_between_Text"},"sa":{"href":"#Space between Text"}}'>#Space between Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Space-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Space-Entity_between_Text"},"sa":{"href":"#Space-Entity&amp;#32;between&amp;#32;Text"}}'>#Space-Entity between Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Plus+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Plus+between+Text"},"sa":{"href":"#Plus+between+Text"}}'>#Plus+between+Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Plus-Entity+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Plus-Entity+between+Text"},"sa":{"href":"#Plus-Entity&amp;#43;between&amp;#43;Text"}}'>#Plus-Entity+between+Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Underscore_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Underscore_between_Text"},"sa":{"href":"#Underscore_between_Text"}}'>#Underscore_between_Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Underscore-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Underscore-Entity_between_Text"},"sa":{"href":"#Underscore-Entity&amp;#95;between&amp;#95;Text"}}'>#Underscore-Entity_between_Text</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#Space_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Space_between_Text"},"sa":{"href":"#Space between Text"}}'>#Space between Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Space-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Space-Entity_between_Text"},"sa":{"href":"#Space-Entity&amp;#32;between&amp;#32;Text"}}'>#Space-Entity between Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Plus+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Plus+between+Text"},"sa":{"href":"#Plus+between+Text"}}'>#Plus+between+Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Plus-Entity+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Plus-Entity+between+Text"},"sa":{"href":"#Plus-Entity&amp;#43;between&amp;#43;Text"}}'>#Plus-Entity+between+Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Underscore_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Underscore_between_Text"},"sa":{"href":"#Underscore_between_Text"}}'>#Underscore_between_Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Underscore-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Underscore-Entity_between_Text"},"sa":{"href":"#Underscore-Entity&amp;#95;between&amp;#95;Text"}}'>#Underscore-Entity_between_Text</a></p>
 !! end
 
 # Parsoid html2wt disabled because it adds padding spaces around =
@@ -18177,8 +18220,7 @@ HTML tag with leading space is parsed as text
 </p>
 !! end
 
-## Don't expect Parsoid and PHP to match, since PHP isn't exactly following
-## the HTML5 parsing spec.
+## FIXME: The untrimmed attribute in Parsoid is T205737
 !! test
 Element with broken attribute syntax
 !! options
@@ -18187,7 +18229,7 @@ parsoid=wt2html
 <div style=" style="123">hi</div>
 <div =>ho</div>
 !! html/php
-<div style="123">hi</div>
+<div style="style=">hi</div>
 <div>ho</div>
 
 !! html/parsoid
@@ -18991,7 +19033,7 @@ Tags which are hidden from tidiers cannot pass through the Sanitizer
 !! end
 
 ###
-### Parser hooks (see tests/parser/parserTestsParserHook.php for the <tag> extension)
+### Parser hooks (see tests/parser/ParserTestParserHook.php for the <tag> extension)
 ###
 
 !! test
@@ -19261,7 +19303,7 @@ array (
 !! end
 
 ###
-### (see tests/parser/parserTestsParserHook.php for the <statictag> extension)
+### (see tests/parser/ParserTestParserHook.php for the <statictag> extension)
 ###
 
 !! test
@@ -19275,8 +19317,8 @@ Parser hook: static parser hook not inside a comment
 hello, world
 </p>
 !! html/parsoid
-<p><span typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{},"body":{"extsrc":"hello, world"}}' data-parsoid='{}' about="#mwt2"></span></p>
-<p typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{"action":"flush"}}' data-parsoid='{}' about="#mwt4">hello, world</p>
+<p><span typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{},"body":{"extsrc":"hello, world"}}' about="#mwt2"></span></p>
+<p><span typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{"action":"flush"}}' about="#mwt4">hello, world</span></p>
 !! end
 
 !! test
@@ -19289,7 +19331,7 @@ Parser hook: static parser hook inside a comment
 </p>
 !! html/parsoid
 <!-- <statictag&#x3E;hello, world</statictag&#x3E; -->
-<p typeof='mw:Extension/statictag' data-mw='{"name":"statictag","attrs":{"action":"flush"}}' data-parsoid='{}' about='#mwt2'></p>
+<p><span typeof='mw:Extension/statictag' data-mw='{"name":"statictag","attrs":{"action":"flush"}}' data-parsoid='{}' about='#mwt2'></span></p>
 !! end
 
 # Nested template calls; this case was broken by Parser.php rev 1.506,
@@ -19364,6 +19406,8 @@ Table not started</td></tr></table>
 
 !! test
 Sanitizer: Escaping of spaces, multibyte characters, colons & other stuff in id=""
+!! options
+title=[[Main Page]]
 !! config
 wgFragmentMode=[ 'html5', 'legacy' ]
 !! wikitext
@@ -20055,8 +20099,8 @@ parsoid=wt2html
 <pre dir="&#10;"></pre>
 
 !! html/parsoid
-<pre typeof="mw:Extension/pre" about="#mwt2" dir="
-" data-mw='{"name":"pre","attrs":{"dir":"\n"},"body":{"extsrc":""}}'></pre>
+<pre dir="
+" typeof="mw:Extension/pre" about="#mwt2"data-mw='{"name":"pre","attrs":{"dir":"\n"},"body":{"extsrc":""}}'></pre>
 !! end
 
 !! test
@@ -20082,7 +20126,7 @@ Templates in extension attributes are not expanded
 <pre dir="{{echo|ltr}}"></pre>
 
 !! html/parsoid
-<pre typeof="mw:Extension/pre" about="#mwt2" dir="{{echo|ltr}}" data-mw='{"name":"pre","attrs":{"dir":"{{echo|ltr}}"},"body":{"extsrc":""}}'></pre>
+<pre dir="{{echo|ltr}}" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"dir":"{{echo|ltr}}"},"body":{"extsrc":""}}'></pre>
 !! end
 
 !! test
@@ -21519,7 +21563,6 @@ image:foobar.jpg|link=Main Page#section|caption
 </ul>
 !! end
 
-## Whoops, Parsoid shouldn't be parsing templates in the attribute caption!
 !! test
 Gallery with template inside caption
 !! options
@@ -21532,7 +21575,7 @@ File:Foobar.jpg|{{echo|ho}}
 </gallery>
 !! html/php
 <ul class="gallery mw-gallery-traditional">
-       <li class='gallerycaption'>{{echo|hi}}</li>
+       <li class='gallerycaption'>hi</li>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
                        <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
                        <div class="gallerytext">
@@ -21549,6 +21592,30 @@ File:Foobar.jpg|{{echo|ho}}
 </ul>
 !! end
 
+!! test
+Gallery with wikitext inside gallery caption
+!! wikitext
+<gallery caption="# List item
+
+Text '''bold''' [[link]] {{ns:-1}}
+
+[[File:Foobar.jpg|thumb|File in gallery caption]]">
+File:Foobar.jpg|Image caption
+</gallery>
+!! html/php
+<ul class="gallery mw-gallery-traditional">
+       <li class='gallerycaption'># List item Text <b>bold</b> <a href="/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">link</a> Special <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>File in gallery caption</div></div></div></li>
+               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+                       <div class="gallerytext">
+<p>Image caption
+</p>
+                       </div>
+               </div></li>
+</ul>
+
+!! end
+
 !! test
 Gallery with wikitext inside caption
 !! options
@@ -22931,6 +22998,19 @@ language=zh variant=zh-tw
 <p><span typeof="mw:LanguageVariant" data-parsoid='{"tSp":[6]}' data-mw-variant='{"twoway":[{"l":"zh","t":"China"},{"l":"zh-tw","t":"Taiwan"}]}'></span>, not China</p>
 !! end
 
+!! test
+Explicit definition of language variant alternatives (BCP 47 codes)
+!! options
+language=zh variant=zh-tw
+!! wikitext
+-{zh:China;zh-Hant-TW:Taiwan}-, not China
+!! html/php
+<p>Taiwan, not China
+</p>
+!! html/parsoid
+<p><span typeof="mw:LanguageVariant" data-parsoid='{"tSp":[6]}' data-mw-variant='{"twoway":[{"l":"zh","t":"China"},{"l":"zh-Hant-TW","t":"Taiwan"}]}'></span>, not China</p>
+!! end
+
 !! test
 Filter syntax for language variants
 !! options
@@ -26801,6 +26881,33 @@ parsoid=html2wt
 
 !! end
 
+!! test
+Tables: 4e. Escape }
+!! options
+parsoid=html2wt
+!! html/parsoid
+<table>
+<tr><td>}</td></tr>
+<tr><td>x</td><td data-parsoid='{"stx":"row"}'>}</td></tr></table>
+</table>
+!! wikitext
+{|
+|<nowiki>}</nowiki>
+|-
+|x||}
+|}
+!! html/php
+<table>
+<tr>
+<td>}
+</td></tr>
+<tr>
+<td>x</td>
+<td>}
+</td></tr></table>
+
+!! end
+
 !! test
 Tables: 5. Empty table cells should get whitespace to avoid need for nowikis
 !! options
@@ -28881,6 +28988,27 @@ Image: Invalid title as link
 <p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=&lt;"}]}' data-mw='{"caption":"link=&amp;lt;"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 !! end
 
+!! test
+Various link types in alt and link options
+!! wikitext
+[[File:Foobar.jpg|link=[[Main Page]]|alt=[[Main Page]]|caption]]
+
+[[File:Foobar.jpg|link=[[Media:Thumb.png]]|alt=[[Media:Thumb.png]]|caption]]
+
+[[File:Foobar.jpg|link=[[wikipedia:Foo]]|alt=[[wikipedia:Foo]]|caption]]
+!! html/php+tidy
+<p><a href="/wiki/Main_Page" title="caption"><img alt="Main Page" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p><p><a href="/wiki/Media:Thumb.png" title="caption"><img alt="Media:Thumb.png" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p><p><a href="http://en.wikipedia.org/wiki/Foo" title="caption"><img alt="wikipedia:Foo" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p>
+!! html/parsoid
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./Main_Page" data-parsoid='{"a":{"href":"./Main_Page"},"sa":{"href":"link=[[Main Page]]"}}'><img alt="Main Page" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"Main Page","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[Main Page]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./Media:Thumb.png" data-parsoid='{"a":{"href":"./Media:Thumb.png"},"sa":{"href":"link=[[Media:Thumb.png]]"}}'><img alt="Media:Thumb.png" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"Media:Thumb.png","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[Media:Thumb.png]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="http://en.wikipedia.org/wiki/Foo" data-parsoid='{"a":{"href":"http://en.wikipedia.org/wiki/Foo"},"sa":{"href":"link=[[wikipedia:Foo]]"}}'><img alt="wikipedia:Foo" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"wikipedia:Foo","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[wikipedia:Foo]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+!! end
+
 !! test
 Lists: Serialize correctly even when list content is wrapped in p-tags (like VE does)
 !! options
@@ -30693,6 +30821,7 @@ parsoid={
 <tr><td>a</td></tr>
 <tr><td>-</td></tr>
 <tr><td>+</td></tr>
+<tr><td>}</td></tr>
 </table>
 !! wikitext
 {|
@@ -30701,6 +30830,8 @@ parsoid={
 |<nowiki>-</nowiki>
 |-
 |<nowiki>+</nowiki>
+|-
+|<nowiki>}</nowiki>
 |}
 !! end
 
@@ -30716,6 +30847,7 @@ parsoid={
 <tr><td>a</td></tr>
 <tr><td>-</td></tr>
 <tr><td>+</td></tr>
+<tr><td>}</td></tr>
 </table>
 !! wikitext
 {|
@@ -30724,6 +30856,8 @@ parsoid={
 | -
 |-
 | +
+|-
+| }
 |}
 !! end
 
@@ -30891,6 +31025,170 @@ parsoid={
 <font>foo</font>
 !! end
 
+!! test
+Ignore empty <p></p> when scrubWikitext is false
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": false
+}
+!! html/parsoid
+<div>1</div>
+<p>a</p><p></p><p>b</p>
+<div>2</div>
+<p>a</p>
+<p></p>
+<p>b</p>
+<div>3</div>
+<p>a</p>
+<p></p>
+<p></p>
+<p></p>
+<p></p>
+<p>b</p>
+!! wikitext
+<div>1</div>
+a
+
+b
+<div>2</div>
+a
+
+b
+<div>3</div>
+a
+
+b
+!! html/php+tidy
+<div>1</div>
+<p>a
+</p><p>b
+</p>
+<div>2</div>
+<p>a
+</p><p>b
+</p>
+<div>3</div>
+<p>a
+</p><p>b
+</p>
+!! end
+
+!! test
+Normalize empty paragraphs to HTML form that html2wt expects
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<div>1</div>
+<p>a</p><p></p><p>b</p>
+<div>2</div>
+<p>a</p>
+<p></p>
+<p>b</p>
+<div>3</div>
+<p>a</p>
+<p></p>
+<p></p>
+<p></p>
+<p></p>
+<p>b</p>
+<div>4</div>
+<p>a</p>
+<p></p>
+<div>foo</div>
+!! wikitext
+<div>1</div>
+a
+
+
+b
+<div>2</div>
+a
+
+
+b
+<div>3</div>
+a
+
+
+
+
+
+b
+<div>4</div>
+a
+
+<br />
+<div>foo</div>
+!! html/php+tidy
+<div>1</div>
+<p>a
+</p><p><br />
+b
+</p>
+<div>2</div>
+<p>a
+</p><p><br />
+b
+</p>
+<div>3</div>
+<p>a
+</p><p><br />
+</p><p><br />
+</p><p>b
+</p>
+<div>4</div>
+<p>a
+</p><p><br />
+</p>
+<div>foo</div>
+!! end
+
+!! test
+Empty paragraphs (marked with mw-empty-elt) found in source should not be normalized away
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<table>
+<tbody>
+<tr>
+<td><div>foo
+</div>
+<p class="mw-empty-elt"></p>
+</td>
+</tr>
+</tbody>
+<caption></caption>
+</table>
+!! wikitext
+{|
+|<div>foo
+</div>
+|+
+|}
+!! end
+
+!! test
+Templated content should be skipped over by normalization
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"SomeTemplate1","href":"./Template:SomeTemplate1"},"params":{"1":{"wt":"boo"}},"i":0}}]}'>foobar</p><p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"SomeTemplate2","href":"./Template:SomeTemplate2"},"params":{"1":{"wt":"booboo"}},"i":0}}]}'>foobar</p><span about="#mwt2">
+</span><p about="#mwt2"></p><span about="#mwt2">
+</span>
+!! wikitext
+{{SomeTemplate1|boo}}{{SomeTemplate2|booboo}}
+!! end
+
 !! test
 Escape nowiki DOM elements
 !! options
@@ -31350,7 +31648,7 @@ wgFragmentMode=[ 'html5', 'legacy' ]
 </p>
 !! html/parsoid
 <h2 id="A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"><span id="A.26B.26C.26amp.3BD.26amp.3Bamp.3BE" typeof="mw:FallbackId" data-parsoid="{}"></span>A&amp;B<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>C<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>amp;D<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>amp;amp;E</h2>
-<p><a rel="mw:WikiLink" href="./Main_Page#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"},"sa":{"href":"#A&amp;B&amp;amp;C&amp;amp;amp;D&amp;amp;amp;amp;E"}}'>#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"},"sa":{"href":"#A&amp;B&amp;amp;C&amp;amp;amp;D&amp;amp;amp;amp;E"}}'>#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E</a></p>
 !! end
 
 !! test
@@ -31463,12 +31761,12 @@ wgFragmentMode=[ 'html5', 'legacy' ]
 <h2 id="тест"><span id=".D1.82.D0.B5.D1.81.D1.82" typeof="mw:FallbackId"></span>тест</h2>
 
 <h2 id="Hey_&lt;_#_&quot;_>_%_:_'"><span id="Hey_.3C_.23_.22_.3E_.25_:_.27" typeof="mw:FallbackId"></span>Hey &lt; # " > %<span typeof="mw:DisplaySpace mw:Placeholder" data-parsoid='{"src":" ","isDisplayHack":true}'> </span>: '</h2>
-<p><a rel="mw:WikiLink" href="./Main_Page#Foo_bar">#Foo bar</a> <a rel="mw:WikiLink" href="./Main_Page#foo_Bar">#foo Bar</a> <a rel="mw:WikiLink" href="./Main_Page#Тест">#Тест</a> <a rel="mw:WikiLink" href="./Main_Page#тест">#тест</a> <a rel="mw:WikiLink" href="./Main_Page#Hey_&lt;_#_&quot;_>_%_:_'" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Hey_&lt;_#_\"_>_%_:_&#39;"},"sa":{"href":"#Hey &lt; # \" > % : &#39;"}}'>#Hey &lt; # " > % : '</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#Foo_bar">#Foo bar</a> <a rel="mw:WikiLink" href="./Parser_test#foo_Bar">#foo Bar</a> <a rel="mw:WikiLink" href="./Parser_test#Тест">#Тест</a> <a rel="mw:WikiLink" href="./Parser_test#тест">#тест</a> <a rel="mw:WikiLink" href="./Parser_test#Hey_&lt;_#_&quot;_>_%_:_'" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Hey_&lt;_#_\"_>_%_:_&#39;"},"sa":{"href":"#Hey &lt; # \" > % : &#39;"}}'>#Hey &lt; # " > % : '</a></p>
 
 <p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"anchorencode:💩","function":"anchorencode"},"params":{},"i":0}}]}'>💩</span> <span id="💩" about="#mwt3" typeof="mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span about=\"#mwt2\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[178,197,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:💩\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&#39;>💩&lt;/span>"}]]}'></span></p>
 
 <!-- These two links should produce identical HTML -->
-<p><a rel="mw:WikiLink" href="./Main_Page#啤酒">#啤酒</a> <a rel="mw:WikiLink" href="./Main_Page#啤酒" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#啤酒"},"sa":{"href":"#%E5%95%A4%E9%85%92"}}'>#啤酒</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#啤酒">#啤酒</a> <a rel="mw:WikiLink" href="./Parser_test#啤酒" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#啤酒"},"sa":{"href":"#%E5%95%A4%E9%85%92"}}'>#啤酒</a></p>
 !! end
 
 # Parsoid doesn't support this mode
@@ -31581,7 +31879,7 @@ wgFragmentMode=[ 'html5', 'legacy' ]
 </p>
 !! html/parsoid
 <h2 id="Foo_bar"> Foo<span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span>bar </h2>
-<p><a rel="mw:WikiLink" href="./Main_Page#Foo_bar" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Foo_bar"},"sa":{"href":"#Foo&amp;nbsp;bar"}}'>#Foo bar</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#Foo_bar" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Foo_bar"},"sa":{"href":"#Foo&amp;nbsp;bar"}}'>#Foo bar</a></p>
 !! end
 
 !! test
@@ -31638,7 +31936,7 @@ wgFragmentMode=[ 'html5' ]
 <p><span id="&#91;foo&#93;"></span><a href="#[foo]">#&#91;foo&#93;</a>
 </p>
 !! html/parsoid
-<p><span id="[foo]" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"id":"[foo]"},"sa":{"id":"{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[10,32,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'></span><a typeof="mw:ExpandedAttrs" about="#mwt4" rel="mw:WikiLink" href="./Main_Page#[foo]" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#[foo]"},"sa":{"href":"#{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"href"},{"html":"#&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[44,66,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt2\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'>#[foo]</a></p>
+<p><span id="[foo]" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"id":"[foo]"},"sa":{"id":"{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[10,32,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'></span><a typeof="mw:ExpandedAttrs" about="#mwt4" rel="mw:WikiLink" href="./Parser_test#[foo]" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#[foo]"},"sa":{"href":"#{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"href"},{"html":"#&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[44,66,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt2\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'>#[foo]</a></p>
 !! end
 
 ## ------------------------------
index 08a8fa6..43fccee 100644 (file)
@@ -483,6 +483,23 @@ class RenderedRevisionTest extends MediaWikiTestCase {
                $this->assertContains( 'time:20180101000003!', $html );
        }
 
+       public function testSetRevisionParserOutput() {
+               $title = $this->getMockTitle( 3, 21 );
+               $rev = $this->getMockRevision( RevisionStoreRecord::class, $title );
+
+               $options = ParserOptions::newCanonical( 'canonical' );
+               $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback );
+
+               $output = new ParserOutput( 'Kittens' );
+               $rr->setRevisionParserOutput( $output );
+
+               $this->assertSame( $output, $rr->getRevisionParserOutput() );
+               $this->assertSame( 'Kittens', $rr->getRevisionParserOutput()->getText() );
+
+               $this->assertSame( $output, $rr->getSlotParserOutput( SlotRecord::MAIN ) );
+               $this->assertSame( 'Kittens', $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() );
+       }
+
        public function testNoHtml() {
                /** @var MockObject|Content $mockContent */
                $mockContent = $this->getMockBuilder( WikitextContent::class )
index 469f281..5c75ede 100644 (file)
@@ -240,6 +240,34 @@ class RevisionRendererTest extends MediaWikiTestCase {
                $this->assertSame( $html, $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() );
        }
 
+       public function testGetRenderedRevision_known() {
+               $renderer = $this->newRevisionRenderer( 100, true ); // use master
+               $title = $this->getMockTitle( 7, 21 );
+
+               $rev = new MutableRevisionRecord( $title );
+               $rev->setId( 21 ); // current!
+               $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) );
+               $rev->setTimestamp( '20180101000003' );
+               $rev->setComment( CommentStoreComment::newUnsavedComment( '' ) );
+
+               $text = "uncached text";
+               $rev->setContent( SlotRecord::MAIN, new WikitextContent( $text ) );
+
+               $output = new ParserOutput( 'cached text' );
+
+               $options = ParserOptions::newCanonical( 'canonical' );
+               $rr = $renderer->getRenderedRevision(
+                       $rev,
+                       $options,
+                       null,
+                       [ 'known-revision-output' => $output ]
+               );
+
+               $this->assertSame( $output, $rr->getRevisionParserOutput() );
+               $this->assertSame( 'cached text', $rr->getRevisionParserOutput()->getText() );
+               $this->assertSame( 'cached text', $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() );
+       }
+
        public function testGetRenderedRevision_old() {
                $renderer = $this->newRevisionRenderer( 100 );
                $title = $this->getMockTitle( 7, 21 );
index d11e314..312ef55 100644 (file)
@@ -599,7 +599,9 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                [
                                        'text' => '&#60;b&#62;Something broke!&#60;/b&#62;',
                                        'code' => 'internal_api_error_RuntimeException',
-                                       'data' => [],
+                                       'data' => [
+                                               'errorclass' => 'RuntimeException',
+                                       ],
                                ]
                        ],
                        'Normal exception, wrapped' => [
@@ -632,4 +634,23 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                ];
        }
 
+       /**
+        * @dataProvider provideIsValidApiCode
+        * @covers ApiErrorFormatter::isValidApiCode
+        * @param string $code
+        * @param bool $expect
+        */
+       public function testIsValidApiCode( $code, $expect ) {
+               $this->assertSame( $expect, ApiErrorFormatter::isValidApiCode( $code ) );
+       }
+
+       public static function provideIsValidApiCode() {
+               return [
+                       [ 'foo-bar_Baz123', true ],
+                       [ 'foo bar', false ],
+                       [ 'foo\\bar', false ],
+                       [ 'internal_api_error_foo\\bar baz', true ],
+               ];
+       }
+
 }
index a6083cd..9cb84e2 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Wikimedia\Rdbms\DBQueryError;
 use Wikimedia\TestingAccessWrapper;
 
 /**
@@ -1010,6 +1011,15 @@ class ApiMainTest extends ApiTestCase {
                        MWExceptionHandler::getRedactedTraceAsString( $dbex )
                )->inLanguage( 'en' )->useDatabase( false )->text();
 
+               // The specific exception doesn't matter, as long as it's namespaced.
+               $nsex = new MediaWiki\ShellDisabledError();
+               $nstrace = wfMessage( 'api-exception-trace',
+                       get_class( $nsex ),
+                       $nsex->getFile(),
+                       $nsex->getLine(),
+                       MWExceptionHandler::getRedactedTraceAsString( $nsex )
+               )->inLanguage( 'en' )->useDatabase( false )->text();
+
                $apiEx1 = new ApiUsageException( null,
                        StatusValue::newFatal( new ApiRawMessage( 'An error', 'sv-error1' ) ) );
                TestingAccessWrapper::newFromObject( $apiEx1 )->modulePath = 'foo+bar';
@@ -1017,6 +1027,13 @@ class ApiMainTest extends ApiTestCase {
                $apiEx1->getStatusValue()->warning( new ApiRawMessage( 'Another warning', 'sv-warn2' ) );
                $apiEx1->getStatusValue()->fatal( new ApiRawMessage( 'Another error', 'sv-error2' ) );
 
+               $badMsg = $this->getMockBuilder( ApiRawMessage::class )
+                        ->setConstructorArgs( [ 'An error', 'ignored' ] )
+                        ->setMethods( [ 'getApiCode' ] )
+                        ->getMock();
+               $badMsg->method( 'getApiCode' )->willReturn( "bad\nvalue" );
+               $apiEx2 = new ApiUsageException( null, StatusValue::newFatal( $badMsg ) );
+
                return [
                        [
                                $ex,
@@ -1030,6 +1047,9 @@ class ApiMainTest extends ApiTestCase {
                                                [
                                                        'code' => 'internal_api_error_InvalidArgumentException',
                                                        'text' => "[$reqId] Exception caught: Random exception",
+                                                       'data' => [
+                                                               'errorclass' => InvalidArgumentException::class,
+                                                       ],
                                                ]
                                        ],
                                        'trace' => $trace,
@@ -1049,12 +1069,36 @@ class ApiMainTest extends ApiTestCase {
                                                        'code' => 'internal_api_error_DBQueryError',
                                                        'text' => "[$reqId] Exception caught: A database query error has occurred. " .
                                                                "This may indicate a bug in the software.",
+                                                       'data' => [
+                                                               'errorclass' => DBQueryError::class,
+                                                       ],
                                                ]
                                        ],
                                        'trace' => $dbtrace,
                                        'servedby' => wfHostname(),
                                ]
                        ],
+                       [
+                               $nsex,
+                               [ 'existing-error', 'internal_api_error_MediaWiki\ShellDisabledError' ],
+                               [
+                                       'warnings' => [
+                                               [ 'code' => 'existing-warning', 'text' => 'existing warning', 'module' => 'main' ],
+                                       ],
+                                       'errors' => [
+                                               [ 'code' => 'existing-error', 'text' => 'existing error', 'module' => 'main' ],
+                                               [
+                                                       'code' => 'internal_api_error_MediaWiki\ShellDisabledError',
+                                                       'text' => "[$reqId] Exception caught: " . $nsex->getMessage(),
+                                                       'data' => [
+                                                               'errorclass' => MediaWiki\ShellDisabledError::class,
+                                                       ],
+                                               ]
+                                       ],
+                                       'trace' => $nstrace,
+                                       'servedby' => wfHostname(),
+                               ]
+                       ],
                        [
                                $apiEx1,
                                [ 'existing-error', 'sv-error1', 'sv-error2' ],
@@ -1075,6 +1119,23 @@ class ApiMainTest extends ApiTestCase {
                                        'servedby' => wfHostname(),
                                ]
                        ],
+                       [
+                               $apiEx2,
+                               [ 'existing-error', '<invalid-code>' ],
+                               [
+                                       'warnings' => [
+                                               [ 'code' => 'existing-warning', 'text' => 'existing warning', 'module' => 'main' ],
+                                       ],
+                                       'errors' => [
+                                               [ 'code' => 'existing-error', 'text' => 'existing error', 'module' => 'main' ],
+                                               [ 'code' => "bad\nvalue", 'text' => 'An error' ],
+                                       ],
+                                       'docref' => "See $doclink for API usage. Subscribe to the mediawiki-api-announce mailing " .
+                                               "list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; " .
+                                               "for notice of API deprecations and breaking changes.",
+                                       'servedby' => wfHostname(),
+                               ]
+                       ]
                ];
        }
 
index c6f5a8e..70114c2 100644 (file)
@@ -38,6 +38,10 @@ class ApiMessageTest extends MediaWikiTestCase {
                $msg = new ApiMessage( 'apiwarn-baz' );
                $this->assertSame( 'baz', $msg->getApiCode() );
 
+               // Weird "message key"
+               $msg = new ApiMessage( "<foo> bar\nbaz" );
+               $this->assertSame( '_foo__bar_baz', $msg->getApiCode() );
+
                // BC case
                $msg = new ApiMessage( 'actionthrottledtext' );
                $this->assertSame( 'ratelimited', $msg->getApiCode() );
@@ -72,6 +76,9 @@ class ApiMessageTest extends MediaWikiTestCase {
                return [
                        [ '' ],
                        [ 42 ],
+                       [ 'A bad code' ],
+                       [ 'Project:A_page_title' ],
+                       [ "WTF\nnewlines" ],
                ];
        }
 
index e865e79..58f9654 100644 (file)
@@ -493,7 +493,7 @@ class LBFactoryTest extends MediaWikiTestCase {
                $lb->reuseConnection( $db ); // don't care
 
                $db = $lb->getConnection( DB_MASTER ); // local domain connection
-               $factory->setDomainPrefix( 'my_' );
+               $factory->setLocalDomainPrefix( 'my_' );
 
                $this->assertEquals( $wgDBname, $db->getDBname() );
                $this->assertEquals(
@@ -556,7 +556,7 @@ class LBFactoryTest extends MediaWikiTestCase {
 
                $lb->reuseConnection( $db ); // don't care
 
-               $factory->setDomainPrefix( 'my_' );
+               $factory->setLocalDomainPrefix( 'my_' );
                $db = $lb->getConnection( DB_MASTER, [], "$wgDBname-my_" );
 
                $this->assertEquals(
@@ -621,6 +621,50 @@ class LBFactoryTest extends MediaWikiTestCase {
                }
        }
 
+       public function testRedefineLocalDomain() {
+               global $wgDBname;
+
+               if ( wfGetDB( DB_MASTER )->databasesAreIndependent() ) {
+                       self::markTestSkipped( "Skipping tests about selecting DBs: not applicable" );
+                       return;
+               }
+
+               $factory = $this->newLBFactoryMulti(
+                       [],
+                       []
+               );
+               $lb = $factory->getMainLB();
+
+               $conn1 = $lb->getConnectionRef( DB_MASTER );
+               $this->assertEquals(
+                       wfWikiID(),
+                       $conn1->getDomainID()
+               );
+               unset( $conn1 );
+
+               $factory->redefineLocalDomain( 'somedb-prefix' );
+               $this->assertEquals( 'somedb-prefix', $factory->getLocalDomainID() );
+
+               $domain = new DatabaseDomain( $wgDBname, null, 'pref' );
+               $factory->redefineLocalDomain( $domain );
+
+               $n = 0;
+               $lb->forEachOpenConnection( function () use ( &$n ) {
+                       ++$n;
+               } );
+               $this->assertEquals( 0, $n, "Connections closed" );
+
+               $conn2 = $lb->getConnectionRef( DB_MASTER );
+               $this->assertEquals(
+                       $domain->getId(),
+                       $conn2->getDomainID()
+               );
+               unset( $conn2 );
+
+               $factory->closeAll();
+               $factory->destroy();
+       }
+
        private function quoteTable( Database $db, $table ) {
                if ( $db->getType() === 'sqlite' ) {
                        return $table;
index 6ce01ca..58441f0 100644 (file)
@@ -124,9 +124,8 @@ class LocalIdLookupTest extends MediaWikiTestCase {
         * @param bool $localDBSet $wgLocalDatabases contains the shared DB
         */
        public function testIsAttachedShared( $sharedDB, $sharedTable, $localDBSet ) {
-               global $wgDBName;
                $this->setMwGlobals( [
-                       'wgSharedDB' => $sharedDB ? $wgDBName : null,
+                       'wgSharedDB' => $sharedDB ? "dummy" : null,
                        'wgSharedTables' => $sharedTable ? [ 'user' ] : [],
                        'wgLocalDatabases' => $localDBSet ? [ 'shared' ] : [],
                ] );
index f1c049b..b9289db 100644 (file)
@@ -1285,8 +1285,17 @@ class UserTest extends MediaWikiTestCase {
                                'pageRestrictions' => [ 'Test page' ],
                        ] ],
                        'Partial block, overriding allowUsertalk' => [ self::USER_TALK_PAGE, true, [
+                               'allowUsertalk' => false,
                                'pageRestrictions' => [ self::USER_TALK_PAGE ],
                        ] ],
+                       'Partial block, allowing user talk' => [ self::USER_TALK_PAGE, false, [
+                               'allowUsertalk' => true,
+                               'pageRestrictions' => [ 'Test page' ],
+                       ] ],
+                       'Partial block, not allowing user talk' => [ self::USER_TALK_PAGE, true, [
+                               'allowUsertalk' => false,
+                               'pageRestrictions' => [ 'Test page' ],
+                       ] ],
                ];
        }
 
index acdf2f1..afeb4a5 100644 (file)
                assert.strictEqual( title.getFragment(), null, 'getTalkPage does not copy the fragment' );
        } );
 
+       QUnit.test( 'wantSignaturesNamespace', function ( assert ) {
+               var namespaces = mw.config.values.wgExtraSignatureNamespaces;
+
+               mw.config.values.wgExtraSignatureNamespaces = [];
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 0 ), false, 'Main namespace has no signatures' );
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 1 ), true, 'Talk namespace no signatures' );
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 2 ), false, 'NS2 has no signatures' );
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 3 ), true, 'NS3 has signatures' );
+
+               mw.config.values.wgExtraSignatureNamespaces = [ 0 ];
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 0 ), true, 'Main namespace has signatures when explicitly defined' );
+
+               // Restore
+               mw.config.values.wgExtraSignatureNamespaces = namespaces;
+       } );
+
        QUnit.test( 'Throw error on invalid title', function ( assert ) {
                assert.throws( function () {
                        return new mw.Title( '' );