From: jenkins-bot Date: Fri, 24 May 2019 22:16:07 +0000 (+0000) Subject: Merge "AllMessagesTablePager: Use $this->msg instead of wfMessage" X-Git-Tag: 1.34.0-rc.0~1592 X-Git-Url: http://git.cyclocoop.org/data/Luca_Pacioli_%28Gemaelde%29.jpeg?a=commitdiff_plain;h=10ec68ee372db0ead8aa9626ed9bb3bd328b98f1;hp=eb187d079c1db54ed5dc5f1dcd2a9a4e498768d2;p=lhc%2Fweb%2Fwiklou.git Merge "AllMessagesTablePager: Use $this->msg instead of wfMessage" --- diff --git a/README b/README index ad9b9d9d83..b9b2c8a381 100644 --- a/README +++ b/README @@ -23,7 +23,7 @@ RELEASE-NOTES, INSTALL, and UPGRADE. * Seeking help from a person? ** https://www.mediawiki.org/wiki/Special:MyLanguage/Communication * Looking to file a bug report or a feature request? -** https://bugs.mediawiki.org/ +** https://phabricator.mediawiki.org/ * Interested in helping out? ** https://www.mediawiki.org/wiki/Special:MyLanguage/How_to_contribute diff --git a/RELEASE-NOTES-1.34 b/RELEASE-NOTES-1.34 index 81831458cf..e59d7f7fe4 100644 --- a/RELEASE-NOTES-1.34 +++ b/RELEASE-NOTES-1.34 @@ -35,6 +35,13 @@ For notes on 1.33.x and older releases, see HISTORY. module or will be generated by Mediawiki itself (depending on the set-up). ==== Changed configuration ==== +* $wgUseCdn, $wgCdnServers, $wgCdnServersNoPurge, and $wgCdnMaxAge – These four + CDN-related config variables have been renamed from being specific to Squid – + they were previously $wgUseSquid, $wgSquidServers, $wgSquidServersNoPurge, and + $wgSquidMaxage respectively. This aligns them with the related existing + variable $wgCdnMaxageLagged. The previous configuration variable names are + deprecated, but will be used as the fall back if they are still set. + Note that wgSquidPurgeUseHostHeader has not been renamed, as it is deprecated. * … ==== Removed configuration ==== @@ -218,6 +225,11 @@ because of Phabricator reports. * Parser::$mConf is deprecated. It will be removed entirely in a later version. Some context can be found at T224165. * Constructing Parser directly is deprecated. Obtain one from ParserFactory. +* Title::moveSubpages is deprecated. Use MovePage::moveSubpages or + MovePage::moveSubpagesIfAllowed. +* The MWNamespace class is deprecated. Use MediaWikiServices::getNamespaceInfo. +* (T62260) Hard deprecate Language::getExtraUserToggles() method. +* … === Other changes in 1.34 === * … diff --git a/includes/AjaxResponse.php b/includes/AjaxResponse.php index 5f889adb86..323c5d30ac 100644 --- a/includes/AjaxResponse.php +++ b/includes/AjaxResponse.php @@ -179,8 +179,7 @@ class AjaxResponse { # If CDN caches are configured, tell them to cache the response, # and tell the client to always check with the CDN. Otherwise, # tell the client to use a cached copy, without a way to purge it. - - if ( $this->mConfig->get( 'UseSquid' ) ) { + if ( $this->mConfig->get( 'UseCdn' ) ) { # Expect explicit purge of the proxy cache, but require end user agents # to revalidate against the proxy on each visit. # Surrogate-Control controls our CDN, Cache-Control downstream caches diff --git a/includes/Block.php b/includes/Block.php index 9f7f77d439..0f5e8dd316 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -1154,7 +1154,7 @@ class Block extends AbstractBlock { if ( !IP::isValid( $ipaddr ) ) { continue; } - # Don't check trusted IPs (includes local squids which will be in every request) + # Don't check trusted IPs (includes local CDNs which will be in every request) if ( $proxyLookup->isTrustedProxy( $ipaddr ) ) { continue; } @@ -1208,14 +1208,14 @@ class Block extends AbstractBlock { * - Other softblocks are chosen over autoblocks * - If there are multiple exact or range blocks at the same level, the one chosen * is random - * This should be used when $blocks where retrieved from the user's IP address + * This should be used when $blocks were retrieved from the user's IP address * and $ipChain is populated from the same IP address information. * * @param array $blocks Array of Block objects * @param array $ipChain List of IPs (strings). This is used to determine how "close" * a block is to the server, and if a block matches exactly, or is in a range. * The order is furthest from the server to nearest e.g., (Browser, proxy1, proxy2, - * local-squid, ...) + * local-cdn, ...) * @throws MWException * @return Block|null The "best" block from the list */ diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 9efcfb47a3..eed732bac6 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -2701,7 +2701,8 @@ $wgExtensionInfoMTime = false; * @name HTTP proxy (CDN) settings * * Many of these settings apply to any HTTP proxy used in front of MediaWiki, - * although they are referred to as Squid settings for historical reasons. + * although they are sometimes still referred to as Squid settings for + * historical reasons. * * Achieving a high hit ratio with an HTTP proxy requires special * configuration. See https://www.mediawiki.org/wiki/Manual:Squid_caching for @@ -2713,8 +2714,10 @@ $wgExtensionInfoMTime = false; /** * Enable/disable CDN. * See https://www.mediawiki.org/wiki/Manual:Squid_caching + * + * @since 1.34 Renamed from $wgUseSquid. */ -$wgUseSquid = false; +$wgUseCdn = false; /** * If you run Squid3 with ESI support, enable this (default:false): @@ -2756,12 +2759,15 @@ $wgInternalServer = false; * out s-maxage in the CDN config. * * 18000 seconds = 5 hours, more cache hits with 2678400 = 31 days. + * + * @since 1.34 Renamed from $wgSquidMaxage */ -$wgSquidMaxage = 18000; +$wgCdnMaxAge = 18000; /** * Cache timeout for the CDN when DB replica DB lag is high - * @see $wgSquidMaxage + * @see $wgCdnMaxAge + * * @since 1.27 */ $wgCdnMaxageLagged = 30; @@ -2784,7 +2790,7 @@ $wgCdnReboundPurgeDelay = 0; /** * Cache timeout for the CDN when a response is known to be wrong or incomplete (due to load) - * @see $wgSquidMaxage + * @see $wgCdnMaxAge * @since 1.27 */ $wgCdnMaxageSubstitute = 60; @@ -2803,20 +2809,24 @@ $wgForcedRawSMaxage = 300; * headers sent/modified from these proxies when obtaining the remote IP address * * For a list of trusted servers which *aren't* purged, see $wgSquidServersNoPurge. + * + * @since 1.34 Renamed from $wgSquidServers. */ -$wgSquidServers = []; +$wgCdnServers = []; /** - * As above, except these servers aren't purged on page changes; use to set a - * list of trusted proxies, etc. Supports both individual IP addresses and - * CIDR blocks. + * As with $wgCdnServers, except these servers aren't purged on page changes; + * use to set a list of trusted proxies, etc. Supports both individual IP + * addresses and CIDR blocks. + * * @since 1.23 Supports CIDR ranges + * @since 1.34 Renamed from $wgSquidServersNoPurge */ -$wgSquidServersNoPurge = []; +$wgCdnServersNoPurge = []; /** * Whether to use a Host header in purge requests sent to the proxy servers - * configured in $wgSquidServers. Set this to false to support Squid + * configured in $wgCdnServers. Set this to false to support a CDN * configured in forward-proxy mode. * * If this is set to true, a Host header will be sent, and only the path @@ -6505,7 +6515,7 @@ $wgCachePrefix = false; /** * Display the new debugging toolbar. This also enables profiling on database * queries and other useful output. - * Will be ignored if $wgUseFileCache or $wgUseSquid is enabled. + * Will be ignored if $wgUseFileCache or $wgUseCdn is enabled. * * @since 1.19 */ @@ -9083,6 +9093,17 @@ $wgReportToEndpoints = []; */ $wgFeaturePolicyReportOnly = []; +/** + * Options for Special:Search completion widget form created by SearchFormWidget class. + * Settings that can be used: + * - showDescriptions: true/false - whether to show opensearch description results + * - performSearchOnClick: true/false - whether to perform search on click + * See also TitleWidget.js UI widget. + * @since 1.34 + * @var array + */ +$wgSpecialSearchFormOptions = []; + /** * For really cool vim folding this needs to be at the end: * vim: foldmarker=@{,@} foldmethod=marker diff --git a/includes/FeedUtils.php b/includes/FeedUtils.php index 0a88b2345f..59efc98b1c 100644 --- a/includes/FeedUtils.php +++ b/includes/FeedUtils.php @@ -20,7 +20,6 @@ * @file * @ingroup Feed */ -use MediaWiki\MediaWikiServices; /** * Helper functions for feeds @@ -29,25 +28,6 @@ use MediaWiki\MediaWikiServices; */ class FeedUtils { - /** - * Check whether feed's cache should be cleared; for changes feeds - * If the feed should be purged; $timekey and $key will be removed from cache - * - * @param string $timekey Cache key of the timestamp of the last item - * @param string $key Cache key of feed's content - */ - public static function checkPurge( $timekey, $key ) { - global $wgRequest, $wgUser; - - $purge = $wgRequest->getVal( 'action' ) === 'purge'; - // Allow users with 'purge' right to clear feed caches - if ( $purge && $wgUser->isAllowed( 'purge' ) ) { - $cache = MediaWikiServices::getInstance()->getMainWANObjectCache(); - $cache->delete( $timekey, 1 ); - $cache->delete( $key, 1 ); - } - } - /** * Check whether feeds can be used and that $type is a valid feed type * diff --git a/includes/MediaWiki.php b/includes/MediaWiki.php index 69bafafb7f..ca77121b6b 100644 --- a/includes/MediaWiki.php +++ b/includes/MediaWiki.php @@ -486,14 +486,14 @@ class MediaWiki { } # Let CDN cache things if we can purge them. - if ( $this->config->get( 'UseSquid' ) && + if ( $this->config->get( 'UseCdn' ) && in_array( // Use PROTO_INTERNAL because that's what getCdnUrls() uses wfExpandUrl( $request->getRequestURL(), PROTO_INTERNAL ), $requestTitle->getCdnUrls() ) ) { - $output->setCdnMaxage( $this->config->get( 'SquidMaxage' ) ); + $output->setCdnMaxage( $this->config->get( 'CdnMaxAge' ) ); } $action->show(); @@ -597,7 +597,7 @@ class MediaWiki { wfDebug( __METHOD__ . ': primary transaction round committed' ); // Run updates that need to block the user or affect output (this is the last chance) - DeferredUpdates::doUpdates( 'enqueue', DeferredUpdates::PRESEND ); + DeferredUpdates::doUpdates( 'run', DeferredUpdates::PRESEND ); wfDebug( __METHOD__ . ': pre-send deferred updates completed' ); // T214471: persist the session to avoid race conditions on subsequent requests $request->getSession()->save(); diff --git a/includes/MovePage.php b/includes/MovePage.php index 004ca07641..d04535558d 100644 --- a/includes/MovePage.php +++ b/includes/MovePage.php @@ -286,6 +286,132 @@ class MovePage { return $this->moveUnsafe( $user, $reason, $createRedirect, $changeTags ); } + /** + * Move the source page's subpages to be subpages of the target page, without checking user + * permissions. The caller is responsible for moving the source page itself. We will still not + * do moves that are inherently not allowed, nor will we move more than $wgMaximumMovedPages. + * + * @param User $user + * @param string|null $reason The reason for the move + * @param bool|null $createRedirect Whether to create redirects from the old subpages to + * the new ones + * @param string[] $changeTags Applied to entries in the move log and redirect page revision + * @return Status Good if no errors occurred. Ok if at least one page succeeded. The "value" + * of the top-level status is an array containing the per-title status for each page. For any + * move that succeeded, the "value" of the per-title status is the new page title. + */ + public function moveSubpages( + User $user, $reason = null, $createRedirect = true, array $changeTags = [] + ) { + return $this->moveSubpagesInternal( false, $user, $reason, $createRedirect, $changeTags ); + } + + /** + * Move the source page's subpages to be subpages of the target page, with user permission + * checks. The caller is responsible for moving the source page itself. + * + * @param User $user + * @param string|null $reason The reason for the move + * @param bool|null $createRedirect Whether to create redirects from the old subpages to + * the new ones. Ignored if the user doesn't have the 'suppressredirect' right. + * @param string[] $changeTags Applied to entries in the move log and redirect page revision + * @return Status Good if no errors occurred. Ok if at least one page succeeded. The "value" + * of the top-level status is an array containing the per-title status for each page. For any + * move that succeeded, the "value" of the per-title status is the new page title. + */ + public function moveSubpagesIfAllowed( + User $user, $reason = null, $createRedirect = true, array $changeTags = [] + ) { + return $this->moveSubpagesInternal( true, $user, $reason, $createRedirect, $changeTags ); + } + + /** + * @param bool $checkPermissions + * @param User $user + * @param string $reason + * @param bool $createRedirect + * @param array $changeTags + * @return Status + */ + private function moveSubpagesInternal( + $checkPermissions, User $user, $reason, $createRedirect, array $changeTags + ) { + global $wgMaximumMovedPages; + $services = MediaWikiServices::getInstance(); + + if ( $checkPermissions ) { + if ( !$services->getPermissionManager()->userCan( + 'move-subpages', $user, $this->oldTitle ) + ) { + return Status::newFatal( 'cant-move-subpages' ); + } + } + + $nsInfo = $services->getNamespaceInfo(); + + // Do the source and target namespaces support subpages? + if ( !$nsInfo->hasSubpages( $this->oldTitle->getNamespace() ) ) { + return Status::newFatal( 'namespace-nosubpages', + $nsInfo->getCanonicalName( $this->oldTitle->getNamespace() ) ); + } + if ( !$nsInfo->hasSubpages( $this->newTitle->getNamespace() ) ) { + return Status::newFatal( 'namespace-nosubpages', + $nsInfo->getCanonicalName( $this->newTitle->getNamespace() ) ); + } + + // Return a status for the overall result. Its value will be an array with per-title + // status for each subpage. Merge any errors from the per-title statuses into the + // top-level status without resetting the overall result. + $topStatus = Status::newGood(); + $perTitleStatus = []; + $subpages = $this->oldTitle->getSubpages( $wgMaximumMovedPages + 1 ); + $count = 0; + foreach ( $subpages as $oldSubpage ) { + $count++; + if ( $count > $wgMaximumMovedPages ) { + $status = Status::newFatal( 'movepage-max-pages', $wgMaximumMovedPages ); + $perTitleStatus[$oldSubpage->getPrefixedText()] = $status; + $topStatus->merge( $status ); + $topStatus->setOk( true ); + break; + } + + // We don't know whether this function was called before or after moving the root page, + // so check both titles + if ( $oldSubpage->getArticleID() == $this->oldTitle->getArticleID() || + $oldSubpage->getArticleID() == $this->newTitle->getArticleID() + ) { + // When moving a page to a subpage of itself, don't move it twice + continue; + } + $newPageName = preg_replace( + '#^' . preg_quote( $this->oldTitle->getDBkey(), '#' ) . '#', + StringUtils::escapeRegexReplacement( $this->newTitle->getDBkey() ), # T23234 + $oldSubpage->getDBkey() ); + if ( $oldSubpage->isTalkPage() ) { + $newNs = $this->newTitle->getTalkPage()->getNamespace(); + } else { + $newNs = $this->newTitle->getSubjectPage()->getNamespace(); + } + // T16385: we need makeTitleSafe because the new page names may be longer than 255 + // characters. + $newSubpage = Title::makeTitleSafe( $newNs, $newPageName ); + + $mp = new MovePage( $oldSubpage, $newSubpage ); + $method = $checkPermissions ? 'moveIfAllowed' : 'move'; + $status = $mp->$method( $user, $reason, $createRedirect, $changeTags ); + if ( $status->isOK() ) { + $status->setResult( true, $newSubpage->getPrefixedText() ); + } + $perTitleStatus[$oldSubpage->getPrefixedText()] = $status; + $topStatus->merge( $status ); + $topStatus->setOk( true ); + } + + $topStatus->value = $perTitleStatus; + return $topStatus; + } + /** * Moves *without* any sort of safety or sanity checks. Hooks can still fail the move, however. * diff --git a/includes/OutputPage.php b/includes/OutputPage.php index edffc3bd03..54b3ee5f68 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -746,10 +746,10 @@ class OutputPage extends ContextSource { 'user' => $this->getUser()->getTouched(), 'epoch' => $config->get( 'CacheEpoch' ) ]; - if ( $config->get( 'UseSquid' ) ) { + if ( $config->get( 'UseCdn' ) ) { $modifiedTimes['sepoch'] = wfTimestamp( TS_MW, $this->getCdnCacheEpoch( time(), - $config->get( 'SquidMaxage' ) + $config->get( 'CdnMaxAge' ) ) ); } Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes, $this ] ); @@ -818,7 +818,7 @@ class OutputPage extends ContextSource { * @return int Timestamp */ private function getCdnCacheEpoch( $reqTime, $maxAge ) { - // Ensure Last-Modified is never more than (wgSquidMaxage) in the past, + // Ensure Last-Modified is never more than $wgCdnMaxAge in the past, // because even if the wiki page content hasn't changed since, static // resources may have changed (skin HTML, interface messages, urls, etc.) // and must roll-over in a timely manner (T46570) @@ -2248,12 +2248,12 @@ class OutputPage extends ContextSource { * * @param string|int|float|bool|null $mtime Last-Modified timestamp * @param int $minTTL Minimum TTL in seconds [default: 1 minute] - * @param int $maxTTL Maximum TTL in seconds [default: $wgSquidMaxage] + * @param int $maxTTL Maximum TTL in seconds [default: $wgCdnMaxAge] * @since 1.28 */ public function adaptCdnTTL( $mtime, $minTTL = 0, $maxTTL = 0 ) { $minTTL = $minTTL ?: IExpiringStore::TTL_MINUTE; - $maxTTL = $maxTTL ?: $this->getConfig()->get( 'SquidMaxage' ); + $maxTTL = $maxTTL ?: $this->getConfig()->get( 'CdnMaxAge' ); if ( $mtime === null || $mtime === false ) { return $minTTL; // entity does not exist @@ -2567,7 +2567,7 @@ class OutputPage extends ContextSource { if ( $this->mEnableClientCache ) { if ( - $config->get( 'UseSquid' ) && + $config->get( 'UseCdn' ) && !$response->hasCookies() && !SessionManager::getGlobalSession()->isPersistent() && !$this->isPrintable() && @@ -2584,7 +2584,7 @@ class OutputPage extends ContextSource { # start with a shorter timeout for initial testing # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"'); $response->header( - "Surrogate-Control: max-age={$config->get( 'SquidMaxage' )}" . + "Surrogate-Control: max-age={$config->get( 'CdnMaxAge' )}" . "+{$this->mCdnMaxage}, content=\"ESI/1.0\"" ); $response->header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' ); diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index c9db5a88dc..c5764d2262 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -484,8 +484,8 @@ return [ 'ProxyLookup' => function ( MediaWikiServices $services ) : ProxyLookup { $mainConfig = $services->getMainConfig(); return new ProxyLookup( - $mainConfig->get( 'SquidServers' ), - $mainConfig->get( 'SquidServersNoPurge' ) + $mainConfig->get( 'CdnServers' ), + $mainConfig->get( 'CdnServersNoPurge' ) ); }, diff --git a/includes/Setup.php b/includes/Setup.php index a51cb83c19..f367fc2278 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -518,9 +518,61 @@ foreach ( LanguageCode::getNonstandardLanguageCodeMapping() as $code => $bcp47 ) // To determine the user language, use $wgLang->getCode() $wgContLanguageCode = $wgLanguageCode; +// Temporary backwards-compatibility reading of old Squid-named CDN settings as of MediaWiki 1.34, +// to support sysadmins who fail to update their settings immediately: + +if ( isset( $wgUseSquid ) ) { + // If the sysadmin is still setting a value of $wgUseSquid to true but $wgUseCdn is the default of + // false, to be safe, assume they do want this still, so enable it. + if ( !$wgUseCdn && $wgUseSquid ) { + $wgUseCdn = $wgUseSquid; + wfDeprecated( '$wgUseSquid enabled but $wgUseCdn disabled; enabling CDN functions', '1.34' ); + } +} else { + // Backwards-compatibility for extensions that read this value. + $wgUseSquid = $wgUseCdn; +} + +if ( isset( $wgSquidServers ) ) { + // If the sysadmin is still setting a value of $wgSquidServers but $wgCdnServers is the default of + // empty, to be safe, assume they do want these servers to be still used, so use them. + if ( !empty( $wgSquidServers ) && empty( $wgCdnServers ) ) { + $wgCdnServers = $wgSquidServers; + wfDeprecated( '$wgSquidServers set, $wgCdnServers empty; using them', '1.34' ); + } +} else { + // Backwards-compatibility for extensions that read this value. + $wgSquidServers = $wgCdnServers; +} + +if ( isset( $wgSquidServersNoPurge ) ) { + // If the sysadmin is still setting values in $wgSquidServersNoPurge but $wgCdnServersNoPurge is + // the default of empty, to be safe, assume they do want these servers to be still used, so use + // them. + if ( !empty( $wgSquidServersNoPurge ) && empty( $wgCdnServersNoPurge ) ) { + $wgCdnServersNoPurge = $wgSquidServersNoPurge; + wfDeprecated( '$wgSquidServersNoPurge set, $wgCdnServersNoPurge empty; using them', '1.34' ); + } +} else { + // Backwards-compatibility for extensions that read this value. + $wgSquidServersNoPurge = $wgCdnServersNoPurge; +} + +if ( isset( $wgSquidMaxage ) ) { + // If the sysadmin is still setting a value of $wgSquidMaxage and it's higher than $wgCdnMaxAge, + // to be safe, assume they want the higher (lower performance requirement) value, so use that. + if ( $wgCdnMaxAge < $wgSquidMaxage ) { + $wgCdnMaxAge = $wgSquidMaxage; + wfDeprecated( '$wgSquidMaxage set higher than $wgCdnMaxAge; using the higher value', '1.34' ); + } +} else { + // Backwards-compatibility for extensions that read this value. + $wgSquidMaxage = $wgCdnMaxAge; +} + // Easy to forget to falsify $wgDebugToolbar for static caches. // If file cache or CDN cache is on, just disable this (DWIMD). -if ( $wgUseFileCache || $wgUseSquid ) { +if ( $wgUseFileCache || $wgUseCdn ) { $wgDebugToolbar = false; } diff --git a/includes/Storage/DerivedPageDataUpdater.php b/includes/Storage/DerivedPageDataUpdater.php index bc48a0e7bd..ff5541d800 100644 --- a/includes/Storage/DerivedPageDataUpdater.php +++ b/includes/Storage/DerivedPageDataUpdater.php @@ -1582,10 +1582,10 @@ class DerivedPageDataUpdater implements IDBAccessObject { ]; $deferValues = [ false, DeferredUpdates::PRESEND, DeferredUpdates::POSTSEND ]; if ( !in_array( $options['defer'], $deferValues, true ) ) { - throw new InvalidArgumentException( 'invalid value for defer: ' . $options['defer'] ); + throw new InvalidArgumentException( 'Invalid value for defer: ' . $options['defer'] ); } - Assert::parameterType( 'integer|null', $options['transactionTicket'], - '$options[\'transactionTicket\']' ); + Assert::parameterType( + 'integer|null', $options['transactionTicket'], '$options[\'transactionTicket\']' ); $updates = $this->getSecondaryDataUpdates( $options['recursive'] ); @@ -1596,14 +1596,13 @@ class DerivedPageDataUpdater implements IDBAccessObject { $causeAction = $this->options['causeAction'] ?? 'unknown'; $causeAgent = $this->options['causeAgent'] ?? 'unknown'; $legacyRevision = new Revision( $this->revision ); + $ticket = $options['transactionTicket']; - if ( $options['defer'] === false && $options['transactionTicket'] !== null ) { + if ( $options['defer'] === false && $ticket !== null ) { // For legacy hook handlers doing updates via LinksUpdateConstructed, make sure // any pending writes they made get flushed before the doUpdate() calls below. // This avoids snapshot-clearing errors in LinksUpdate::acquirePageLock(). - $this->loadbalancerFactory->commitAndWaitForReplication( - __METHOD__, $options['transactionTicket'] - ); + $this->loadbalancerFactory->commitAndWaitForReplication( __METHOD__, $ticket ); } foreach ( $updates as $update ) { @@ -1616,8 +1615,8 @@ class DerivedPageDataUpdater implements IDBAccessObject { } if ( $options['defer'] === false ) { - if ( $update instanceof DataUpdate && $options['transactionTicket'] !== null ) { - $update->setTransactionTicket( $options['transactionTicket'] ); + if ( $update instanceof DataUpdate && $ticket !== null ) { + $update->setTransactionTicket( $ticket ); } $update->doUpdate(); } else { diff --git a/includes/Title.php b/includes/Title.php index 866f0415d8..c4fe858ac8 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -3480,6 +3480,7 @@ class Title implements LinkTarget, IDBAccessObject { /** * Move this page's subpages to be subpages of $nt * + * @deprecated since 1.34, use MovePage instead * @param Title $nt Move target * @param bool $auth Whether $wgUser's permissions should be checked * @param string $reason The reason for the move @@ -3494,7 +3495,6 @@ class Title implements LinkTarget, IDBAccessObject { public function moveSubpages( $nt, $auth = true, $reason = '', $createRedirect = true, array $changeTags = [] ) { - global $wgMaximumMovedPages; // Check permissions if ( !$this->userCan( 'move-subpages' ) ) { return [ @@ -3514,46 +3514,21 @@ class Title implements LinkTarget, IDBAccessObject { ]; } - $subpages = $this->getSubpages( $wgMaximumMovedPages + 1 ); - $retval = []; - $count = 0; - foreach ( $subpages as $oldSubpage ) { - $count++; - if ( $count > $wgMaximumMovedPages ) { - $retval[$oldSubpage->getPrefixedText()] = [ - [ 'movepage-max-pages', $wgMaximumMovedPages ], - ]; - break; - } + global $wgUser; + $mp = new MovePage( $this, $nt ); + $method = $auth ? 'moveSubpagesIfAllowed' : 'moveSubpages'; + $result = $mp->$method( $wgUser, $reason, $createRedirect, $changeTags ); - // We don't know whether this function was called before - // or after moving the root page, so check both - // $this and $nt - if ( $oldSubpage->getArticleID() == $this->getArticleID() - || $oldSubpage->getArticleID() == $nt->getArticleID() - ) { - // When moving a page to a subpage of itself, - // don't move it twice - continue; - } - $newPageName = preg_replace( - '#^' . preg_quote( $this->mDbkeyform, '#' ) . '#', - StringUtils::escapeRegexReplacement( $nt->getDBkey() ), # T23234 - $oldSubpage->getDBkey() ); - if ( $oldSubpage->isTalkPage() ) { - $newNs = $nt->getTalkPage()->getNamespace(); - } else { - $newNs = $nt->getSubjectPage()->getNamespace(); - } - # T16385: we need makeTitleSafe because the new page names may - # be longer than 255 characters. - $newSubpage = self::makeTitleSafe( $newNs, $newPageName ); + if ( !$result->isOk() ) { + return $result->getErrorsArray(); + } - $success = $oldSubpage->moveTo( $newSubpage, $auth, $reason, $createRedirect, $changeTags ); - if ( $success === true ) { - $retval[$oldSubpage->getPrefixedText()] = $newSubpage->getPrefixedText(); + $retval = []; + foreach ( $result->getValue() as $key => $status ) { + if ( $status->isOK() ) { + $retval[$key] = $status->getValue(); } else { - $retval[$oldSubpage->getPrefixedText()] = $success; + $retval[$key] = $status->getErrorsArray(); } } return $retval; diff --git a/includes/actions/RawAction.php b/includes/actions/RawAction.php index 14f7603785..505c9d5dc2 100644 --- a/includes/actions/RawAction.php +++ b/includes/actions/RawAction.php @@ -67,7 +67,7 @@ class RawAction extends FormlessAction { $contentType = $this->getContentType(); - $maxage = $request->getInt( 'maxage', $config->get( 'SquidMaxage' ) ); + $maxage = $request->getInt( 'maxage', $config->get( 'CdnMaxAge' ) ); $smaxage = $request->getIntOrNull( 'smaxage' ); if ( $smaxage === null ) { if ( diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 1a7175a3e0..b845c57b58 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -148,7 +148,7 @@ class ApiMain extends ApiBase { private $mContinuationManager; private $mAction; private $mEnableWrite; - private $mInternalMode, $mSquidMaxage; + private $mInternalMode, $mCdnMaxAge; /** @var ApiBase */ private $mModule; @@ -288,7 +288,7 @@ class ApiMain extends ApiBase { $this->mContinuationManager = null; $this->mEnableWrite = $enableWrite; - $this->mSquidMaxage = -1; // flag for executeActionWithErrorHandling() + $this->mCdnMaxAge = -1; // flag for executeActionWithErrorHandling() $this->mCommit = false; } @@ -1368,18 +1368,20 @@ class ApiMain extends ApiBase { $ts->format( 'D M j H:i:s Y' ) === $value || $ts->format( 'D M j H:i:s Y' ) === $value ) { + $config = $this->getConfig(); $lastMod = $module->getConditionalRequestData( 'last-modified' ); if ( $lastMod !== null ) { // Mix in some MediaWiki modification times $modifiedTimes = [ 'page' => $lastMod, 'user' => $this->getUser()->getTouched(), - 'epoch' => $this->getConfig()->get( 'CacheEpoch' ), + 'epoch' => $config->get( 'CacheEpoch' ), ]; - if ( $this->getConfig()->get( 'UseSquid' ) ) { + + if ( $config->get( 'UseCdn' ) ) { // T46570: the core page itself may not change, but resources might $modifiedTimes['sepoch'] = wfTimestamp( - TS_MW, time() - $this->getConfig()->get( 'SquidMaxage' ) + TS_MW, time() - $config->get( 'CdnMaxAge' ) ); } Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes, $this->getOutput() ] ); diff --git a/includes/api/ApiMove.php b/includes/api/ApiMove.php index cc4490e63f..89ecc43bd9 100644 --- a/includes/api/ApiMove.php +++ b/includes/api/ApiMove.php @@ -201,22 +201,22 @@ class ApiMove extends ApiBase { public function moveSubpages( $fromTitle, $toTitle, $reason, $noredirect, $changeTags = [] ) { $retval = []; - $success = $fromTitle->moveSubpages( $toTitle, true, $reason, !$noredirect, $changeTags ); - if ( isset( $success[0] ) ) { - $status = $this->errorArrayToStatus( $success ); - return [ 'errors' => $this->getErrorFormatter()->arrayFromStatus( $status ) ]; + $mp = new MovePage( $fromTitle, $toTitle ); + $result = + $mp->moveSubpagesIfAllowed( $this->getUser(), $reason, !$noredirect, $changeTags ); + if ( !$result->isOk() ) { + // This means the whole thing failed + return [ 'errors' => $this->getErrorFormatter()->arrayFromStatus( $result ) ]; } // At least some pages could be moved // Report each of them separately - foreach ( $success as $oldTitle => $newTitle ) { + foreach ( $result->getValue() as $oldTitle => $status ) { $r = [ 'from' => $oldTitle ]; - if ( is_array( $newTitle ) ) { - $status = $this->errorArrayToStatus( $newTitle ); - $r['errors'] = $this->getErrorFormatter()->arrayFromStatus( $status ); + if ( $status->isOK() ) { + $r['to'] = $status->getValue(); } else { - // Success - $r['to'] = $newTitle; + $r['errors'] = $this->getErrorFormatter()->arrayFromStatus( $status ); } $retval[] = $r; } diff --git a/includes/api/ApiQueryProtectedTitles.php b/includes/api/ApiQueryProtectedTitles.php index f5266850bd..8edf00cf57 100644 --- a/includes/api/ApiQueryProtectedTitles.php +++ b/includes/api/ApiQueryProtectedTitles.php @@ -135,7 +135,7 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase { if ( isset( $prop['parsedcomment'] ) ) { $vals['parsedcomment'] = Linker::formatComment( - $commentStore->getComment( 'pt_reason', $row )->text, $titles + $commentStore->getComment( 'pt_reason', $row )->text ); } diff --git a/includes/api/ApiQueryRevisions.php b/includes/api/ApiQueryRevisions.php index fc5028959f..ee6a264281 100644 --- a/includes/api/ApiQueryRevisions.php +++ b/includes/api/ApiQueryRevisions.php @@ -114,7 +114,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase { if ( $revCount > 0 && $enumRevMode ) { $this->dieWithError( - [ 'apierror-revisions-nolist', $this->getModulePrefix() ], 'invalidparammix' + [ 'apierror-revisions-norevids', $this->getModulePrefix() ], 'invalidparammix' ); } @@ -389,6 +389,10 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase { $this->addOption( 'LIMIT', $this->limit + 1 ); + // T224017: `rev_timestamp` is never the correct index to use for this module, but + // MariaDB (10.1.37-39) sometimes insists on trying to use it anyway. Tell it not to. + $this->addOption( 'IGNORE INDEX', [ 'revision' => 'rev_timestamp' ] ); + $count = 0; $generated = []; $hookData = []; diff --git a/includes/api/i18n/mk.json b/includes/api/i18n/mk.json index 912f026c44..fa4110e0f4 100644 --- a/includes/api/i18n/mk.json +++ b/includes/api/i18n/mk.json @@ -68,7 +68,7 @@ "apihelp-edit-param-text": "Содржина на страницата.", "apihelp-edit-param-summary": "Опис на уредувањето. Ова е и назив на поднасловот кога не се зададени $1section=new и $1sectiontitle.", "apihelp-edit-param-tags": "Ознаки за измена што се однесуваат на преработката.", - "apihelp-edit-param-minor": "Ситно уредување.", + "apihelp-edit-param-minor": "Означи го уредувањево како ситно.", "apihelp-edit-param-notminor": "Неситно уредување.", "apihelp-edit-param-bot": "Означи го уредувањето како ботовско.", "apihelp-edit-param-basetimestamp": "Датум и време на преработката на базата, кои се користат за утврдување на спротиставености во уредувањето. Може да се добие преку [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].", diff --git a/includes/cache/localisation/LocalisationCache.php b/includes/cache/localisation/LocalisationCache.php index 788eec345e..bb84f97289 100644 --- a/includes/cache/localisation/LocalisationCache.php +++ b/includes/cache/localisation/LocalisationCache.php @@ -108,14 +108,15 @@ class LocalisationCache { */ public static $allKeys = [ 'fallback', 'namespaceNames', 'bookstoreList', - 'magicWords', 'messages', 'rtl', 'capitalizeAllNouns', 'digitTransformTable', - 'separatorTransformTable', 'minimumGroupingDigits', - 'fallback8bitEncoding', 'linkPrefixExtension', - 'linkTrail', 'linkPrefixCharset', 'namespaceAliases', - 'dateFormats', 'datePreferences', 'datePreferenceMigrationMap', - 'defaultDateFormat', 'extraUserToggles', 'specialPageAliases', - 'imageFiles', 'preloadedMessages', 'namespaceGenderAliases', - 'digitGroupingPattern', 'pluralRules', 'pluralRuleTypes', 'compiledPluralRules', + 'magicWords', 'messages', 'rtl', 'capitalizeAllNouns', + 'digitTransformTable', 'separatorTransformTable', + 'minimumGroupingDigits', 'fallback8bitEncoding', + 'linkPrefixExtension', 'linkTrail', 'linkPrefixCharset', + 'namespaceAliases', 'dateFormats', 'datePreferences', + 'datePreferenceMigrationMap', 'defaultDateFormat', + 'specialPageAliases', 'imageFiles', 'preloadedMessages', + 'namespaceGenderAliases', 'digitGroupingPattern', 'pluralRules', + 'pluralRuleTypes', 'compiledPluralRules', ]; /** @@ -129,7 +130,7 @@ class LocalisationCache { /** * Keys for items which are a numbered array. */ - public static $mergeableListKeys = [ 'extraUserToggles' ]; + public static $mergeableListKeys = []; /** * Keys for items which contain an array of arrays of equivalent aliases diff --git a/includes/clientpool/SquidPurgeClient.php b/includes/clientpool/SquidPurgeClient.php index 75f51ef7e3..6b5482cf8d 100644 --- a/includes/clientpool/SquidPurgeClient.php +++ b/includes/clientpool/SquidPurgeClient.php @@ -150,7 +150,7 @@ class SquidPurgeClient { if ( IP::isIPv4( $this->host ) ) { $this->ip = $this->host; } elseif ( IP::isIPv6( $this->host ) ) { - throw new MWException( '$wgSquidServers does not support IPv6' ); + throw new MWException( '$wgCdnServers does not support IPv6' ); } else { Wikimedia\suppressWarnings(); $this->ip = gethostbyname( $this->host ); diff --git a/includes/debug/logger/LegacyLogger.php b/includes/debug/logger/LegacyLogger.php index bbcd33ac75..72c7643418 100644 --- a/includes/debug/logger/LegacyLogger.php +++ b/includes/debug/logger/LegacyLogger.php @@ -21,12 +21,14 @@ namespace MediaWiki\Logger; use DateTimeZone; +use Error; use Exception; use WikiMap; use MWDebug; use MWExceptionHandler; use Psr\Log\AbstractLogger; use Psr\Log\LogLevel; +use Throwable; use UDPTransport; /** @@ -269,7 +271,7 @@ class LegacyLogger extends AbstractLogger { $e = $context['exception']; $backtrace = false; - if ( $e instanceof Exception ) { + if ( $e instanceof Throwable || $e instanceof Exception ) { $backtrace = MWExceptionHandler::getRedactedTrace( $e ); } elseif ( is_array( $e ) && isset( $e['trace'] ) ) { @@ -405,8 +407,9 @@ class LegacyLogger extends AbstractLogger { return $item->format( 'c' ); } - if ( $item instanceof Exception ) { - return '[Exception ' . get_class( $item ) . '( ' . + if ( $item instanceof Throwable || $item instanceof Exception ) { + $which = $item instanceof Error ? 'Error' : 'Exception'; + return '[' . $which . ' ' . get_class( $item ) . '( ' . $item->getFile() . ':' . $item->getLine() . ') ' . $item->getMessage() . ']'; } diff --git a/includes/debug/logger/monolog/LineFormatter.php b/includes/debug/logger/monolog/LineFormatter.php index 8537d71f99..d0748bc5a9 100644 --- a/includes/debug/logger/monolog/LineFormatter.php +++ b/includes/debug/logger/monolog/LineFormatter.php @@ -20,9 +20,11 @@ namespace MediaWiki\Logger\Monolog; +use Error; use Exception; use Monolog\Formatter\LineFormatter as MonologLineFormatter; use MWExceptionHandler; +use Throwable; /** * Formats incoming records into a one-line string. @@ -32,7 +34,7 @@ use MWExceptionHandler; * excluded from '%context%' output if the '%exception%' placeholder is * present. * - * Exceptions that are logged with this formatter will optional have their + * Throwables that are logged with this formatter will optional have their * stack traces appended. If that is done, MWExceptionHandler::redactedTrace() * will be used to redact the trace information. * @@ -75,7 +77,7 @@ class LineFormatter extends MonologLineFormatter { $e = $record['context']['exception']; unset( $record['context']['exception'] ); - if ( $e instanceof Exception ) { + if ( $e instanceof Throwable || $e instanceof Exception ) { $prettyException = $this->normalizeException( $e ); } elseif ( is_array( $e ) ) { $prettyException = $this->normalizeExceptionArray( $e ); @@ -93,9 +95,9 @@ class LineFormatter extends MonologLineFormatter { } /** - * Convert an Exception to a string. + * Convert a Throwable to a string. * - * @param Exception $e + * @param Exception|Throwable $e * @return string */ protected function normalizeException( $e ) { @@ -103,12 +105,12 @@ class LineFormatter extends MonologLineFormatter { } /** - * Convert an exception to an array of structured data. + * Convert a throwable to an array of structured data. * - * @param Exception $e + * @param Exception|Throwable $e * @return array */ - protected function exceptionAsArray( Exception $e ) { + protected function exceptionAsArray( $e ) { $out = [ 'class' => get_class( $e ), 'message' => $e->getMessage(), @@ -127,7 +129,7 @@ class LineFormatter extends MonologLineFormatter { } /** - * Convert an array of Exception data to a string. + * Convert an array of Throwable data to a string. * * @param array $e * @return string @@ -142,7 +144,8 @@ class LineFormatter extends MonologLineFormatter { ]; $e = array_merge( $defaults, $e ); - $str = "\n[Exception {$e['class']}] (" . + $which = is_a( $e['class'], Error::class, true ) ? 'Error' : 'Exception'; + $str = "\n[$which {$e['class']}] (" . "{$e['file']}:{$e['line']}) {$e['message']}"; if ( $this->includeStacktraces && $e['trace'] ) { @@ -154,7 +157,8 @@ class LineFormatter extends MonologLineFormatter { $prev = $e['previous']; while ( $prev ) { $prev = array_merge( $defaults, $prev ); - $str .= "\nCaused by: [Exception {$prev['class']}] (" . + $which = is_a( $prev['class'], Error::class, true ) ? 'Error' : 'Exception'; + $str .= "\nCaused by: [$which {$prev['class']}] (" . "{$prev['file']}:{$prev['line']}) {$prev['message']}"; if ( $this->includeStacktraces && $prev['trace'] ) { diff --git a/includes/deferred/CdnCacheUpdate.php b/includes/deferred/CdnCacheUpdate.php index 2d07f75156..66ce9a3ddf 100644 --- a/includes/deferred/CdnCacheUpdate.php +++ b/includes/deferred/CdnCacheUpdate.php @@ -79,14 +79,14 @@ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate { } /** - * Purges a list of CDN nodes defined in $wgSquidServers. + * Purges a list of CDN nodes defined in $wgCdnServers. * $urlArr should contain the full URLs to purge as values * (example: $urlArr[] = 'http://my.host/something') * * @param string[] $urlArr List of full URLs to purge */ public static function purge( array $urlArr ) { - global $wgSquidServers, $wgHTCPRouting; + global $wgCdnServers, $wgHTCPRouting; if ( !$urlArr ) { return; @@ -120,20 +120,20 @@ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate { } // Do direct server purges if enabled (this does not scale very well) - if ( $wgSquidServers ) { - // Maximum number of parallel connections per squid - $maxSocketsPerSquid = 8; + if ( $wgCdnServers ) { + // Maximum number of parallel connections per CDN + $maxSocketsPerCdn = 8; // Number of requests to send per socket // 400 seems to be a good tradeoff, opening a socket takes a while $urlsPerSocket = 400; - $socketsPerSquid = ceil( count( $urlArr ) / $urlsPerSocket ); - if ( $socketsPerSquid > $maxSocketsPerSquid ) { - $socketsPerSquid = $maxSocketsPerSquid; + $socketsPerCdn = ceil( count( $urlArr ) / $urlsPerSocket ); + if ( $socketsPerCdn > $maxSocketsPerCdn ) { + $socketsPerCdn = $maxSocketsPerCdn; } $pool = new SquidPurgeClientPool; - $chunks = array_chunk( $urlArr, ceil( count( $urlArr ) / $socketsPerSquid ) ); - foreach ( $wgSquidServers as $server ) { + $chunks = array_chunk( $urlArr, ceil( count( $urlArr ) / $socketsPerCdn ) ); + foreach ( $wgCdnServers as $server ) { foreach ( $chunks as $chunk ) { $client = new SquidPurgeClient( $server ); foreach ( $chunk as $url ) { diff --git a/includes/htmlform/HTMLForm.php b/includes/htmlform/HTMLForm.php index f5be83fc1a..504202845a 100644 --- a/includes/htmlform/HTMLForm.php +++ b/includes/htmlform/HTMLForm.php @@ -1062,10 +1062,10 @@ class HTMLForm extends ContextSource { } /** - * Set whether the HTML form can be collapsed. + * Enable collapsible mode, and set whether the form is collapsed by default. * * @since 1.34 - * @param bool $collapsedByDefault (optional) whether the form is collapsed by default + * @param bool $collapsedByDefault Whether the form is collapsed by default (optional). * @return HTMLForm $this for chaining calls */ public function setCollapsibleOptions( $collapsedByDefault = false ) { diff --git a/includes/installer/i18n/nb.json b/includes/installer/i18n/nb.json index 8dec5665cf..fc299fb91c 100644 --- a/includes/installer/i18n/nb.json +++ b/includes/installer/i18n/nb.json @@ -70,9 +70,9 @@ "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] er installert", "config-no-cache-apcu": "Advarsel: Kunne ikke finne [https://www.php.net/apcu APCu] eller [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nObjekthurtiglagring er ikke aktivert.", "config-mod-security": "'''Advarsel''': Din web-tjener har [https://modsecurity.org/ mod_security] påslått. Hvis denne er feilinnstilt, kan det gi problemer for MediaWiki eller annen programvare som tillater brukere å poste vilkårlig innhold.\nSjekk [https://modsecurity.org/documentation/ mod_security-dokumentasjonen] eller ta kontakt med din nettleverandør hvis du opplever tilfeldige feil.", - "config-diff3-bad": "GNU diff3 ikke funnet.", + "config-diff3-bad": "GNU diff3 ikke funnet. Du kan ignorere dette for øyeblikket, men du kan støte på redigeringskonflikter oftere.", "config-git": "Har funnet Git version control software: $1.", - "config-git-bad": "Git version control software ble ikke funnet.", + "config-git-bad": "Git version control software ble ikke funnet. Du kan ignorere dette for øyeblikket. Merk at Special:Version ikke vil vise hashverdien for commits.", "config-imagemagick": "Fant ImageMagick: $1.\nBildeminiatyrisering vil aktiveres om du aktiverer opplastinger.", "config-gd": "Fant innebygd GD-grafikkbibliotek.\nBildeminiatyrisering vil aktiveres om du aktiverer opplastinger.", "config-no-scaling": "Kunne ikke finne GD-bibliotek eller ImageMagick.\nBildeminiatyrisering vil være deaktivert.", @@ -87,11 +87,11 @@ "config-using-32bit": "Adversel: Systemet ditt ser ut til å være 32-bit-basert, mens dette er [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit not advised].", "config-db-type": "Databasetype:", "config-db-host": "Databasevert:", - "config-db-host-help": "Hvis databasen kjører på en annen tjenermaskin, skriv inn vertsnavnet eller IP-adressen her.\n\nHvis du bruker et webhotell, vil du kunne be om aktuelt vertsnavn fra din leverandør.\n\nHvis du installerer på en Windowstjener og bruker MySQL, kan det hende at «localhost» ikke brukes som tjenernavn. Hvis så er tilfelle, prøv «127.0.0.1» som lokal IP-adresse.\n\nHvis du bruker PostgreSQL, la dette feltet være blankt slik at koplingen gjøres via en \"Unix socket\".", + "config-db-host-help": "Hvis databasen kjører på en annen tjenermaskin, skriv inn vertsnavnet eller IP-adressen her.\n\nHvis du bruker et webhotell, vil du kunne be om aktuelt vertsnavn fra din leverandør.\n\nHvis du bruker MySQL, kan det hende at «localhost» ikke brukes som tjenernavn. Hvis så er tilfelle, prøv «127.0.0.1» som lokal IP-adresse.\n\nHvis du bruker PostgreSQL, la dette feltet være blankt slik at koplingen gjøres via en \"Unix socket\".", "config-db-host-oracle": "Database TNS:", "config-db-host-oracle-help": "Skriv inn et gyldig [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm Local Connect Name]; en tnsnames.ora-fil må være synlig for installasjonsprosessen.
Hvis du bruker klientbibliotek 10g eller nyere kan du også bruke navngivingsmetoden [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Easy Connect].", "config-db-wiki-settings": "Identifiser denne wikien", - "config-db-name": "Databasenavn:", + "config-db-name": "Databasenavn (ingen bindestreker):", "config-db-name-help": "Velg et navn som identifiserer wikien din.\nDet bør ikke inneholde mellomrom.\n\nHvis du bruker en delt nettvert vil verten din enten gi deg et spesifikt databasenavn å bruke, eller la deg opprette databaser via kontrollpanelet.", "config-db-name-oracle": "Databaseskjema:", "config-db-account-oracle-warn": "Det finnes tre mulig fremgangsmåter for å installere Oracle som database:\n\nHvis du ønsker å opprette en databasekonto som del av installasjonsprosessen, oppgi da en konto med SYSDBA-rolle som databasekonto for installasjonen og angi påkrevd autentiseringsinformasjon for web-aksesskontoen. Ellers kan du enten opprette web-aksesskontoen manuelt eller kun oppgi den kontoen (hvis den har påkrevede tillatelser for å opprette skjemeobjektene) , alternativt oppgi to ulike kontoer, en med opprettelsesprivilegier (create) og en begrenset konto for web-aksess.\n\nSkript for å opprette en konto med påkrevde privilegier finnes i \"maintenance/oracle/\"-folderen av denne installasjonen. Husk at det å bruke en begrenset konto vil blokkere all vedlikeholdsfunksjonalitet med standard konto.", @@ -104,11 +104,11 @@ "config-db-account-lock": "Bruk det samme brukernavnet og passordet under normal drift", "config-db-wiki-account": "Brukerkonto for normal drift", "config-db-wiki-help": "Skriv inn brukernavnet og passordet som vil bli brukt til å koble til databasen under normal wikidrift.\nHvis kontoen ikke finnes, og installasjonskontoen har tilstrekkelige privilegier, vil denne brukerkontoen bli opprettet med et minimum av privilegier, tilstrekkelig for å operere wikien.", - "config-db-prefix": "Databasetabellprefiks:", + "config-db-prefix": "Databasetabellprefiks (ingen bindestreker):", "config-db-prefix-help": "Hvis du trenger å dele en database mellom flere wikier, eller mellom MediaWiki og andre nettapplikasjoner, kan du velge å legge til et prefiks til alle tabellnavnene for å unngå konflikter.\nIkke bruk mellomrom.\n\nDette feltet er vanligvis tomt.", "config-mysql-old": "MySQL $1 eller senere kreves, du har $2.", "config-db-port": "Databaseport:", - "config-db-schema": "Skjema for MediaWiki", + "config-db-schema": "Skjema for MediaWiki (ingen bindestreker):", "config-db-schema-help": "Dette skjemaet er som regel riktig.\nBare endre det hvis du vet at du trenger det.", "config-pg-test-error": "Får ikke kontakt med database '''$1''': $2", "config-sqlite-dir": "SQLite datamappe:", @@ -138,7 +138,7 @@ "config-invalid-db-server-oracle": "Ugyldig database-TNS «$1».\nBruk enten \"TNS Name\" eller en \"Easy Connect\"-streng ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Oracle Naming Methods])", "config-invalid-db-name": "Ugyldig databasenavn «$1».\nBruk bare ASCII-bokstaver (a-z, A-Z), tall (0-9), undestreker (_) og bindestreker (-).", "config-invalid-db-prefix": "Ugyldig databaseprefiks «$1».\nBruk bare ASCII-bokstaver (a-z, A-Z), tall (0-9), undestreker (_) og bindestreker (-).", - "config-connection-error": "$1.\n\nSjekk verten, brukernavnet og passordet nedenfor og prøv igjen.", + "config-connection-error": "$1.\n\nSjekk verten, brukernavnet og passordet nedenfor og prøv igjen. Hvis du brukte «localhost» som databasevert, prøv å bruke «127.0.0.1» i stedet (eller motsatt).", "config-invalid-schema": "Ugyldig skjema for MediaWiki «$1».\nBruk bare ASCII-bokstaver (a-z, A-Z), tall (0-9) og undestreker (_).", "config-db-sys-create-oracle": "Installasjonsprogrammet støtter kun bruk av en SYSDBA-konto for opprettelse av en ny konto.", "config-db-sys-user-exists-oracle": "Brukerkontoen «$1» finnes allerede. SYSDBA kan kun brukes for oppretting av nye kontoer!", @@ -154,6 +154,7 @@ "config-sqlite-cant-create-db": "Kunne ikke opprette databasefilen $1.", "config-sqlite-fts3-downgrade": "PHP mangler FTS3-støtte, nedgraderer tabeller", "config-can-upgrade": "Det er MediaWiki-tabeller i denne databasen.\nFor å oppgradere dem til MediaWiki $1, klikk '''Fortsett'''.", + "config-upgrade-error": "En feil oppsto under oppgradering av MediaWiki-tabeller i databasen din.\n\nFor mer informasjon, se på loggen ovenfor; klikk Fortsett for å prøve igjen.", "config-upgrade-done": "Oppgradering fullført.\n\nDu kan nå [$1 begynne å bruke wikien din].\n\nHvis du ønsker å regenerere LocalSettings.php-filen din, klikk på knappen nedenfor.\nDette er '''ikke anbefalt''' med mindre du har problemer med wikien din.", "config-upgrade-done-no-regenerate": "Oppgradering fullført.\n\nDu kan nå [$1 begynne å bruke wikien din].", "config-regenerate": "Regenerer LocalSettings.php →", @@ -309,6 +310,7 @@ "config-install-done": "Gratulrerer!\nDu har lykkes i å installere MediaWiki.\n\nInstallasjonsprogrammet har generert en LocalSettings.php-fil.\nDen inneholder alle dine konfigureringer.\n\nDu må laste den ned og legge den på hovedfolderen for din wiki-installasjon (der index.php ligger). Nedlastingen skulle ha startet automatisk.\n\nHvis ingen nedlasting ble tilbudt, eller du avbrøt den, kan du få den i gang ved å klikke på lenken under:\n\n$3\n\nOBS: Hvis du ikke gjør dette nå, vil den genererte konfigurasjonsfilen ikke være tilgjengelig for deg senere.\n\nNår dette er gjort, kan du [$2 gå inn i wikien].", "config-install-done-path": "Gratulerer!\nDu har installert MediaWiki.\n\nInstallereren har generert en LocalSettings.php-fil.\nDen inneholder all konfigurasjonen for wikien.\n\nDu må laste den ned og legge den i $4. Nedlastingen skal ha startet automatisk.\n\nOm nedlastingen ikke ble startet, eller om du avbrøt den, kan du starte på nytt ved å klikke lenken nedenfor:\n\n$3\n\nMerk: Om du ikke gjør dette nå vil den genererte konfigurasjonen ikke være tilgjengelig senere.\n\nNår dette er gjort kan du [$2 gå til wikien din].", "config-install-success": "MediaWiki har blitt installert. Du kan nå\nbesøke <$1$2> for å se wikien din.\nOm du har spørsmål, sjekk de ofte stilte spørsmålene:\n eller bruk et av\nsupportforumene som lenkes til fra den siden.", + "config-install-db-success": "Databasen ble satt opp", "config-download-localsettings": "Last ned LocalSettings.php", "config-help": "hjelp", "config-help-tooltip": "klikk for å utvide", diff --git a/includes/jobqueue/jobs/RefreshLinksJob.php b/includes/jobqueue/jobs/RefreshLinksJob.php index b1c805b4a4..a0b6e07aef 100644 --- a/includes/jobqueue/jobs/RefreshLinksJob.php +++ b/includes/jobqueue/jobs/RefreshLinksJob.php @@ -280,8 +280,7 @@ class RefreshLinksJob extends Job { // Carry over cause so the update can do extra logging 'causeAction' => $this->params['causeAction'], 'causeAgent' => $this->params['causeAgent'], - 'defer' => false, - 'transactionTicket' => $ticket, + 'transactionTicket' => $ticket ]; if ( !empty( $this->params['triggeringUser'] ) ) { $userInfo = $this->params['triggeringUser']; diff --git a/includes/preferences/DefaultPreferencesFactory.php b/includes/preferences/DefaultPreferencesFactory.php index b18088f481..1ba6d99429 100644 --- a/includes/preferences/DefaultPreferencesFactory.php +++ b/includes/preferences/DefaultPreferencesFactory.php @@ -496,18 +496,6 @@ class DefaultPreferencesFactory implements PreferencesFactory { } } - // Stuff from Language::getExtraUserToggles() - // FIXME is this dead code? $extraUserToggles doesn't seem to be defined for any language - $toggles = $this->contLang->getExtraUserToggles(); - - foreach ( $toggles as $toggle ) { - $defaultPreferences[$toggle] = [ - 'type' => 'toggle', - 'section' => 'personal/i18n', - 'label-message' => "tog-$toggle", - ]; - } - // show a preview of the old signature first $oldsigWikiText = MediaWikiServices::getInstance()->getParser()->preSaveTransform( '~~~', diff --git a/includes/resourceloader/ResourceLoaderModule.php b/includes/resourceloader/ResourceLoaderModule.php index 53ed133be2..66a4edfb1c 100644 --- a/includes/resourceloader/ResourceLoaderModule.php +++ b/includes/resourceloader/ResourceLoaderModule.php @@ -504,10 +504,11 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface { 'md_skin' => $vary, 'md_deps' => $deps, ], - [ 'md_module', 'md_skin' ], + [ [ 'md_module', 'md_skin' ] ], [ 'md_deps' => $deps, - ] + ], + __METHOD__ ); if ( $dbw->trxLevel() ) { diff --git a/includes/specials/SpecialBlockList.php b/includes/specials/SpecialBlockList.php index 4e541c9581..8c6ad2d074 100644 --- a/includes/specials/SpecialBlockList.php +++ b/includes/specials/SpecialBlockList.php @@ -45,7 +45,7 @@ class SpecialBlockList extends SpecialPage { $this->outputHeader(); $out = $this->getOutput(); $out->setPageTitle( $this->msg( 'ipblocklist' ) ); - $out->addModuleStyles( [ 'mediawiki.special', 'mediawiki.special.blocklist' ] ); + $out->addModuleStyles( [ 'mediawiki.special' ] ); $request = $this->getRequest(); $par = $request->getVal( 'ip', $par ); diff --git a/includes/specials/SpecialSearch.php b/includes/specials/SpecialSearch.php index 4adc2475e1..ed83aafd53 100644 --- a/includes/specials/SpecialSearch.php +++ b/includes/specials/SpecialSearch.php @@ -290,6 +290,7 @@ class SpecialSearch extends SpecialPage { } $out = $this->getOutput(); + $widgetOptions = $this->getConfig()->get( 'SpecialSearchFormOptions' ); $formWidget = new MediaWiki\Widget\Search\SearchFormWidget( $this, $this->searchConfig, @@ -308,7 +309,7 @@ class SpecialSearch extends SpecialPage { // only do the form render here for the empty $term case. Rendering // the form when a search is provided is repeated below. $out->addHTML( $formWidget->render( - $this->profile, $term, 0, 0, $this->offset, $this->isPowerSearch() + $this->profile, $term, 0, 0, $this->offset, $this->isPowerSearch(), $widgetOptions ) ); return; } @@ -365,7 +366,7 @@ class SpecialSearch extends SpecialPage { // start rendering the page $out->enableOOUI(); $out->addHTML( $formWidget->render( - $this->profile, $term, $num, $totalRes, $this->offset, $this->isPowerSearch() + $this->profile, $term, $num, $totalRes, $this->offset, $this->isPowerSearch(), $widgetOptions ) ); // did you mean... suggestions diff --git a/includes/specials/pagers/ImageListPager.php b/includes/specials/pagers/ImageListPager.php index ea55568fd2..8f31f3e630 100644 --- a/includes/specials/pagers/ImageListPager.php +++ b/includes/specials/pagers/ImageListPager.php @@ -513,7 +513,7 @@ class ImageListPager extends TablePager { return $this->getLanguage()->formatNum( intval( $value ) + 1 ); case 'top': // Messages: listfiles-latestversion-yes, listfiles-latestversion-no - return $this->msg( 'listfiles-latestversion-' . $value ); + return $this->msg( 'listfiles-latestversion-' . $value )->escaped(); default: throw new MWException( "Unknown field '$field'" ); } diff --git a/includes/widget/SearchInputWidget.php b/includes/widget/SearchInputWidget.php index d4ffed2c8c..2f0c23deeb 100644 --- a/includes/widget/SearchInputWidget.php +++ b/includes/widget/SearchInputWidget.php @@ -14,6 +14,7 @@ class SearchInputWidget extends TitleInputWidget { protected $validateTitle = false; protected $highlightFirst = false; protected $dataLocation = 'header'; + protected $showDescriptions = false; /** * @param array $config Configuration options @@ -41,6 +42,10 @@ class SearchInputWidget extends TitleInputWidget { $this->dataLocation = $config['dataLocation']; } + if ( !empty( $config['showDescriptions'] ) ) { + $this->showDescriptions = true; + } + // Initialization $this->addClasses( [ 'mw-widget-searchInputWidget' ] ); } @@ -58,6 +63,9 @@ class SearchInputWidget extends TitleInputWidget { if ( $this->dataLocation ) { $config['dataLocation'] = $this->dataLocation; } + if ( $this->showDescriptions ) { + $config['showDescriptions'] = true; + } $config['$overlay'] = true; return parent::getConfig( $config ); } diff --git a/includes/widget/search/SearchFormWidget.php b/includes/widget/search/SearchFormWidget.php index 7c28b5efe7..62ee9cb6f1 100644 --- a/includes/widget/search/SearchFormWidget.php +++ b/includes/widget/search/SearchFormWidget.php @@ -40,6 +40,7 @@ class SearchFormWidget { * @param int $totalResults The total estimated results found * @param int $offset Current offset in search results * @param bool $isPowerSearch Is the 'advanced' section open? + * @param array $options Widget options * @return string HTML */ public function render( @@ -48,7 +49,8 @@ class SearchFormWidget { $numResults, $totalResults, $offset, - $isPowerSearch + $isPowerSearch, + array $options = [] ) { $user = $this->specialSearch->getUser(); @@ -63,7 +65,7 @@ class SearchFormWidget { ] ) . '
' . - $this->shortDialogHtml( $profile, $term, $numResults, $totalResults, $offset ) . + $this->shortDialogHtml( $profile, $term, $numResults, $totalResults, $offset, $options ) . '
' . "
" . "
" . @@ -81,12 +83,20 @@ class SearchFormWidget { * @param int $numResults The number of results shown * @param int $totalResults The total estimated results found * @param int $offset Current offset in search results + * @param array $options Widget options * @return string HTML */ - protected function shortDialogHtml( $profile, $term, $numResults, $totalResults, $offset ) { + protected function shortDialogHtml( + $profile, + $term, + $numResults, + $totalResults, + $offset, + array $options = [] + ) { $html = ''; - $searchWidget = new SearchInputWidget( [ + $searchWidget = new SearchInputWidget( $options + [ 'id' => 'searchText', 'name' => 'search', 'autofocus' => trim( $term ) === '', diff --git a/languages/Language.php b/languages/Language.php index 2262fa775e..6c8b19ed80 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -814,7 +814,8 @@ class Language { * @return array */ public function getExtraUserToggles() { - return (array)self::$dataCache->getItem( $this->mCode, 'extraUserToggles' ); + wfDeprecated( __METHOD__, '1.34' ); + return []; } /** diff --git a/languages/i18n/bjn.json b/languages/i18n/bjn.json index 4af0bd42f4..52d5c0645a 100644 --- a/languages/i18n/bjn.json +++ b/languages/i18n/bjn.json @@ -17,29 +17,29 @@ "tog-hideminor": "Sungkupakan babakan sapalih dalam paubahan pahanyarnya", "tog-hidepatrolled": "Sungkupakan babakan taawasi dalam paubahan pahanyarnya", "tog-newpageshidepatrolled": "Sungkupakan tungkaran nang diitihi matan daptar tungkaran hanyar", - "tog-hidecategorization": "Patak tumbungnya tungkaran", + "tog-hidecategorization": "Tukupakan pamilahan halaman", "tog-extendwatchlist": "Singkaiakan daptar itihan hagan manampaiakan samunyaan paubahan, kada nang hanyar haja.", - "tog-usenewrc": "Garumbungakan babakan di tampilan paubahan pahanyarnya wan daptar itihan badasar tungkaran", + "tog-usenewrc": "Galambangakan babakan di tampilan paubahan pahanyarnya wan daptar itihan badasar halaman", "tog-numberheadings": "Bari numur judul utumatis", - "tog-editondblclick": "Babak tungkaran wan dua kali klik", + "tog-editondblclick": "Babak halaman wan dua kali kalik", "tog-editsectiononrightclick": "Kawa'akan mambabak sub-hagian lawan mang-klik kanan pada judul hagian", - "tog-watchcreations": "Tambahi tungkaran nang ulun ulah ka daptar itihan", - "tog-watchdefault": "Tambahi tungkaran nang ulun babak ka daptar itihan ulun", - "tog-watchmoves": "Tambahi tungkaran nang ulun pindah ka daptar itihan ulun", - "tog-watchdeletion": "Tambahi tungkaran nang ulun hapus ka daptar itihan ulun", + "tog-watchcreations": "Tambahi halaman nang ulun ulah ka daptar itihan", + "tog-watchdefault": "Tambahi halaman nang ulun babak ka daptar itihan ulun", + "tog-watchmoves": "Tambahi halaman nang ulun pindah ka daptar itihan ulun", + "tog-watchdeletion": "Tambahi halaman nang ulun hapus ka daptar itihan ulun", "tog-watchuploads": "Tambahi barakas hanyar nang ulun unggah ka daptar itihan ulun", - "tog-watchrollback": "Tambahi tungkaran nang suah ulun bulikakan ka dalam daptar itihan ulun", + "tog-watchrollback": "Tambahi halaman nang suah ulun bulikakan ka dalam daptar itihan ulun", "tog-minordefault": "Tandai samunyaan babakan sawagai babakan sapalih sacara baku", "tog-previewontop": "Tampaiakan titilikan sabalum kutak babak", "tog-previewonfirst": "Tampaiakan titilikan pada babakan panambaian", - "tog-enotifwatchlistpages": "Kirimi ulun sur-él amun sabuting tungkaran dalam daptar itihan ulun baubah", + "tog-enotifwatchlistpages": "Kirimi ulun sur-él amun sabuting halaman dalam daptar itihan ulun baubah", "tog-enotifusertalkpages": "Surili ulun amun tungkaran pamandiran ulun baubah", "tog-enotifminoredits": "Kirimi ulun sur-él jua amun ada babakan sapalih", "tog-enotifrevealaddr": "Tampaiakan alamat sur-él ulun pada sur-él pamadahan", "tog-shownumberswatching": "Tampaiakan barapa pamakai nang maitihi", "tog-oldsig": "Tandateken nang sudah ada:", "tog-fancysig": "Tapsirakan tandatangan sawagai naskah wiki (kada batautan utumatis)", - "tog-uselivepreview": "Tampaiakan pratayang tanpa mamuat baasa tungkaran", + "tog-uselivepreview": "Tampaiakan titilikan tanpa mamuat baasa halaman", "tog-forceeditsummary": "Ingatakan ulun wayah babuat sabuting kasimpulan babakan puang", "tog-watchlisthideown": "Sungkupakan babakan ulun di daptar itihan", "tog-watchlisthidebots": "Sungkupakan babakan bot di daptar itihan", @@ -124,7 +124,7 @@ "category-file-count-limited": "Tumbung ngini baisi {{PLURAL:$1|barakas|$1 barakas}} barikut.", "listingcontinuesabbrev": "samb.", "index-category": "Tungkaran tasusun bapadalakan kata", - "noindex-category": "Tungkaran nang diindéks", + "noindex-category": "Halaman nang diindéks", "broken-file-category": "Tutungkaran lawan tatautan barakas pagat", "about": "Pasal", "article": "Tungkaran isi", @@ -132,7 +132,7 @@ "cancel": "Walangi", "moredotdotdot": "Lainnya...", "morenotlisted": "Daptar ngini mungkin kada langkap", - "mypage": "Tungkaran", + "mypage": "Halaman", "mytalk": "Pamandiran", "anontalk": "Pamandiran", "navigation": "Napigasi", @@ -297,12 +297,12 @@ "viewsource-title": "Tiringi asalmula matan $1", "actionthrottled": "Kalakuan dikiripi", "actionthrottledtext": "Pian dibatasi gasan manggawi tindakan ngini talalu banyak dalam waktu handap, wan Pian sudah limpua batas nang dibarii. Silahkan cuba baasa imbah babarapa manit.", - "protectedpagetext": "Tungkaran ngini sudah disunduk gasan mancagah babakan.", + "protectedpagetext": "Halaman ngini sudah disunduk gasan mancagah babakan.", "viewsourcetext": "Pian kawa manjanaki wan manyalin asal-mula halaman ngini.", - "viewyourtext": "Pian kawa maniringi wan manyalin asalmula matan '''babakan pian''' ka tungkaran ngini:", - "protectedinterface": "Tungkaran ngini manyadiakan naskah antarmuha gasan parangkat lunak, wan dilindungi tahadap panyalahpakaian. Gasan manambah atawa mambabak tarjamahan pada sabarataan wiki, muhun pakai [https://translatewiki.net translatewiki.net], pruyik palukalan MediaWiki.", + "viewyourtext": "Pian kawa manjanaki wan manyalin asalmula matan '''babakan pian''' ka halaman ngini:", + "protectedinterface": "Halaman ngini manyadiakan naskah antarmuha gasan parangkat lunak, wan dilindungi tahadap panyalahgunaan. Gasan manambah atawa mambabak tarjamahan pada sabarataan wiki, muhun pakai [https://translatewiki.net translatewiki.net], rangka-gawi palokalan MediaWiki.", "editinginterface": "'''Paringatan:''' Pian mambabak sabuting tungkaran nang dipuruk hagan manyadiakan naskah antarmuha gasan parangkat lunak.\nPaubahan ka tungkaran ngini akan bapangaruh matan tampaian antarmuha gasan pamakai lain.\nGasan tarjamahan, muhun pakai [https://translatewiki.net/wiki/Main_Page?setlang=bjn translatewiki.net], rangka gawian palokalan MediaWiki.", - "cascadeprotected": "Tungkaran ini sudah dilindungi matan pambabakan, maraga nangini tamasuk dalam {{PLURAL:$1|tungkaran|tutungkaran}} dudi nang dilindungi \"barénténg\": $2", + "cascadeprotected": "Halaman ini sudah dilindungi matan pambabakan, maraga nangini tamasuk dalam {{PLURAL:$1|halaman}} dudi nang dilindungi \"barénténg\": $2", "namespaceprotected": "Pian kada baisi ijin hagan mambabak tutungkaran dalam ngaran kamar '''$1'''.", "customcssprotected": "Pian kada baisi ijin mambabak tungkaran CSS ngini, karana ngini baisi setelan paribadi pamakai lain.", "customjsprotected": "Pian kada baisi ijin mambabak tungkaran JavaScript ngini, karana ngini baisi setelan paribadi pamakai lain.", @@ -312,11 +312,11 @@ "invalidtitle-knownnamespace": "Judul nang kada sah lawan ruang-ngaran \"$2\" wan teks \"$3\"", "invalidtitle-unknownnamespace": "Judul nang kada sah lawan numur ruang ngaran kada dikatahui $1 wan teks \"$2\"", "exception-nologin": "Balum babuat log", - "exception-nologin-text": "Silahkan babuat log gasan kawa maaksis tungkaran atau gawian ngini", + "exception-nologin-text": "Silahkan babuat log gasan kawa masuk ka halaman atau gawian ngini", "virus-badscanner": "Konpigurasi buruk: pamindai virus kada dipinandui: ''$1''", "virus-scanfailed": "Pamindaian gagal (kudi $1)", "virus-unknownscanner": "Antivirus kada dipinandui:", - "logouttext": "Pian wayahini kaluar log.\n\n\nIngatakan bahwa babarapa tungkaran mungkin masih manampaiakan pian kaya masih babuat log, sampai pian mambarasihi singgahan panjalajah pian.", + "logouttext": "Pian wayahini kaluar log.\n\nIngatakan bahwa babarapa halaman mungkin masih manampaiakan pian kaya masih babuat log, sampai Pian mambarasihi singgahan panjalajah pian.", "welcomeuser": "Salamat datang, $1 !", "welcomecreation-msg": "Akun pian sudah diulah.\nPian kawa maubah [[Special:Preferences|preperensi]] {{SITENAME}} amun pian handak.", "yourname": "Ngaran pamakai:", @@ -478,10 +478,10 @@ "loginreqlink": "Babuat log", "loginreqpagetext": "Pian musti $1 hagan maniringi rungkaran-tungkaran lain.", "accmailtitle": "Katasunduk takirim.", - "accmailtext": "Sabuting katasunduk babarang gasan [[User talk:$1|$1]] sudah dikirim ka $2.\n\nKatasunduk gasan pamakai hanyar nangini kawa diubah di tungkaran ''[[Special:ChangePassword|ubah katasunduk]]'' imbah babuat log.", + "accmailtext": "Sabuting katasunduk babarang gasan [[User talk:$1|$1]] sudah dikirim ka $2.\n\nKatasunduk gasan pamakai hanyar nangini kawa diubah di halaman ''[[Special:ChangePassword|ubah katasunduk]]'' limbah babuat log.", "newarticle": "(Hanyar)", "newarticletext": "Pian maumpati tautan ka halaman nang balum tasadia. Amun handak maulah halaman itu, katiklah isi halaman di kutak di bawah ngini (janaki [$1 halaman patulung] gasan maklumat labih lanjut). Amun pian kada bakurinah sampai ka halaman ngini, kalik picikan back di panjalajah wéb Pian.", - "anontalkpagetext": "----''Ngini adalah tungkaran pamandiran gasan pamakai kada bangaran nang baluman ma-ulah akun pulang, atawa kada mamakainya. Kami tapaksa mamakai numurik alamat IP hagan maminanduinya.\nAlamat IP nangkaini kawaai dipuruk ulih babarapa pamakai.\nAmun Pian adalah pamakai kada bangaran wan marasa kumin nang kada pas ta ka Pian, muhun [[Special:CreateAccount|ulah sabuah akun]] atawa [[Special:UserLogin|babuat log]] gasan mahindari kabingungan awan pamakai kada bangaran lain kaina.", + "anontalkpagetext": "----''Ngini adalah halaman pamandiran gasan pamakai kada bangaran nang baluman ma-ulah akun pulang, atawa kada mamakainya. Kami tapaksa mamakai numurik alamat IP hagan maminanduinya.\nAlamat IP nangkaini kawaai dipuruk ulih babarapa pamakai.\nAmun Pian adalah pamakai kada bangaran wan marasa kumin nang kada pas ta ka Pian, muhun [[Special:CreateAccount|ulah sabuah akun]] atawa [[Special:UserLogin|babuat log]] gasan mahindari kabingungan awan pamakai kada bangaran lain kaina.", "noarticletext": "Damini kadada naskah di halaman ngini.\nPian kawa [[Special:Search/{{PAGENAME}}|mangikihi gasan judul halaman ngini]] di halaman lain, [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mancari log tarait], atawa [{{fullurl:{{FULLPAGENAME}}|action=edit}} maulah halaman ngini].", "noarticletext-nopermission": "Wayahini kadada naskah di halaman ngini.\nPian kawa [[Special:Search/{{PAGENAME}}|manggagai gasan judul halaman ngini]] di halaman lain, atawa [{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} manggagai log tarait], tagal Pian kada baisi ijin gasan maulah halaman ngini.", "userpage-userdoesnotexist": "Akun pamakai \"$1\" kada tadaptar.\nMuhun pariksa/ditukui amun Pian handak maulah/mambabak tungkaran ngini.", @@ -494,7 +494,7 @@ "userjspreview": "'''Ingatakan bahwasa Pian tis/manilik pamakai JavaScript Pian.'''\n'''Nangini baluman tasimpan pulang!'''", "sitecsspreview": "'''Ingatakan bahwasa Pian manilik CSS ini haja.'''\n'''Nangini lagi baluman tasimpan!'''", "sitejspreview": "'''Ingatakan bahwasa Pian manilik JavaScript code ini haja.'''\n'''Nangini lagi baluman tasimpan!'''", - "userinvalidconfigtitle": "'''Paringatan:''' Kadada kulimbit \"$1\".\nTungkaran-tungkaran .css, .json wan .js ulahan mamuruk aksara halus, cuntuh {{ns:user}}:Foo/vector.css sawagai tandingan {{ns:user}}:Foo/Vector.css.", + "userinvalidconfigtitle": "'''Paringatan:''' Kadada kulimbit \"$1\".\nhalaman .css, .json wan .js ulahan mamakai aksara halus, cuntuh {{ns:user}}:Foo/vector.css sabagai tandingan {{ns:user}}:Foo/Vector.css.", "updated": "(Dihanyarakan)", "note": "'''Catatan:'''", "previewnote": "'''Ingatakanlah bahwasa ngini titilikan haja''' Paubahan Pian baluman disimpan!", @@ -520,7 +520,7 @@ "readonlywarning": "'''Paringatan: Basis data disunduk gasan diharagu, jadinya Pian kada kawa manyimpan babakan Pian wayahini.'''\nPian mungkin bagusnya manyalin wan malikap naskah ka sabuah barakas naskah wan simpan ngini gasan kainah.\n\nPambakal nang manyunduk manjalasakan kaini: $1", "protectedpagewarning": "'''Paringatan: Tungkaran ngini sudah dilindungi nang akibatnya pamakai awan hak istimiwa pambakal nang kawa mambabak ini.'''\nLog masuk pauncitnya disadiakan di bawah gasan rujukan:", "semiprotectedpagewarning": "'''Catatan:''' Tungkaran ngini sudah dilindungi nang akibatnya pamakai tadaptar haja nang kawa mambabak.\nLog masuk pauncitnya disadiakan di bawah gasan rujukan:", - "cascadeprotectedwarning": "Paringatan: Tungkaran ngini dilindungi jadinya pamakai lawan [[Special:ListGroupRights|hak aksis batantu] wara nang kawa mambabaknya maraga ditransklusiakan dalam {{PLURAL:$1|tungkaran|tungkaran-tungkaran}} nang dilindungi barinting.", + "cascadeprotectedwarning": "Paringatan: Halaman ngini dilindungi jadinya pamakai lawan [[Special:ListGroupRights|hak aksis batantu]] wara nang kawa mambabaknya maraga ditransklusiakan dalam {{PLURAL:$1|halaman}} nang dilindungi barinting.", "titleprotectedwarning": "'''Paringatan: Tungkaran ngini sudah dilindungi nang akibatnya [[Special:ListGroupRights|hak khas]] diparluakan hagan maulah ngini.'''\nLog masuk pauncitnya disadiakan di bawah gasan rujukan:", "templatesused": "{{PLURAL:$1|Citakan|Citakan}} nang dipakai di halaman ngini:", "templatesusedpreview": "{{PLURAL:$1|Citakan|Cicitakan}} nang dipakai di titilikan ngini:", @@ -546,7 +546,7 @@ "defaultmessagetext": "Naskah baku pasan", "content-failed-to-parse": "Gagal manjabarakan isi $2 gasan model $1: $3", "invalid-content-data": "Data isi kada sah", - "content-not-allowed-here": "Isi \"$1\" kada diijinakan di tungkaran [[:$2]] di bagian \"$3\"", + "content-not-allowed-here": "Isi \"$1\" kada diijinakan di halaman [[:$2]] di palih \"$3\"", "content-model-wikitext": "teks wiki", "content-model-text": "teks polos", "content-model-javascript": "JavaScript", @@ -561,7 +561,7 @@ "parser-template-recursion-depth-warning": "Citakan batas kadalaman recursi limpuar ($1)", "language-converter-depth-warning": "Batas kadalaman pangonversi basa limpuar ($1)", "node-count-exceeded-category": "Tungkaran di mana node-count tarlalui", - "node-count-exceeded-warning": "Tungkaran malabihi jumlah node", + "node-count-exceeded-warning": "Halaman malabihi jumlah node", "expansion-depth-exceeded-category": "Tungkaran dimana kadalaman ikspansi talalui", "expansion-depth-exceeded-warning": "Tungkaran malabihi kadalaman ikspansi", "parser-unstrip-loop-warning": "Lingkaran unstrip taditiksi", @@ -592,7 +592,7 @@ "historysize": "($1 {{PLURAL:$1|bita|bibita}})", "historyempty": "kusung", "history-feed-title": "Riwayat ralatan", - "history-feed-description": "Riwayat ralatan gasan tungkaran ngini pada wiki", + "history-feed-description": "Riwayat ralatan gasan halaman ngini pada wiki", "history-feed-item-nocomment": "$1 wayah $2", "history-feed-empty": "Tungkaran nang diminta kadada.\nIni pinanya sudah dihapus matan wiki ini, atawa dingarani lain.\nCubai [[Special:Search|gagai di wiki ini]] gasan tungkaran hanyar bakarabat.", "rev-deleted-comment": "(kasimpulan babakan dibuang)", @@ -762,7 +762,7 @@ "stub-threshold-disabled": "Kada kawa-akan", "recentchangesdays": "Jumlah hari nang manampaiakan paubahan pahanyarnya:", "recentchangesdays-max": "Paling lawas $1 {{PLURAL:$1|hari|hahari}}", - "recentchangescount": "Rikinan babakan default gasan ditampaiakan di paubahan pahanyarnya, riwayat tungkaran, wan di tungkaran log:", + "recentchangescount": "Rikinan babakan standar gasan ditampaiakan di paubahan pahanyarnya, riwayat halaman, wan di halaman log:", "prefs-help-recentchangescount": "Rikinan paningginya: 1000", "savedprefs": "Kakatujuan Pian sudah ham disimpan.", "timezonelegend": "Waktu banua:", @@ -805,8 +805,8 @@ "badsiglength": "Tapak tangan Sampian talalu panjang. Jangan malabihi pada $1 {{PLURAL:$1|karakter|karakter}}.", "yourgender": "Kaya apa pian handak dijalasakan?", "gender-unknown": "Wayah manyambat pian, parangkat lunak pacangan mamakai kata netral wayah parlu", - "gender-male": "Inya (lakian) mambabak tungkaran wiki", - "gender-female": "Inya (binian) mambabak tungkaran wiki", + "gender-male": "Inya (lakian) mambabak halaman wiki", + "gender-female": "Inya (binian) mambabak halaman wiki", "prefs-help-gender": "Paraturan katujuan ngini opsional.\nParangkat lambik mamakai nilainya gasan maarahakan pian wan manyambat pian ka sabarataan pamakaian mamakai hiauan janis kalamin.\nInformasi nginji pacangan publik.", "email": "Suril", "prefs-help-realname": "Ngaran bujur adalah pilihan haja.\nAmun Pian mamilih manyadiakan ini, ini akan dipuruk gasan paminanduan kulihan gawian Pian.", @@ -869,7 +869,7 @@ "right-minoredit": "Tandai bababakan sawagai sapalih", "right-move": "Mamindahakan tungkaran", "right-move-subpages": "Ugahakan tutungkaran awan subtumgkaran-nya", - "right-move-rootuserpages": "Mamindahakan tungkaran utama pamakai", + "right-move-rootuserpages": "Mamindahakan halaman utama pamakai", "right-movefile": "Mamindahakan barakas", "right-suppressredirect": "Kada maulah paugahan matan tutungkaran asal mula parhatan tutungkan pindahan", "right-upload": "Unggahakan barakas", @@ -904,7 +904,7 @@ "right-editusercss": "Babak pamruk lain babarakas CSS", "right-edituserjson": "Mambabak barakas JSON pamakai lain", "right-edituserjs": "Mambabak barakas JS pamakai lain", - "right-rollback": "Mambulikakan hancap babakan pamakai pauncitnya nang mambabak tungkaran tartantu", + "right-rollback": "Mambulikakan hancap babakan pamakai pauncitnya nang mambabak halaman tartantu", "right-markbotedits": "Tandai bababakan dibulikakan sawagai bababakan bot", "right-noratelimit": "Kada pangaruh awan watas rating", "right-import": "Impur tutungkaran matan wiwiki lain", @@ -947,7 +947,7 @@ "action-suppressionlog": "tiringi log paribadi ini", "action-block": "Blukir pamakai ngini matan mambabak", "action-protect": "Ubah tingkat parlindungan tungkaran ngini", - "action-rollback": "Mambulikakan hancap babakan matan pamakai pauncitnya nang mambabak tungkaran tartantu.", + "action-rollback": "Mambulikakan hancap babakan matan pamakai pauncitnya nang mambabak halaman tartantu.", "action-import": "Impur tungkaran ngini matan wiki lain", "action-importupload": "Impur tungkaran ngini matan sabuah barakas hunggahan", "action-patrol": "tandai babakan nang lain sawagai ta'awasi", @@ -1128,7 +1128,7 @@ "zip-bad": "Barakas ngini korup atawa pinanya barakas ZIP nang kada kawa dibaca.\nBarakas ngini kada kawa dipariksa gasan kaamanan.", "zip-unsupported": "Barakas ngini adalah sabuah barakas ZIP nang dipuruk pitur ZIP nang kada disukung ulih MediaWiki.\nNgini kada kawa dipariksa gasan kaamanan.", "uploadstash": "Simpanan hunggahan", - "uploadstash-summary": "Tungkaran ngini manyadiaakan ungkaian ka barakas nang taunggah (atawa dalam prosés unggahan) tapi baluman ditarbitakan ka wiki.\nBarakas ngini kada kawa dijanaki ka siapa pun kacuali pamakai nang maunggahnya.", + "uploadstash-summary": "Halaman ngini manyadiaakan ungkaian ka barakas nang taunggah (atawa dalam prosés unggahan) tapi baluman dicungulakan ka wiki.\nBarakas ngini kada kawa dijanaki ka siapa pun kacuali pamakai nang maunggahnya.", "uploadstash-clear": "Kalarakan babarakas simpanan.", "uploadstash-nofiles": "Pian kada baisi babarakas simpanan.", "uploadstash-badtoken": "Aksi kada ruhui dilaksanaakan, pinanya karana babakan Pian sudah kadaluarsa. Cubai pulang.", @@ -1189,7 +1189,7 @@ "filehist-comment": "Ulasan", "imagelinks": "Tautan barakas", "linkstoimage": "{{PLURAL:$1|Halaman|$1 halaman}} nangini mamakai barakas ngini:", - "linkstoimage-more": "Labih daripada $1 {{PLURAL:$1|pamakaian tungkaran|pamakaian tutungkaran}} ka barakas ngini.\nDaptar barikut manampaiakan {{PLURAL:$1|tungkaran panambaian|$1 tungkaran panambaiam}} nang mamakai barakas ngini haja.\nSabuah [[Special:WhatLinksHere/$2|daptar hibak]] tasadia.", + "linkstoimage-more": "Labih daripada $1 {{PLURAL:$1|pamakaian halaman|pamakaian halaman}} ka barakas ngini.\nDaptar barikut manampaiakan {{PLURAL:$1|halaman panambaian|$1 halaman panambaian}} nang mamakai barakas ngini haja.\nSabuting [[Special:WhatLinksHere/$2|daptar hibak]] tasadia.", "nolinkstoimage": "Kadada tutungkaran nang mamakai barakas ngini.", "morelinkstoimage": "Tiringi [[Special:WhatLinksHere/$1|tautan lagi]] ka barakas ngini.", "linkstoimage-redirect": "$1 (barakas paugahan) $2", @@ -1323,7 +1323,7 @@ "unusedimagestext": "Babarakas barikut ada tagal kada diumpatakan di tungkaran mamana.\nMuhun catat bahwasa situs web lain pina-ai bataut ka sabuah barakas awan sabuah URL langsung, wan karana ngini masih-ha didaptar di sia biar gin aktip dipuruk.", "unusedcategoriestext": "Tumbung tutungkaran barikut ada, walaupun kadada tungkaran lain atawa tumbung mamuruknya.", "notargettitle": "Kadada tujuan", - "notargettext": "Pian kada manantuakan tungkaran atawa pamakai tujuan tugas ngini.", + "notargettext": "Pian kada manantuakan halaman atawa pamakai tujuan tugas ngini.", "nopagetitle": "Kadada tungkaran sasaran", "nopagetext": "Tungkaran sasaran nang Pian ajuakan kadada.", "pager-newer-n": "{{PLURAL:$1|labih hanyar 1|labih hanyar $1}}", @@ -1339,7 +1339,7 @@ "speciallogtitlelabel": "Tujuan (judul atawa {{ns:user}}:ngaran pamakai gasan pamakai)", "log": "Log", "all-logs-page": "Samunyaan log umum", - "alllogstext": "Tampaian baimbai matan sabataan log nang ada matan {{SITENAME}}.\nPian kada mawatasi tiringan lawan mamilih sabuah macam log, ngaran-pamakai (sansitip kapital), atawa tungkaran tapangaruh (sansitip kapital jua).", + "alllogstext": "Tampaian baimbai matan sabataan log nang ada matan {{SITENAME}}.\nPian kada mawatasi tiringan lawan mamilih sabuting macam log, ngaran-pamakai (sansitip kapital), atawa halaman tapangaruh (sansitip kapital jua).", "logempty": "Kadada barang nang parsis pintang log.", "log-title-wildcard": "Gagai judul ba-awalan awan naskah ngini", "showhideselectedlogentries": "Tampaiakan/sungkupakan masukan log tapilih", @@ -1379,7 +1379,7 @@ "activeusers-from": "Manampaiakan papamuruk mulai matan:", "activeusers-noresult": "Kadada papamuruk tatamu.", "listgrouprights": "Daptar hak galambang", - "listgrouprights-summary": "Nangini daptar galambang pamakai nang tahaga di wiki ini, lawan daptar hak maungkai bubuhannya. Maklumat salanjutnya sual hak masing-masing kawa ditamuakan di [[{{MediaWiki:Listgrouprights-helppage}}|tungkaran patulung hak pamakai]].", + "listgrouprights-summary": "Nangini daptar galambang pamakai nang tahaga di wiki ini, lawan daptar hak maungkai bubuhannya. Maklumat salanjutnya sual hak masing-masing kawa ditamuakan di [[{{MediaWiki:Listgrouprights-helppage}}|halaman patulung hak pamakai]].", "listgrouprights-key": "* Hak nang balaku\n* Hak nang dicukut", "listgrouprights-group": "Galambang", "listgrouprights-rights": "Hak", @@ -1436,7 +1436,7 @@ "unwatchthispage": "Mandak maitihi", "notanarticle": "Lainan sabuting tungkaran isi", "notvisiblerev": "Ralatan sudah dihapus", - "watchlist-details": "Tahaga {{PLURAL:$1|$1 tungkaran|$1 tungkaran}} di daptar itihan Pian, (tamasuk tungkaran pamandiran).", + "watchlist-details": "Tahaga {{PLURAL:$1|halaman}} di daptar itihan Pian, (tamasuk halaman pamandiran).", "wlheader-enotif": "Suril pamadahan dipajahi.", "wlheader-showupdated": "Tutungkaran nang ba-ubah tumatan ilangan tauncit Pian ditampaiakan dalam hurup kandal.", "wlnote": "Dibawah ngini adalah {{PLURAL:$1|paubahan pahabisan|$1 paubahan pahabisan}} dalam {{PLURAL:$2|sajam|$2 jam}} par $3, $4.", @@ -1491,7 +1491,7 @@ "rollbacklinkcount": "bulikakan $1 {{PLURAL:$1|babakan}}", "rollbackfailed": "Guling-bulik luput", "cantrollback": "Kada kawa mambalikakan babakan;\npanyumbang tauncit adalah asa-asanya panulis tungkaran ngini.", - "alreadyrolled": "Kada kawa malakukan pambulikan ka ralatan pauncitnya [[:$1]] ulih [[User:$2|$2]] ([[User talk:$2|pandir]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\npamakai lain sudah mambabak atawa malakukan pambulikan lawan tungkaran ngini.\n\nBabakan pauncitnya dilakukan ulih [[User:$3|$3]] ([[User talk:$3|pandir]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).", + "alreadyrolled": "Kada kawa malakukan pambulikan ka ralatan pauncitnya [[:$1]] ulih [[User:$2|$2]] ([[User talk:$2|pandir]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\npamakai lain sudah mambabak atawa malakukan pambulikan lawan halaman ngini.\n\nBabakan pauncitnya dilakukan ulih [[User:$3|$3]] ([[User talk:$3|pandir]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).", "editcomment": "Kumintar pambabakan adalah: $1.", "revertpage": "←Babakan [[Special:Contributions/$2|$2]] ([[User talk:$2|pandir]]) dibulikakan ka ralatan tauncit ulih [[User:$1|$1]]", "revertpage-nouser": "Pambulikan babakan ulih (pamuruk dihapus) ka babakan tauncit ulih [[User:$1|$1]]", @@ -1617,7 +1617,7 @@ "sp-contributions-search": "Kikihi sumbangan", "sp-contributions-username": "Alamat IP atawa ngaran-pamakai:", "sp-contributions-toponly": "Tampaiakan wastu ralatan nang paling atas (pauncitnya)", - "sp-contributions-newonly": "Hanya tampaiakan babakan nang barupa paulahan tungkaran", + "sp-contributions-newonly": "Hanya tampaiakan babakan nang barupa paulahan halaman", "sp-contributions-submit": "Kikih", "whatlinkshere": "Tautan balik", "whatlinkshere-title": "Halaman nang batautan ka ''$1''", @@ -1643,7 +1643,7 @@ "blockiptext": "Puruk purmulir di bawah hagan mamblukir hak ungkai manulis matan sabuah alamat IP atawa ngaran-pamuruk.\nNgini dipuruk hagan mancagah vandalisma haja, wan sasuai awan [[{{MediaWiki:Policy-url}}|kabijakan]].\nIsi sabuah alasan khas di bawah (gasan cuntuh, manulisakan tutungkaran nang suah divandal)", "ipaddressorusername": "Alamat IP atawa ngaran pamakai:", "ipbreason": "Alasan:", - "ipbreason-dropdown": "*Alasan umum\n** Vandalisma\n** Mambariakan katarangan kada bujur alias palsu\n** Mahilangakan isi tungkaran\n** Spam tautan ka situs luar\n** Mangaradau ka tungkaran\n** Parilaku intimidasi/mancapa\n** Manyalahgunaakan babarapa akun\n** Ngaran pamakai kada layak", + "ipbreason-dropdown": "*Alasan umum\n** Vandalisma\n** Mambariakan katarangan kada bujur alias palsu\n** Mahilangakan isi halaman\n** Spam tautan ka situs luar\n** Mangaradau ka halaman\n** Parilaku intimidasi/mancapa\n** Manyalahgunaakan babarapa akun\n** Ngaran pamakai kada layak", "ipb-hardblock": "Tangati pamakai tadaptar gasan mambabak matan alamat IP ngini", "ipbcreateaccount": "Tangkal paulahan akun", "ipbemailban": "Tangkal pamuruk mangirimi suril", @@ -1652,7 +1652,7 @@ "ipbother": "Wayah lain:", "ipboptions": "2 jam:2 hours,1 hari:1 day,3 hari:3 days,1 minggu:1 week,2 minggu:2 weeks,1 bulan:1 month,3 bulan:3 months,6 bulan:6 months,1 tahun:1 year,salawasan:infinite", "ipbhidename": "Sungkupakan ngaranpamuruk matan babakan wan dadaptar", - "ipbwatchuser": "Itihi tungkaran pamakai wan pamandiran pamakai ngini", + "ipbwatchuser": "Itihi halaman pamakai wan pamandiran pamakai ngini", "ipb-disableusertalk": "Tangkal pamuruk ngini mambabak tungkaran pamandirannya wayah diblukir", "ipb-change-block": "Blukir pulang pamakai lawan setélan ngini", "ipb-confirm": "Yakinakan blukir", @@ -1739,8 +1739,8 @@ "ipbnounblockself": "Pian kada dibulihakan malapas blukir Pian surang", "lockdb": "Sunduk basisdata", "unlockdb": "Lapas sunduk basisdata", - "lockdbtext": "Manyunduk basis data akan maampihakan kamampuan samunyaan pamakai mambabak tungkaran, maubah kakatujuan sidin, mambabak paitihin sidin, wan nang lainnya nang parlu diubah dalam basis data.\nMuhun yakinakan nangini bujur nang handak Pian gawi, wan Pian akan malapas-sunduk basis data amun paharaguan tuntung.", - "unlockdbtext": "Malapas sunduk basis data akan manyimpan-pulang kamampuan samunyaan pamakai gasan mambabak tungkaran, maubah kakatujuan sidin, mambabak paitihan sidin, wan nang lainnya nang parlu diubah dalam basis data.\nMuhun yakinakan nang ngini nang Pian handak gawi.", + "lockdbtext": "Manyunduk basis data akan maampihakan kamampuan samunyaan pamakai mambabak halaman, maubah kakatujuan sidin, mambabak paitihin sidin, wan nang lainnya nang parlu diubah dalam basis data.\nMuhun yakinakan nangini bujur nang handak Pian gawi, wan Pian akan malapas-sunduk basis data amun paharaguan tuntung.", + "unlockdbtext": "Malapas sunduk basis data akan manyimpan-pulang kamampuan samunyaan pamakai gasan mambabak halaman, maubah kakatujuan sidin, mambabak paitihan sidin, wan nang lainnya nang parlu diubah dalam basis data.\nMuhun yakinakan nang ngini nang Pian handak gawi.", "lockconfirm": "I'ih, ulun bujuran handak manyunduk basisdata.", "unlockconfirm": "I'ih, ulun bujuran handak malapas sunduk basisdata.", "lockbtn": "Sunduk basisdata", @@ -1758,12 +1758,12 @@ "movepagetext": "Mamakai purmulir di bawah akan mangganti ngaran sabuting tungkaran, mamindahakan samunyaan halam ka ngaran nang hanyar. Judul lawas akan jadi sabuting tungkaran paugahan ka judul hanyar. Pian kawa mahanyari bahwasanya paugahan-paugahan manuju ka judul nang samustinya langsung. Amun kada, pastiakan pariksa gasan [[Special:DoubleRedirects|ganda]] atawa [[Special:BrokenRedirects|paugahan pagat]]. Pian batanggung jawab gasan mamastiakan tautan-tautan tatarusan manuju ka mana nang samustinya.\n\nCatatan bahwasanya tungkaran '''kada''' akan tapindah amun sudah ada tungkaran nang bangaran hanyar ngitu, kacuali amun tungkaran itu puang atawa sabuting paugahan wan kadada halam babakan.\n\n'''Paringatan!'''\nIni kawa maakibatakan paubahan kada taduga wan drastis gasan sabuting tungkaran rami; muhun mamastiakan Pian paham akibatnya sabalum manarusakan.", "movepagetext-noredirectfixer": "Mamakai purmulir di bawah akan mangganti ngaran sabuting tungkaran, mamindahakan samunyaan halam ka ngaran nang hanyar.\nJudul lawas akan jadi sabuting tungkaran paugahan ka judul hanyar.\nPastiakan pariksa gasan [[Special:DoubleRedirects|ganda]] atawa [[Special:BrokenRedirects|paugahan pagat]].\nPian batanggung jawab gasan mamastiakan tautan-tautan tatarusan manuju ka mana nang samustinya.\n\nCatatan bahwasanya tungkaran '''kada''' akan tapindah amun sudah ada tungkaran nang bangaran hanyar ngitu, kacuali amun tungkaran itu puang atawa sabuah paugahan wan kadada halam babakan.\n\n'''Paringatan!'''\nIni kawa maakibatakan paubahan kada taduga wan drastis gasan sabuah tungkaran rami; \nmuhun mamastiakan Pian paham akibatnya sabalum manarusakan.", "movepagetalktext": "Tungkaran pamandiran tarait akan langsung dipindahakan baimbai wan ini '''kacuali amun:'''\n*Sabuah tungkaran pamandiran nang kada puang sudah baisi awan judul hanyar, atawa\n*Pian kada manyuntring kutak di bawah.", - "moveuserpage-warning": "'''Paringatan:''' Pian parhatan mamindahakan tungkaran pamakai. Parlu Pian tahu lamun cuma tungkaran nang akan dipindahakan tapi pamakai ''kada'' baganti ngaran.", - "movenologintext": "Pian musti manjadi pamakai tadaptar wan [[Special:UserLogin|babuat log]] gasan mamindahakan suatu tungkaran.", + "moveuserpage-warning": "'''Paringatan:''' Pian parhatan mamindahakan halaman pamakai. Parlu Pian tahu lamun cuma halaman nang akan dipindahakan tapi pamakai ''kada'' baganti ngaran.", + "movenologintext": "Pian musti manjadi pamakai tadaptar wan [[Special:UserLogin|babuat log]] gasan mamindahakan suatu halaman.", "movenotallowed": "Pian kada baisi ijin hagan mamindahakan tutungkaran.", "movenotallowedfile": "Pian kada baisi ijin hagan mamindahakan babarakas.", - "cant-move-user-page": "Pian kada baisi ijin gasan mamindahakan tungkaran pamakai (tapisah matan sub-tutungkaran).", - "cant-move-to-user-page": "Pian kada baisi ijin gasan mamindahakan tungkaran ka suatu tungkaran pamakai (kacuali ka sub-tutungkaran pamakai).", + "cant-move-user-page": "Pian kada baisi ijin gasan mamindahakan halaman pamakai (tapisah matan sub-halaman).", + "cant-move-to-user-page": "Pian kada baisi ijin gasan mamindahakan halaman ka suatu halaman pamakai (kacuali ka sub-halaman pamakai).", "newtitle": "Ka judul hanyar:", "move-watch": "Itihi tungkaran asal mula wan tungkaran tujuan", "movepagebtn": "Pindahakan tungkaran", @@ -1803,7 +1803,7 @@ "imageinvalidfilename": "Ngaran barakas tujuan kada sah", "fix-double-redirects": "Mutakhirakan babarapa paugahan nang manitik ka judul asli", "move-leave-redirect": "Ulah paugahan ka judul hanyar", - "protectedpagemovewarning": "'''Paringatan''': Tungkaran ngini sudah dikunci wan cuma pamakai nang baisi hak pambakal haja nang kawa mamindahakannya.\nMasukan catatan pauncitnya disadiaakan di bawah gasan rujukan:", + "protectedpagemovewarning": "'''Paringatan''': Halaman ngini sudah disunduk wan cuma pamakai nang baisi hak pambakal haja nang kawa mamindahakannya.\nMasukan catatan pauncitnya disadiaakan di bawah gasan rujukan:", "semiprotectedpagemovewarning": "'''Catatan:''' Tungkaran ngini sudah dilindungi laluai pamuruk tadaptar haja nang kawa mamindahakan ngini.\nLog masuk pauncitan disadiakan di bawah gasan rujukan:", "move-over-sharedrepo": "==Barakas ada==\n[[:$1]] ada pintangan panyimpanan babagi. Mamindahakan sabuah barakas ka judul ngini akan manulis-tindih barakas babagi.", "file-exists-sharedrepo": "Ngaran barakas nang dipilih sudah dipuruk pintangan panyimpanan babagi.\nMuhun pilih ngaran lain.", @@ -1885,7 +1885,7 @@ "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|ralatan|raralatan}} matan $2", "javascripttest": "Mantis JavaScript", "tooltip-pt-userpage": "Halaman {{GENDER:|pamakai Pian}}", - "tooltip-pt-anonuserpage": "Tungkaran pamakai IP Pian", + "tooltip-pt-anonuserpage": "Halaman pamakai IP Pian", "tooltip-pt-mytalk": "Halaman {{GENDER:|pamandiran Pian}}", "tooltip-pt-anontalk": "Pamandiran pasal bababakan matan alamat IP ngini", "tooltip-pt-preferences": "Kakatujuan {{GENDER:|Pian}}", @@ -1979,14 +1979,14 @@ "pageinfo-default-sort": "Kunci urut baku", "pageinfo-length": "Panjang tungkaran (dalam bita)", "pageinfo-article-id": "ID Tungkaran", - "pageinfo-language": "Basa isi tungkaran", - "pageinfo-content-model": "Mudil isi tungkaran", + "pageinfo-language": "Basa isi halaman", + "pageinfo-content-model": "Mudil isi halaman", "pageinfo-robot-policy": "Pangindéksan ulih robot", "pageinfo-robot-index": "Dibulihakan", "pageinfo-robot-noindex": "Kada dibulihakan", "pageinfo-watchers": "Jumlah pa-itih tungkaran", "pageinfo-few-watchers": "Kurang matan $1 {{PLURAL:$1|pa-ilang}}", - "pageinfo-redirects-name": "Jumlah paugahan ka tungkaran ngini", + "pageinfo-redirects-name": "Jumlah paugahan ka halaman ngini", "pageinfo-subpages-name": "Subtungkaran tungkaran ngini", "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|paugahan|paugahan}}; $3 {{PLURAL:$3|non-paugahan|non-paugahan}})", "pageinfo-firstuser": "Pa-ulah tungkaran", @@ -2108,7 +2108,7 @@ "confirm-unwatch-button": "OK", "confirm-unwatch-top": "Buang tungkaran ini matan paitihan Pian?", "imgmultipageprev": "← tungkaran sabalumnya", - "imgmultipagenext": "tungkaran salanjutnya →", + "imgmultipagenext": "halaman salanjutnya →", "imgmultigo": "Tulak!", "imgmultigoto": "Tulak ka tungkaran $1", "ascending_abbrev": "naik", @@ -2170,8 +2170,8 @@ "version-software-product": "Produk", "version-software-version": "Virsi", "version-entrypoints-header-url": "URL", - "redirect": "Paugahan badasarakan ID barakas, pamakai, tungkaran, ralatan, atawa log", - "redirect-summary": "Tungkaran istimiwa ngini baugah ka barakas (sasuai ngarannya), halaman (sasuai ID ralatan atawa ID tungkaran), tungkaran pamakai (sasuai ID pamakai), atawa buatan log (ID lognya). Pamakaian: [[{{#Special:Redirect}}/file/Cuntuh.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], or [[{{#Special:Redirect}}/logid/186]].", + "redirect": "Paugahan badasarakan ID barakas, pamakai, halaman, ralatan, atawa log", + "redirect-summary": "Halaman istimiwa ngini baugah ka barakas (sasuai ngarannya), halaman (sasuai ID ralatan atawa ID halaman), halaman pamakai (sasuai ID pamakai), atawa buatan log (ID lognya). Pamakaian: [[{{#Special:Redirect}}/file/Cuntuh.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], atawa [[{{#Special:Redirect}}/logid/186]].", "redirect-submit": "Lanjut", "redirect-lookup": "Panggagaian:", "redirect-value": "Nilai:", @@ -2241,9 +2241,9 @@ "htmlform-reset": "Bulikakan paubahan", "htmlform-selectorother-other": "Lain-lain", "logentry-delete-delete": "$1 {{GENDER:$2|mahapus}} halaman $3", - "logentry-delete-restore": "$1 {{GENDER:$2|mambulikakan}} tungkaran $3 ($4)", + "logentry-delete-restore": "$1 {{GENDER:$2|mambulikakan}} halaman $3 ($4)", "logentry-delete-event": "$1 mangganti kakawaan dijanaki {{PLURAL:$5|sabuah log kajadian|$5 log kajadian}} pintangan $3: $4", - "logentry-delete-revision": "$1 {{GENDER:$2|maubah}} tampaian {{PLURAL:$5|$5 ralatan}} di tungkaran $3: $4", + "logentry-delete-revision": "$1 {{GENDER:$2|maubah}} tampaian {{PLURAL:$5|$5 ralatan}} di halaman $3: $4", "logentry-delete-event-legacy": "$1 mangganti kakawaan dijanaki log kajadian pintangan $3", "logentry-delete-revision-legacy": "$1 mangganti kakawaan dijanaki ralatan pintangan tungkaran $3", "logentry-suppress-delete": "$1 ditikin tungkaran $3", @@ -2260,11 +2260,11 @@ "revdelete-restricted": "Talamar pambatasan hagan pambakal-pambakal", "revdelete-unrestricted": "Buang pambatasan gasan pambakal-pambakal", "logentry-move-move": "$1 {{GENDER:$2|mamindahakan}} halaman $3 ka $4", - "logentry-move-move-noredirect": "$1 {{GENDER:$2|mamindahakan}} tungkaran $3 ka $4 kada pakai maulah paugahan", - "logentry-move-move_redir": "$1 {{GENDER:$2|mamindahakan}} tungkaran $3 ka $4 manimpa paugahan lawas", + "logentry-move-move-noredirect": "$1 {{GENDER:$2|mamindahakan}} halaman $3 ka $4 kada pakai maulah paugahan", + "logentry-move-move_redir": "$1 {{GENDER:$2|mamindahakan}} halaman $3 ka $4 manimpa paugahan lawas", "logentry-move-move_redir-noredirect": "$1 diugah tungkaran $3 ka $4 lung sabuah paugahan awan-kada maninggalakan sabuah paugahan", "logentry-patrol-patrol": "$1 diciri'i ralatan $4 matan tungkaran $3 taawasi", - "logentry-patrol-patrol-auto": "$1 utumatis {{GENDER:$2|manandai}} ralatan $4 matan tungkaran $3 taitihi", + "logentry-patrol-patrol-auto": "$1 utumatis {{GENDER:$2|manandai}} ralatan $4 matan halaman $3 taitihi", "logentry-newusers-newusers": "$1 ma-ulah sabuting akun pamakai", "logentry-newusers-create": "$1 {{GENDER:$2|maulah}} akun pamakai", "logentry-newusers-create2": "$1 ma-ulah sabuting akun pamakai $3", @@ -2275,7 +2275,7 @@ "feedback-adding": "Manambahi kitihanbalik ka tungkaran...", "feedback-bugcheck": "Harat! hanyar dipariksa bahwasa ngini lainan salah asa [$1 bug nang dipinandui].", "feedback-bugnew": "Ulun mamariksa. Malapurakan sabuah bug hanyar", - "feedback-bugornote": "Lamun Pian sudah siap gasan mamaparakan masalah téknis sacara rinci silakan [$1 malapurakan bug].\nLamun kada, Pian kawa mamakai purmulir mudah di bawah ngini. Kumintar Pian akan ditambahakan ka tungkaran \"[$3 $2]\", baimbai lawan ngaran pamakai Pian wan apa paramban nang Pian pakai.", + "feedback-bugornote": "Lamun Pian sudah siap gasan mamaparakan masalah téknis sacara rinci silakan [$1 malapurakan bug].\nLamun kada, Pian kawa mamakai purmulir mudah di bawah ngini. Kumintar Pian akan ditambahakan ka halaman \"[$3 $2]\", baimbai lawan ngaran pamakai Pian wan apa paramban nang Pian pakai.", "feedback-cancel": "Pasah", "feedback-close": "Sudah", "feedback-error1": "Kasalahan: kulihan matan API kada-dipinandui", @@ -2306,5 +2306,5 @@ "special-characters-group-thai": "Thai", "special-characters-group-lao": "Lao", "special-characters-group-khmer": "Khmer", - "randomrootpage": "Tungkaran dasar sambarang" + "randomrootpage": "Halaman dasar sambarang" } diff --git a/languages/i18n/bn.json b/languages/i18n/bn.json index f3a4d8d74c..2fc856d676 100644 --- a/languages/i18n/bn.json +++ b/languages/i18n/bn.json @@ -2516,7 +2516,7 @@ "ipb-confirm": "বাধা নিশ্চিতকরণ", "ipb-sitewide": "সাইটব্যাপী", "ipb-partial": "আংশিক", - "ipb-sitewide-help": "উইকিতে সব পাতা ও অন্যান্য সব অবদানে বাধা।", + "ipb-sitewide-help": "উইকির সব পাতায় ও অন্যান্য সব অবদানে বাধা।", "ipb-partial-help": "নির্দিষ্ট পাতা ও নামস্থানসমূহ।", "ipb-pages-label": "পাতা", "ipb-namespaces-label": "নামস্থানসমূহ", diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 71f56332d2..0dd9fe0e77 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -4044,6 +4044,9 @@ "mw-widgets-abandonedit-discard": "Discard edits", "mw-widgets-abandonedit-keep": "Continue editing", "mw-widgets-abandonedit-title": "Are you sure?", + "mw-widgets-copytextlayout-copy": "Copy", + "mw-widgets-copytextlayout-copy-fail": "Failed to copy to clipboard.", + "mw-widgets-copytextlayout-copy-success": "Copied to clipboard.", "mw-widgets-dateinput-no-date": "No date selected", "mw-widgets-dateinput-placeholder-day": "YYYY-MM-DD", "mw-widgets-dateinput-placeholder-month": "YYYY-MM", diff --git a/languages/i18n/fy.json b/languages/i18n/fy.json index b67abb2f96..9b14ac1b22 100644 --- a/languages/i18n/fy.json +++ b/languages/i18n/fy.json @@ -775,13 +775,14 @@ "timezonelegend": "Tiidsône:", "localtime": "Pleatslike tiid:", "timezoneuseserverdefault": "Wikistandert brûke ($1)", - "timezoneuseoffset": "Oars (tiidferskil oanjaan)", + "timezoneuseoffset": "Oars (ferskil hjirûnder oanjaan)", + "timezone-useoffset-placeholder": "Foarbyldwearden: \"-07:00\" as \"01:00\"", "servertime": "Servertiid:", - "guesstimezone": "Freegje de blêder", + "guesstimezone": "Webblêder ynfolje litte", "timezoneregion-africa": "Afrika", "timezoneregion-america": "Amearika", "timezoneregion-antarctica": "Antarktika", - "timezoneregion-arctic": "Arktysk", + "timezoneregion-arctic": "Noardpoalgebiet", "timezoneregion-asia": "Aazje", "timezoneregion-atlantic": "Atlantyske Oseaan", "timezoneregion-australia": "Austraalje", @@ -793,7 +794,9 @@ "prefs-namespaces": "Nammeromten", "default": "standert", "prefs-files": "Bestannen", - "prefs-custom-js": "Persoanlik JS", + "prefs-custom-css": "Oanpast CSS", + "prefs-custom-js": "Oanpast JavaScript", + "prefs-common-config": "Dield CSS/JSON/JavaScript foar alle foarmjouwings:", "prefs-reset-intro": "Jo kinne dizze side brûke, en set jo ynstellings werom nei de websteestandert.\nDat kin net ûngedien makke wurde.", "prefs-emailconfirm-label": "E-mailbefêstiging:", "youremail": "E-mail:", diff --git a/languages/i18n/hr.json b/languages/i18n/hr.json index 4e8d0e8a7c..5c71b0516e 100644 --- a/languages/i18n/hr.json +++ b/languages/i18n/hr.json @@ -410,6 +410,7 @@ "virus-scanfailed": "skeniranje neuspješno (kod $1)", "virus-unknownscanner": "nepoznati antivirus:", "logouttext": "'''Odjavili ste se.'''\n\nNeke se stranice mogu prikazivati kao da ste još uvijek prijavljeni, sve dok ne očistite međuspremnik svog preglednika.", + "logging-out-notify": "Odjavljujemo Vas, molimo pričekajte.", "cannotlogoutnow-title": "Odjava trenutno nije moguća", "cannotlogoutnow-text": "Odjava nije moguća tijekom uporabe $1.", "welcomeuser": "Dobrodošli, $1!", diff --git a/languages/i18n/lrc.json b/languages/i18n/lrc.json index e5f17c013c..41f87a8e7e 100644 --- a/languages/i18n/lrc.json +++ b/languages/i18n/lrc.json @@ -80,7 +80,7 @@ "february": "فڤریٱ", "march": "مارس", "april": "آڤریلٛ", - "may_long": "ماٛ", + "may_long": "ماٛی", "june": "ژوئٱن", "july": "جۊلای", "august": "آگوست", @@ -104,7 +104,7 @@ "feb": "فڤریٱ", "mar": "مارس", "apr": "آڤریلٛ", - "may": "ماٛ", + "may": "ماٛی", "jun": "ژوئٱن", "jul": "جۊلای", "aug": "آگوست", @@ -116,7 +116,7 @@ "february-date": "فڤریٱ $1", "march-date": "مارس $1", "april-date": "آڤریلٛ $", - "may-date": "ماٛ $1", + "may-date": "ماٛی $1", "june-date": "ژوئٱن $1", "july-date": "جۊلای $1", "august-date": "آگوست $1", @@ -375,15 +375,15 @@ "createacct-another-username-ph": "نوم کاریاری تو ناْ بٱزنؽت", "yourpassword": "پٱسڤورد:", "userlogin-yourpassword": "پٱسڤورد", - "userlogin-yourpassword-ph": "رازینٱ گوئارسناْ بٱزاْ", - "createacct-yourpassword-ph": "رازینٱ گوئاردن ناْ بٱزاْ", - "yourpasswordagain": "یاٛ هنی رازینٱ گوئاردن ناْ بٱزاْ", + "userlogin-yourpassword-ph": "رازینٱ گوئارسن ناْ بٱزاْ", + "createacct-yourpassword-ph": "رازینٱ گوئارسن ناْ بٱزاْ", + "yourpasswordagain": "یاٛ هنی رازینٱ گوئارسن ناْ بٱزاْ", "createacct-yourpasswordagain": "پٱسڤورد تازٱ ناْ تٱیید كو", - "createacct-yourpasswordagain-ph": "یاٛ گلٛ هنی رازینٱ گوئاردن بٱزٱ", + "createacct-yourpasswordagain-ph": "یاٛ گلٛ هنی رازینٱ گوئارسن بٱزٱ", "userlogin-remembermypassword": "مناْ د سامونٱ ڤادار", "userlogin-signwithsecure": "ڤٱسل بیئن ٱمن ناْ ڤ کار باٛیر", "yourdomainname": "پوشگر شما:", - "password-change-forbidden": "شوما نئمی توٙنیت رازینە گوڤاردئن خوتوٙنە د ئی ڤیکی آلئشت بأکیت.", + "password-change-forbidden": "شما نمؽ تونؽت رازینٱ گوئارسن خوتوناْ د ئاؽ ڤیکی آلشت بٱکؽت.", "externaldberror": "اْشتبایؽ د اْرتبات ڤا رسینٱگا پیش اومایٱ یا شما سلا یٱ ناْ کاْ یاٛ هساو خارجی خوتو ناْ ڤ هنگوم سازی بٱکؽت نارؽت.", "login": "ڤامؽن اوماین", "nav-login-createaccount": " ڤامؽن اوماین/دۏرس کردن هساو", @@ -478,35 +478,35 @@ "retypenew": "رازینٱ گوئارسن تازٱ ناْ د نۊ ٱنجومیارنیسی بٱکؽت:", "resetpass_submit": "رازینٱ گوئارسن ناْ بٱزنؽت ۉ بؽایؽت ڤامؽن", "changepassword-success": "رازینە گوڤاردئن شوما ڤا خوٙیی آلئشت کاری بی!", - "changepassword-throttled": "شوما تا ایساْ سی ڤامؽن اوماین فرٱ تٱفرٱ کردؽتٱ.\n$1 لوتف بٱکؽت سی تٱفراٛ هنی گرؽ باٛسؽت.", - "resetpass_forbidden": "نأبوٙە رازینە گوڤاردنیانە آلئشتکاری بأکیت", - "resetpass-no-info": "شوما سی یە کئ د ئی بألگە دأسرئسی داشتوٙییت باس بیاییت ڤامین.", - "resetpass-submit-loggedin": "رارینە گوڤاردئن نە آلئشت بأکیت", - "resetpass-submit-cancel": "أنجوم شیڤئستئن", + "changepassword-throttled": "شما تا ایساْ سی ڤامؽن اوماین فرٱ تٱفرٱ کردؽتٱ.\n$1 لوتف بٱکؽت سی تٱفراٛ هنی گرؽ باٛسؽت.", + "resetpass_forbidden": "نمۊئٱ رازینٱ گوئارسنؽا ناْ آشتکاری بٱکؽت", + "resetpass-no-info": "شما سی یٱ کاْ د اؽ بٱلگٱ دٱسرسی داشتۊیؽت بایٱد بؽایؽت ڤامؽن.", + "resetpass-submit-loggedin": "رارینٱ گوئارسن ناْ آلشت بٱکؽت", + "resetpass-submit-cancel": "ٱنجوم شؽڤسن", "resetpass-wrong-oldpass": "رازینە گوڤاردئن تازە یا موڤأقأتی نادیارە.\nگاسی شوما ئیسئنی یا یا رازینە گوڤاردئن خوتوٙنە د خوٙیی آلئشت دأئیتە یا یئ گئل رازینە گوڤاردئن موڤأقأت هأنی حاستیتە.", "resetpass-recycled": "لوطف بأکیت رازینە گوڤاردئن خوتوٙنە سی چیا هأنی د رازینە گوڤاردئن ئیسئنی د نۊ زئنە بأکیت.", - "resetpass-temp-emailed": "شوما ڤا یئ گئل رازینە گوڤاردئن موڤأقأتی ئوٙمایتە ڤامین.\nسی ئوٙمائن ڤئ دأر، یئ گئل رازینە گوڤاردئن هأنی نە ئیچئ جاگئر(میزوٙنکاری) بأکیت.", - "resetpass-temp-password": "رازینە گوڤاردئن موڤأقأت:", - "resetpass-abort-generic": "آلئشت دأئن رازینە گوڤاردئن ڤا یئ گئل دئمادیس خئراڤ بییە.", - "resetpass-expired": "گات دیاری رازینە گوڤاردئن شوما تأموم بییە. لوطف بأکیت یئ گئل رازینە گوڤاردئن هأنی نە سی ڤامین ئوٙمائن میزوٙنکاری بأکیت.", + "resetpass-temp-emailed": "شما ڤا یاٛ رازینٱ گوئارسن موڤٱقٱتی اومایؽتٱ ڤامؽن.\nسی اوماین ڤ دٱر، یاٛ رازینٱ گوئارسن هنی ناْ ایچاْ جاگیر(میزونکاری) بٱکؽت.", + "resetpass-temp-password": "رازینٱ گوئارسن موڤٱقٱتت:", + "resetpass-abort-generic": "آلشت داٛئن رازینٱ گوئارسن ڤا یاٛ دمادیس خراو بیٱ.", + "resetpass-expired": "گات دؽاری رازینٱ گوئاردسن شما تموم بیٱ. لوتف بٱکؽت یاٛ رازینٱ گوئاردسن هنی ناْ سی ڤامؽن اوماین میزونکاری بٱکؽت.", "resetpass-expired-soft": "گات دیاری رازینە گوڤاردئن شوما تأموم بییە و باس د نۊ زئنە با. لوطف بأکیت یئ گئل رازینە گوڤاردئن هأنی نە ئنتئخاڤ بأکیت، یا سی د نۊ زئنە کئردئن د نئهاتئر د ئیچئ \"{{int:authprovider-resetpass-skip-label}}\" بأپوٙرنیت.", "resetpass-validity-soft": "رازینە گوڤاردئن توٙ نادیاره:$1\n\n لوطف بأکیت یئ گئل رازینە گوڤاردئن هأنی نە ئنتئخاڤ بأکیت، یا سی د نۊ زئنە کئردئن د نئهاتئر د ئیچئ \"{{int:authprovider-resetpass-skip-label}}\" بأپوٙرنیت.", - "passwordreset": "د نۊ داٛئن رازیٱ گوئاردن", - "passwordreset-text-one": "ئی نوم بألگە نە سی گئرئتئن یئ گئل رازینە گوڤاردئن موڤأقأت ڤا أنجومانامە توٙ پور بأکیت.", - "passwordreset-text-many": "{{PLURAL:$1|یئ گئل د جاگە یا نە سی گئرئتئن رازینە گوڤاردئن موڤأقأتی نە ڤا أنجومانامە گئرئتە بوٙأ پور بأکیت.}}", - "passwordreset-disabled": "نۊ کئردئن رازینە گوڤاردئن د ئی ڤیکی ناکونئشگأر بییە.", - "passwordreset-emaildisabled": "چیا هأنی کئ هان د أنجومانامە د ئی ڤیکی ناکونئشتگأر بینە.", + "passwordreset": "د نۊ داٛئن رازیٱ گوئارسن", + "passwordreset-text-one": "اؽ نوم بٱلگٱ ناْ سی گرتن یاٛ رازینٱ گوئارسن موڤٱقٱت ڤا ٱنجومانامٱ تو پور بٱکؽت.", + "passwordreset-text-many": "{{PLURAL:$1|یاٛ د جاگٱیا ناْ سی گرتن رازینٱ گوئارسن موڤٱقٱتی ناْ ڤا ٱنجومانامٱ گرتٱ بۊئٱ پور بٱکؽت.}}", + "passwordreset-disabled": "نۊ کردن رازینٱ گوئارسن د اؽ ڤیکی ناکونشگٱر بیٱ.", + "passwordreset-emaildisabled": "چیا هنی کاْ هان د ٱنجومانامٱ د اؽ ڤیکی ناکونشگٱر بیٱ.", "passwordreset-username": "نوم کاریاری:", - "passwordreset-domain": "پوشگئر", - "passwordreset-email": "تیرنئشوٙن أنجومانامە", - "passwordreset-emailtitle": "جوزئیات حئساڤ ها د {{نوم مالگە}}", + "passwordreset-domain": "پۊشگر", + "passwordreset-email": "تیرنشوݩ ٱنجومانامٱ", + "passwordreset-emailtitle": "جۏزیات هساو ها د {{نوم مالگٱ}}", "passwordreset-emailtext-ip": "یە کئسی(گاسی خوتوٙ، ڤا تیرنئشوٙن آی پی $1) د نۊ زئنە کئردئن رازینە گوڤاردئنئتوٙ د {{SITENAME}} حاستیتە($4).\nسی کاریار «$2» یئ گئل رازینە گوڤاردئن موڤأقتی رأڤأندیاری بییە و هومبأراڤأر «$3» ە.\nأر دالئتوٙ یە بییە ئیسئ ڤاس بیائیت ڤامین ساموٙنە و یئ گئل رازینە گوڤاردئن هأنی بئهایت.\n رازینە گوڤاردئن {{PLURAL:$3|ئی رازینە یا گوڤاردئن موڤأقأتی|ئی رازینە یا گوڤاردئن موڤأقأتی}} شوما د گات {{PLURAL:$5|یئ روٙ|$5 روٙ}} باطئل بوٙە.\n\nأر کأسی هأنی چئن حاستی داشتە یا یە کئ رازینە گوڤاردئن دئمایی شوما د ڤیرئتوٙ ئوٙما و دە نئمیهایت ڤئنە آلئشت کاری بأکیت، می توٙنیت د ئی پئیغوم تیە پوٙشی بأکیت و هأموٙ رازینە گوڤاردئن دئمایی نە بونیت د کار.", "passwordreset-emailtext-user": "کاریار $1 د {{SITENAME}} د نۊ زئنە کئردئن رازینە گوڤاردئن شومانە د{{SITENAME}} ($4) حاستە. {{PLURAL:$3|حئساڤ|حئساڤیا}} کاریاری کئ هان د هار و ڤا ئی تیرنئشوٙن أنجومانامە هان د ئرتئڤاط:\n\n$2\n\n رازینە گوڤاردئن {{PLURAL:$3|ئی رازینە یا گوڤاردئن موڤأقأتی|ئی رازینە یا گوڤاردئن موڤأقأتی}} شوما د گات {{PLURAL:$5|یئ روٙ|$5 روٙ}} باطئل بوٙە.\nأر کأسی هأنی چئن حاستی داشتە یا یە کئ رازینە گوڤاردئن دئمایی شوما د ڤیرئتوٙ ئوٙما و دە نئمیهایت ڤئنە آلئشت کاری بأکیت، می توٙنیت د ئی پئیغوم تیە پوٙشی بأکیت و هأموٙ رازینە گوڤاردئن دئمایی نە بونیت د کار.", - "passwordreset-emailelement": "نوم کاریاری: \n$1\n\nرازینە گوڤاردئن موڤأقتی: \n$2", + "passwordreset-emailelement": "نوم کاریاری: \n$1\n\nرازینٱ گوئارسن موڤٱقتی: \n$2", "passwordreset-emailsentemail": "یئ گئل رازینە گوڤاردئن هأنی سی أنجومانامە کئل بییە.", "changeemail": "أنجومانامە توٙنە آلئشت کاری بأکیت", - "changeemail-header": "ئی فورمئ نە سی آلئشتکاری أنجومانامە توٙ پور بأکیت. أر میھایت ھأر جوٙر أنجومانامە یی نە د مینجا حئساڤئتوٙ پاکسا بأکیت، جاگە دأئن أنجومانامە نئ د چئنی فورمی حالی بأنیت.", - "changeemail-no-info": "شوما سی یە کئ د ئی بألگە دأسرئسی داشتوٙییت باس بیاییت ڤامین.", + "changeemail-header": "اؽ فورم ناْ سی آلشتکاری ٱنجومانامٱ تو پور بٱکؽت. ٱر مؽهایت ھٱر جۊر ٱنجومانامٱ ناْ د مؽنجا هساو تو پاکسا بٱکؽت، جاگٱ داٛئن ٱنجومانامٱ ناْ د چنی فورمؽ هالٛی بٱنؽت.", + "changeemail-no-info": "شما سی یٱ کاْ ڤ اؽ بٱلگٱ دٱسرسی داشتۊیؽت بایٱد بؽایؽت ڤامؽن.", "changeemail-oldemail": "تیرنئشوٙن أنجومانامە ئیسئنی:", "changeemail-newemail": "تیرنئشوٙن أنجومانامە تازە:", "changeemail-newemail-help": "أر شوما میھایت تیرنئشوٙن أنجفونامە توٙنە ڤئرداریت چئنی جاگە یی نە بایأد حالی بأنیت. شوما. ئوٙسئ أر رازینە گورادئنئتوٙ د ڤیرتوٙ رأتە با نئمی توٙنیت د نۊ زئنەش بأکیت و ھأنی ھیچ جوٙر أنجومانامە یی د ئی ڤیکی ڤئ دأس شوما نئمی رئسە.-", diff --git a/languages/i18n/nb.json b/languages/i18n/nb.json index 026a5b8156..c97fb36e74 100644 --- a/languages/i18n/nb.json +++ b/languages/i18n/nb.json @@ -424,6 +424,8 @@ "virus-scanfailed": "skanning mislyktes (kode $1)", "virus-unknownscanner": "ukjent antivirusprogram:", "logouttext": "'''Du er nå logget ut.'''\n\nVær oppmerksom på at noen sider kan fortsette å dukke opp som om du fortsatt var innlogget, helt til du nullstiller nettleserens mellomlager (cache).", + "logging-out-notify": "Du blir logget ut, vennligst vent.", + "logout-failed": "Kan ikke logge ut nå: $1", "cannotlogoutnow-title": "Kan ikke logge ut nå", "cannotlogoutnow-text": "Å logge ut er ikke mulig ved bruk av $1.", "welcomeuser": "Velkommen $1!", diff --git a/languages/i18n/nqo.json b/languages/i18n/nqo.json index 3148cf12f8..4ba091c935 100644 --- a/languages/i18n/nqo.json +++ b/languages/i18n/nqo.json @@ -10,6 +10,10 @@ "Babamamadidiane" ] }, + "tog-underline": "ߛߘߌ߬ߜߋ߲߬ ߞߘߐߞߍ߬ߙߍ߲߬ߘߍ߬ߣߍ߲", + "tog-hideminor": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߘߋ߬ߣߍ߲ ߠߎ߬ ߢߡߊߘߏ߲߰ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߞߐ߯ߟߕߊ ߟߎ߬ ߘߐ߫", + "tog-hidepatrolled": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߓߍ߬ߙߍ߲߬ߓߍ߬ߙߍ߲߬ߣߍ߲ ߠߎ߬ ߢߡߊߘߏ߲߰ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߞߐ߯ߟߕߊ ߟߎ߬ ߘߐ߫.", + "tog-newpageshidepatrolled": "ߞߐߜߍ߫ ߓߍ߬ߙߍ߲߬ߓߍ߬ߙߍ߲߬ߣߍ߲ ߠߎ߬ ߢߡߊߘߏ߲߰ ߞߐߜߍ߫ ߞߎߘߊ ߟߎ߬ ߘߐ߫.", "tog-hidecategorization": "ߞߐߜߍ ߟߎ߬ ߦߌߟߡߊߦߊߟߌ ߢߡߊߘߏ߲߰", "tog-numberheadings": "ߕߍ߰ߟߌ ߡߐ߬ߟߐ߲ ߠߎ߬ ߝߙߍߕߍ߫ ߞߍ߲ߖߘߍߡߊߓߟߏߡߊ߬", "tog-editondblclick": "ߞߏߜߍ ߟߎ߬ ߡߊߦߟߍ߬ߡߊ߲߫ ߛߐ߲߬ߞߌ߲߬ߠߌ߲߬ߞߏ ߝߌ߬ߟߊ߬ ߟߊ߫", @@ -101,6 +105,7 @@ "anontalk": "ߢߊߝߐߞߣߍ", "navigation": "ߛߏ߲߯ߓߊߟߌ", "and": " ߊ߬ ߣߌ߫", + "faq": "ߢ.ߡ", "actions": "ߞߍߟߌ ߟߎ߬", "namespaces": "ߕߐ߯ ߛߓߍ ߞߣߍ", "variants": "ߦߟߍ߬ߡߊ߲߬ߦߟߍ߬ߡߊ߲߬ߠߊ ߟߎ߬", @@ -215,11 +220,18 @@ "nosuchspecialpage": "ߘߐߜߍ߫ ߓߟߏߡߊߞߊ߬ߣߍ߲߬ ߛߎ߮ ߏ߬ ߝߋ߲߫ ߕߍ߫ ߦߊ߲߬", "nospecialpagetext": "ߊߟߎ߫ ߓߘߊ߫ ߞߐߜߍ߫ ߓߟߏߡߊߞߊ߬ߣߍ߲ ߘߏ߫ ߢߌߣߌ߲߫ ߡߍ߲ ߕߺߴߦߋ߲߬.\nߞߐߜߍ߫ ߓߟߏߡߊߞߊ߬ߣߍ߲߫ ߓߘߍ߬ߡߊ ߟߎ߬ ߛߙߍߘߍ ߦߋ߫ ߢߌ߲߬ ߠߋ߫ ߞߊ߲߬ [[Special:SpecialPages|{{int:specialpages}}]].", "error": "ߝߎ߬ߕߎ߲߬ߕߌ", + "databaseerror-error": "ߝߎ߬ߕߎ߲߬ߕߌ: $1", + "internalerror": "ߞߣߐߟߊߘߐ߫ ߝߎߕߎ߲ߕߌ", + "internalerror_info": "ߞߣߐߟߊߘߐ߫ ߝߎ߬ߕߎ߲߬ߕߌ: $1", + "filecopyerror": "ߊ߬ ߕߍ߫ ߣߊ߬ ߛߐ߲߬ ߠߊ߫ ߞߐߕߐ߮ $1 ߓߊߦߟߍ߬ߡߊ߲߬ ߠ ߦߊ߲߬ߊ߫ $2", + "filerenameerror": "ߞߐߕߐ߮ \"$1\" ߕߍ߫ ߛߐ߲߬ ߓߊߦߟߍ߬ߡߊ߲߬ ߠߊ߫ ߦߊ߲߬ \"$2\".", "badtitle": "ߞߎ߲߬ߕߐ߰ ߖߎ߮", "badtitletext": "ߞߐߜߍ߫ ߡߊߢߌ߬ߣߌ߲߬ߞߊ߬ߣߍ߲ ߞߎ߲߬ߕߐ߮ ߓߍ߲߬ߣߍ߲߬ ߕߍ߫߸ ߊ߬ ߘߐߞߏߟߏ߲ ߦߋ߫߸ ߥߟߊ߫ ߞߊ߲ ߠߎ߬ ߣߌ߫ ߢߐ߲߯ߕߍ߫ ߛߘߌ߬ߜߋ߲ ߓߍ߲߬ߓߊߟߌ ߤߊߡߊ߲߫ ߥߞߌ ߟߎ߬ ߕߍ߫ ߛߘߌ߬ߜߋ߲.\nߛߓߍߘߋ߲߫ ߞߋߟߋ߲߫ ߥߟߊ߫ ߛߌߦߊߡߊ߲ ߠߎ߬ ߟߋ߬ ߦߋ߫ ߞߍ߫ ߟߴߊ߬ ߘߐ߫߸ ߡߍ߲ ߠߎ߬ ߕߴߛߋ߫ ߞߍ߫ ߟߊ߫ ߞߎ߲߬ߕߐ߯ ߘߌ߫.", "viewsource": "ߊ߬ ߛߎ߲ ߘߐߜߍ߫", "viewsource-title": "ߣߌ߲߬ $1 ߛߎ߲ ߘߐߜߍ߫", "viewsourcetext": "ߌ ߘߌ߫ ߛߋ߫ ߞߐߜߍ ߣߌ߲߬ ߛߎ߲ ߦߋ߫ ߟߊ߫߸ ߞߵߊ߬ ߓߊߓߌ߬ߟߊ߬", + "invalidtitle": "ߞߎ߲߬ߕߐ߮ ߓߍ߲߬ߓߊߟߌ", + "exception-nologin": "ߌ ߜߊ߲߬ߞߎ߲߬ߣߍ߲߬ ߕߍ߫", "yourname": "ߟߊߓߊ߯ߙߊߟߊߕߐ߮:", "userlogin-yourname": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߬ ߕߐ߮", "userlogin-yourname-ph": "ߌ ߟߊ߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߬ ߕߐ߮ ߟߊߘߏ߲߬", @@ -233,14 +245,20 @@ "createacct-yourpasswordagain-ph": "ߌ ߟߊ߫ ߕߊ߬ߡߌ߲߬ߞߊ߲ ߠߊߘߏ߲߬ ߕߎ߲߯", "userlogin-remembermypassword": "ߒ ߜߊ߲߬ߞߎ߲߬ߣߍ߲ ߕߏ߫ ߞߘߊߎ߫", "login": "ߌ ߜߊ߲߬ߞߎ߲߬", + "nav-login-createaccount": "ߌ ߜߊ߲߬ߞߎ߲߬/ߖߊ߬ߕߋ߬ߘߊ ߘߏ߫ ߟߊߞߊ߬", + "logout": "ߌ ߜߊ߲߬ߞߎ߲߬ ߓߐ߫", + "userlogout": "ߌ ߜߊ߲߬ߞߎ߲߬ߣߍ߲ ߓߐ߫", "userlogin-noaccount": "ߖߊ߬ߕߋ߬ߘߊ߬ ߕߴߌ ߓߟߏ߫ ߓߊ߬؟", "userlogin-joinproject": "ߘߏ߫ ߟߊߞߊ߬ {{SITENAME}}", "createaccount": "ߖߊ߬ߕߋ߬ߘߊ ߘߏ߫ ߟߊߞߊ߬", "userlogin-resetpassword-link": "ߌ ߟߊ߫ ߕߊ߬ߡߌ߲߬ߞߊ߲ ߓߘߊ߫ ߓߐ߫ ߌ ߞߣߐ߫؟", "userlogin-helplink2": "ߜߊ߲߬ߞߎ߲߬ߠߌ߲ ߘߍ߬ߡߍ߲߬ߠߌ߲", + "userlogin-createanother": "ߖߊ߬ߕߋ߬ߘߊ߬ ߞߎߘߊ߫ ߛߌ߲ߘߌ߫", "createacct-emailoptional": "ߢߎߡߍߙߋ߲߫ ߞߏ߲ߘߏ", "createacct-email-ph": "ߌ ߟߊ߫ ߢߎߡߍߙߋ߲߫ ߞߏ߲ߘߏ ߟߊߘߏ߲߬", + "createacct-reason-ph": "ߡߎ߲߬ߠߊ߫ ߌ ߦߋ߫ ߖߊ߬ߕߋ߬ߘߊ߰ ߜߘߍ߫ ߛߌ߲ߘߌ߫ ߟߊ߫", "createacct-submit": "ߖߊ߬ߕߋ߬ߘߊ ߘߏ߫ ߘߊߦߟߍ߬", + "createacct-another-submit": "ߖߊ߬ߕߋߘߊ ߛߌ߲ߘߌ߫", "createacct-benefit-heading": "{{SITENAME}} ߛߌ߲ߘߌߣߍ߲߫ ߦߴߌ ߢߐ߲߭ ߡߐ߱ ߟߎ߬ ߟߋ߬ ߓߟߏ߫", "createacct-benefit-body1": "{{PLURAL:$1|ߊ߬ ߡߊߦߟߍ߬ߡߊ߲߬|ߊ߬ߟߎ߬ ߡߊߦߟߍ߬ߡߊ߲߬}}", "createacct-benefit-body2": "$1 {{PLURAL:$1|ߘߐߜߍ|ߞߐߜߍ ߟߎ߬}}", @@ -250,6 +268,13 @@ "pt-login-button": "ߌ ߜߊ߲߬ߞߎ߲߬", "pt-createaccount": "ߖߊ߬ߕߋ߬ߘߊ ߘߏ߫ ߛߌ߲ߘߌ߫", "pt-userlogout": "ߌ ߜߊ߲߬ߞߎ߲߬ߣߍ߲ ߓߐ߫", + "changepassword": "ߕߊ߬ߡߌ߲߬ߞߊ߲ ߡߊߝߊ߬ߟߋ߲߬", + "resetpass_announce": "ߣߴߌ ߦߴߊ߬ ߝߍ߬ ߞߵߌ ߟߊ߫ ߜߊ߲߬ߞߎ߲߬ߠߌ߲ ߠߊߓߊ߲߫߸ ߌ ߦߋ߫ ߖߊ߬ߕߋ߬ߘߊ߰ ߞߎߘߊ߫ ߟߊߘߊ߲߫.", + "resetpass_header": "ߖߊ߬ߕߋ߬ߘߊ ߕߊ߬ߡߌ߲߬ߞߊ߲ ߡߊߝߊ߬ߟߋ߲߬", + "oldpassword": "ߕߊ߬ߡߌ߲߬ߞߊ߲߬ ߞߘߐ", + "newpassword": "ߕߊ߬ߡߌ߲߬ߞߊ߲߬ ߞߎߘߊ", + "retypenew": "ߕߊ߬ߡߌ߲߬ߞߊ߲߬ ߞߎߘߊ ߡߊߛߊ߬ߦߌ߬", + "resetpass_submit": "ߕߊ߬ߡߌ߲߬ߞߊ߲ ߠߊߘߏ߲߬ ߞߵߌ ߜߊ߲߬ߞߎ߲߬", "passwordreset": "ߕߊ߬ߡߌ߲߬ߞߊ߲ ߡߊߦߟߍ߬ߡߊ߲߬", "bold_sample": "ߛߓߍߘߋ߲߫ ߞߎ߲ߓߊ", "bold_tip": "ߛߓߍߘߋ߲߫ ߞߎ߲ߓߊ", @@ -271,10 +296,13 @@ "minoredit": "ߣߌ߲߬ ߦߋ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߘߋ߬ߣߍ߲ ߘߏ߫ ߟߋ߬ ߘߌ߫", "watchthis": "ߘߐߜߍ ߣߌ߲߬ ߘߐߜߍ߫", "savearticle": "ߊ߬ ߟߊߞߎ߲߬ߘߎ߬", + "savearticle-start": "ߞߐߜߍ ߟߊߞߎ߲߬ߘߎ߬", + "savechanges-start": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߠߊߞߎ߲߬ߘߎ߬", "preview": "ߊ߬ ߘߐߜߍ߫ ߡߎߣߎ߲߬", "showpreview": "ߢߍߦߋߟߌ ߘߐߜߍ߫", "showdiff": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ ߠߎ߫ ߦߌ߬ߘߊ߬", "anoneditwarning": "Warning: ߌ ߜߊ߲߬ߞߎ߲߬ߣߍ߲߬ ߕߍ߫.ߌ ߓߊ߯ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߛߎ߯-ߎ߯-ߛߎ߫ ߞߍ߫߸ ߌ ߟߊ߫ IP ߛߊ߲߬ߓߊ߬ߕߐ߮ ߘߌ߫ ߞߍ߫ ߦߋߕߊ ߘߌ߫.ߣߴߌ ߞߊ߬ ߜߊ߲߬ߞߎ߲߬ߠߌ߲߬ ߖߐ߲ߖߐ߲ ߞߍ߫ ߕߎ߬ߡߊ ߡߍ߲ [$1 log in] or [$2 create an account] ߌ ߟߊ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߣߍ߲ ߠߎ߬ ߘߌ߫ ߓߌ߬ߟߊ߬ ߌ ߜߊ߲߬ߞߎ߲߬ ߕߐ߮ ߟߊ߫߸ ߊ߬ ߣߌ߫ ߣߝߊ߬ ߜߘߍ߫ ߟߎ߫.", + "anonpreviewwarning": "ߌ ߜߊ߲߬ߞߎ߲߬ߣߍ߲߬ ߕߍ߫. ߟߊ߬ߞߎ߲߬ߘߎ߬ߟߌ ߘߴߌ ߟߊ߫ IP ߛߊ߲߬ߓߊ߬ߕߐ߮ ߟߊߡߙߊ߬ ߞߐߜߍ ߣߌ߲߬ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߘߐ߬ߝߐ ߘߐ߫", "blockedtext": "ߌ ߟߊ߫ ߟߊ߬ߓߊ߰ߙߊ߬ ߕߐ߮ ߥߟߊ߫ IP ߛߊ߲߬ߓߊ߬ߕߐ߮ ߓߘߊ߫ ߓߊ߬ߟߊ߲߬߸\n\nߌ ߓߊ߬ߟߊ߲߬ߣߍ߲߬ ߦߋ߫ $1 ߟߋ߬ ߓߟߏ߫.\nߞߎ߲߭ ߡߍ߲ ߦߴߊ߬ ߟ߫ߊ߫ $2.\n\n•ߓߊ߬ߟߊ߲߬ߠߌ߲ ߘߊߡߌ߬ߣߊ: $8\n•ߓߊ߬ߟߊ߲߬ߠߌ߲ ߛߕߊ ߝߊ: $6\n•ߓߊ߬ߟߊ߲߬ߠߌ߲ ߘߊ߬ߟߎ: $7 \n\nߌ ߘߌ߫ ߛߋ߫ ߗߋߛߓߍ ߗߋ߫ ߟߊ߫ $1 ߡߊ߬ ߥߟߊ߫ ߡߐ߰ ߜߘߍ߫ \n[[{{MediaWiki:Grouppage-sysop}}|administrator]] ߞߊ߬ ߘߊߘߐߖߊߥߏ ߞߍ߫ ߓߊ߬ߟߊ߲߬ߠߌ߲ ߞߊ߲߬.\nߌ ߕߍ߫ ߣߊ߬ ߛߋ߫ ߟߊ߫ \"{{int:emailuser}}\" ߟߊߓߊ߯ߙߊ߫ ߟߊ߫߸ ߟߊ߬ߓߊ߰ߙߊ߬ߢߊ߬ ߖߐ߲ߖߐ߲ ߡߍ߲ ߦߋ߫ ߦߋ߲߬߸ ߢߎߡߍߙߋ߲߫ ߞߏ߲ߘߏ߫ ߖߐ߲ߖߐ߲߫ ߓߟߏߡߊߞߊ߬ߣߍ߲ ߘߏ߫ ߦߴߌ ߟߊ߫ [[Special:Preferences|account preferences]] ߘߐ߫߸ ߊ߬ ߣߴߌ ߡߊ߫ ߓߊ߬ߟߊ߲߬ ߊ߬ ߟߊߓߊ߯ߙߊ ߞߏߛߐ߲߬ ߘߋ߫. ߌ ߟߊ߫ IP ߛߊ߲߬ߓߊ߬ߕߐ߮ ߦߋ߫ $3 ߟߋ߬ ߘߌ߫ ߕߊ߲߬߸ ߊ߬ ߣߴߌ ߟߊ߫ ߛߊ߲߬ߓߊ߬ߕߐ߮ ߓߊ߬ߟߊ߲߬ߣߍ߲ ߦߋ߫ #$5 ߟߋ߬ ߘߌ߫.\nߖߊ߰ߣߌ߲߬ ߌ ߦߋ߫ ߛߊ߲ߝߍ߫ ߝߊߙߊ߲ߝߊ߯ߛߌ ߣߌ߲߬ ߓߍ߯ ߟߊߘߏ߲߬ ߌ ߟߊ߫ ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߘߐ߫.", "loginreqlink": "ߌ ߜߊ߲߬ߞߎ߲߬", "newarticletext": "ߌ ߓߘߊ߫ ߛߘߌ߬ߜߋ߲ ߘߏ߫ ߟߊߓߊ߬ߕߏ߬ ߞߐߜߍ ߘߏ߫ ߘߐ߫߸ ߡߍ߲ ߕߴߦߋ߲߬ ߡߎߣߎ߲߬.\nߣߵߌ ߦߴߊ߬ ߝߍ߫ ߞߊ߬ ߞߐߜߍ ߘߏ߫ ߟߊߘߊ߲߫߸ ߛߓߍߟߌ ߘߊߡߌ߬ߣߊ߬ ߘߎ߰ߟߊ߬ߘߐ߫ ߞߏ߲ߘߏ ߘߐ߫ (ߞߊ߬ [$1 ߘߍ߬ߡߍ߲߬ߠߌ߲ ߞߐߜߍ] ߦߋ߫߸ ߖߐ߲߬ߛߊ߬ ߌ ߘߌ߫ ߞߌ߬ߓߊ߬ߙߏ߬ ߖߐ߲ߖߐ߲ ߛߐ߬ߘߐ߲߬). ߣߵߌ ߘߏ߲߬ ߞߍ߫ ߘߊ߫ ߦߊ߲߬ ߝߎ߬ߕߎ߲߬ߕߌ߬ ߓߟߏߡߊ߬߸ ߌ ߟߊ߫ ߛߏ߲߯ߓߊߟߊ߲ back ߛߐ߲߬ߞߌ߲߫.", @@ -307,6 +335,7 @@ "nextrevision": "ߡߊ߬ߛߋ߬ߦߌ߲߬ߣߍ߲߬ ߞߎߘߊ ←", "currentrevisionlink": "ߡߊ߬ߛߊ߬ߦߌ߲߬ߠߌ߲ ߕߊ߬ߡߌ߲߬ߣߍ߲", "cur": "ߞߍߞߎߘߊ", + "next": "ߢߍߕߊ", "last": "ߢߍߕߊ", "histlegend": "ߝߘߏ߬ߢߐ߲߰ߡߊ ߡߊߡߌ߬ߘߊ: ߓߊߓߌߟߊߟߌ߫ ߞߏ߲ߘߏ ߡߊߡߌ߬ߘߊ߬ ߟߊߢߐ߲߯ߡߊ߫ ߞߊߡߊ߬߸ ߊ߬ ߣߌ߫ ߞߊ߬ ߟߊߢߐ߲߯ߡߊ߫ ߞߘߎ ߛߐ߲߬ߞߌ߲߫ ߊ߬ ߣߌ߫ ߓߊ߫ ߡߊߡߌ߬ߣߊ߬ߣߍ߲ ߕߍ߫ ߥߟߊ߫ ߞߎ߬ߘߎ ߡߍ߲ ߦߋ߫ ߘߎ߰ߟߊ߫. < br/> Legend: ({{int: cur}}) = ߓߐߢߐ߲߯ߡߊ ߡߍ߲ ߦߋ߫ ߕߋ߲߬ߕߋ߲߬ ߓߊ ߟߊ߫߸ ({{int: ߟߊߓߊ߲}}) = ߓߐߢߐ߲߯ߡߊ ߡߍ߲ ߦߋ߫ ߓߊ߫ ߕߊ߬ߡߌ߲߬ߣߍ߲ ߝߍ߬߸ {{int: ߢߟߊߞߎߘߦߊ߫ ߞߏߘߋߞߏߘߋ}} = ߛߊߞߍߟߌ߫ ߝߕߌߣߍ߲߫.", "history-fieldset-title": "ߣߐ߬ߡߊ߬ߛߊߦߌ߲ ߠߎ߬ ߛߍ߲ߛߍ߲߫", @@ -315,6 +344,7 @@ "history-feed-title": "ߡߊ߬ߛߊ߬ߦߌ߲߬ߠߌ߲ ߘߐ߬ߝߐ", "history-feed-description": "ߞߐߜߍ ߣߌ߲߬ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߘߐ߬ߝߐ߸ ߥߞߌ ߘߐ߫", "rev-delundel": "ߊ߬ ߦߋߢߊ ߡߊߦߟߍ߬ߡߊ߲߫", + "revdelete-show-file-submit": "ߐ߲߬ߐ߲߬ߐ߲߫", "mergelog": "ߥߴߌ ߜߊ߲߬ߞߎ߲߬", "history-title": "$1 ߡߛߊ߬ߦߌ߲߬ߠߌ߲ ߘߐ߬ߝߐ", "difference-title": "ߘߊ߲߬ߝߘߊ߬ߓߐ ߡߍ߲ ߦߋ߫ ߡߛߊ߬ߦߌ߲߬ߠߌ߲ $1 ߕߍ߫", @@ -352,6 +382,7 @@ "search-showingresults": "{{PLURAL:$4|Result $1 of $3|Results $1 – $2 of $3}}", "search-nonefound": "ߖߋ߬ߓߟߌ߬ ߛߌ߫ ߕߍ߫ ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߣߌ߲߫ ߞߊ߲߬.", "mypreferences": "ߟߊ߬ߝߌ߬ߛߦߊ߬ߟߌ", + "timezoneregion-africa": "ߊߝߙߌߞߌ߬", "group-bot": "ߓߏߕ", "group-sysop": "ߞߎ߲߬ߠߊ߬ߛߌ߰ߟߊ", "grouppage-bot": "{{ns:project}}:ߓߏߕ", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 10fdb84333..683e975bd4 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -4252,6 +4252,9 @@ "mw-widgets-abandonedit-discard": "Text shown on the button which closes an editor and discards changes when the user confirms that they want to leave the editor.\n\nPreceded by the prompt {{msg-mw|mw-widgets-abandonedit}}.\n\nFollowed by the button {{msg-mw|mw-widgets-abandonedit-keep}}.", "mw-widgets-abandonedit-keep": "Text shown on the button which does not do anything when the user decides that they do not want to leave the editor.\n\nPreceded by the button {{msg-mw|mw-widgets-abandonedit-discard}}.", "mw-widgets-abandonedit-title": "Title of the dialog shown when the user tries to leave the editor without saving their changes.\n\nFollowed by the following buttons:\n* {{msg-mw|mw-widgets-abandonedit-discard}}\n* {{msg-mw|mw-widgets-abandonedit-keep}}\n{{Identical|Are you sure?}}", + "mw-widgets-copytextlayout-copy": "Label of button to copy text to clipboard.", + "mw-widgets-copytextlayout-copy-fail": "Message shown when copying to clipboard failed.", + "mw-widgets-copytextlayout-copy-success": "Message shown when copying to clipboard failed.", "mw-widgets-dateinput-no-date": "Label of a date input field when no date has been selected.", "mw-widgets-dateinput-placeholder-day": "[[File:DateInputWidget active, empty.png|frame|Screenshot]]\nPlaceholder displayed in a date input field when it's empty, representing a date format with 4 digits for year, 2 digits for month, and 2 digits for day, separated with hyphens. This should be uppercase, if possible, and must not include any additional explanations. If there is no good way to translate it, make this message blank.", "mw-widgets-dateinput-placeholder-month": "Placeholder displayed in a date input field when it's empty, representing a date format with 4 digits for year and 2 digits for month, separated with hyphens (without a day). This should be uppercase, if possible, and must not include any additional explanations. If there is no good way to translate it, make this message blank.", diff --git a/languages/i18n/sr-ec.json b/languages/i18n/sr-ec.json index 0dfdb07412..3da455d9a3 100644 --- a/languages/i18n/sr-ec.json +++ b/languages/i18n/sr-ec.json @@ -818,7 +818,7 @@ "nohistory": "Не постоји историја измена ове странице.", "currentrev": "Најновија измена", "currentrev-asof": "Најновија измена на датум $2 у $3", - "revisionasof": "Измена на датум $2 у $3", + "revisionasof": "Измена на датум $1", "revision-info": "Измена од $1 од стране {{GENDER:$6|корисника $2|кориснице $2}}$7", "previousrevision": "← Старија измена", "nextrevision": "Новија измена →", diff --git a/languages/i18n/sr-el.json b/languages/i18n/sr-el.json index 836f8add5a..0a2da29bab 100644 --- a/languages/i18n/sr-el.json +++ b/languages/i18n/sr-el.json @@ -809,7 +809,7 @@ "nohistory": "Ne postoji istorija izmena ove stranice.", "currentrev": "Najnovija izmena", "currentrev-asof": "Najnovija izmena na datum $2 u $3", - "revisionasof": "Izmena na datum $2 u $3", + "revisionasof": "Izmena na datum $1", "revision-info": "Izmena od $1 od strane {{GENDER:$6|korisnika $2|korisnice $2}}$7", "previousrevision": "← Starija izmena", "nextrevision": "Novija izmena →", diff --git a/languages/i18n/sv.json b/languages/i18n/sv.json index 5cd8455485..52f2e9f3a8 100644 --- a/languages/i18n/sv.json +++ b/languages/i18n/sv.json @@ -451,6 +451,8 @@ "virus-scanfailed": "skanning misslyckades (kod $1)", "virus-unknownscanner": "okänt antivirusprogram:", "logouttext": "Du är nu utloggad.\n\nObservera att det, tills du tömmer din webbläsares cache, på vissa sidor kan det se ut som att du fortfarande är inloggad.", + "logging-out-notify": "Du loggas ut, var god vänta.", + "logout-failed": "Kan inte logga ut nu: $1", "cannotlogoutnow-title": "Kan inte logga ut nu", "cannotlogoutnow-text": "Det går inte att logga ut med $1.", "welcomeuser": "Välkommen, $1!", diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index d0115ea770..666b28f82e 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -37,13 +37,6 @@ $digitTransformTable = null; */ $separatorTransformTable = null; -/** - * Extra user preferences, which will be shown in Special:Preferences as - * checkboxes. Extra settings in derived languages will automatically be - * appended to the array of the fallback languages. - */ -$extraUserToggles = []; - /** * URLs do not specify their encoding. UTF-8 is used by default, but if the * URL is not a valid UTF-8 sequence, we have to try to guess what the real diff --git a/maintenance/benchmarks/benchmarkPurge.php b/maintenance/benchmarks/benchmarkPurge.php index e681a0498e..bb41a91093 100644 --- a/maintenance/benchmarks/benchmarkPurge.php +++ b/maintenance/benchmarks/benchmarkPurge.php @@ -1,6 +1,6 @@ addDescription( 'Benchmark the Squid purge functions.' ); + $this->addDescription( 'Benchmark the CDN purge functions.' ); } public function execute() { - global $wgUseSquid, $wgSquidServers; - if ( !$wgUseSquid ) { - $this->fatalError( "Squid purge benchmark doesn't do much without squid support on." ); + global $wgUseCdn, $wgCdnServers; + + if ( !$wgUseCdn ) { + $this->error( "CDN purge benchmark doesn't do much without CDN support on." ); } else { - $this->output( "There are " . count( $wgSquidServers ) . " defined squid servers:\n" ); + $this->output( "There are " . count( $wgCdnServers ) . " defined CDN servers:\n" ); if ( $this->hasOption( 'count' ) ) { $lengths = [ intval( $this->getOption( 'count' ) ) ]; } else { @@ -47,7 +48,7 @@ class BenchmarkPurge extends Benchmarker { } foreach ( $lengths as $length ) { $urls = $this->randomUrlList( $length ); - $trial = $this->benchSquid( $urls ); + $trial = $this->benchCdn( $urls ); $this->output( $trial . "\n" ); } } @@ -55,12 +56,12 @@ class BenchmarkPurge extends Benchmarker { /** * Run a bunch of URLs through CdnCacheUpdate::purge() - * to benchmark Squid response times. + * to benchmark CDN response times. * @param array $urls A bunch of URLs to purge * @param int $trials How many times to run the test? * @return string */ - private function benchSquid( $urls, $trials = 1 ) { + private function benchCdn( $urls, $trials = 1 ) { $start = microtime( true ); for ( $i = 0; $i < $trials; $i++ ) { CdnCacheUpdate::purge( $urls ); diff --git a/maintenance/purgeChangedPages.php b/maintenance/purgeChangedPages.php index 81fb5e39d7..8f47b1605f 100644 --- a/maintenance/purgeChangedPages.php +++ b/maintenance/purgeChangedPages.php @@ -136,9 +136,9 @@ class PurgeChangedPages extends Maintenance { } } - // Send batch of purge requests out to squids - $squid = new CdnCacheUpdate( $urls, count( $urls ) ); - $squid->doUpdate(); + // Send batch of purge requests out to CDN servers + $cdn = new CdnCacheUpdate( $urls, count( $urls ) ); + $cdn->doUpdate(); if ( $this->hasOption( 'sleep-per-batch' ) ) { // sleep-per-batch is milliseconds, usleep wants micro seconds. diff --git a/maintenance/purgeList.php b/maintenance/purgeList.php index 16a62f405d..d558c478e8 100644 --- a/maintenance/purgeList.php +++ b/maintenance/purgeList.php @@ -1,6 +1,6 @@ addDescription( 'Send purge requests for listed pages to squid' ); + $this->addDescription( 'Send purge requests for listed pages to CDN' ); $this->addOption( 'purge', 'Whether to update page_touched.', false, false ); $this->addOption( 'namespace', 'Namespace number', false, true ); $this->addOption( 'all', 'Purge all pages', false, false ); @@ -120,7 +120,7 @@ class PurgeList extends Maintenance { /** * Helper to purge an array of $urls - * @param array $urls List of URLS to purge from squids + * @param array $urls List of URLS to purge from CDNs */ private function sendPurgeRequest( $urls ) { if ( $this->hasOption( 'delay' ) ) { diff --git a/opensearch_desc.php b/opensearch_desc.php index bd3281aa9c..15ec62d0e5 100644 --- a/opensearch_desc.php +++ b/opensearch_desc.php @@ -36,7 +36,7 @@ if ( $wgRequest->getVal( 'ctype' ) == 'application/xml' ) { $response = $wgRequest->response(); $response->header( "Content-type: $ctype" ); -// Set an Expires header so that squid can cache it for a short time +// Set an Expires header so that CDN can cache it for a short time // Short enough so that the sysadmin barely notices when $wgSitename is changed $expiryTime = 600; # 10 minutes $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expiryTime ) . ' GMT' ); diff --git a/resources/Resources.php b/resources/Resources.php index 4c359ee727..483e37426c 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -2027,6 +2027,7 @@ return [ 'resources/src/mediawiki.special/userrights.css', 'resources/src/mediawiki.special/watchlist.css', 'resources/src/mediawiki.special/block.less', + 'resources/src/mediawiki.special/blocklist.less', ], 'targets' => [ 'desktop', 'mobile' ], ], @@ -2043,6 +2044,7 @@ return [ 'oojs-ui.styles.icons-editing-advanced', 'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-moderation', + 'mediawiki.widgets', 'mediawiki.widgets.datetime', 'jquery.makeCollapsible', ], @@ -2128,10 +2130,6 @@ return [ ], 'targets' => [ 'desktop', 'mobile' ], ], - 'mediawiki.special.blocklist' => [ - 'styles' => 'resources/src/mediawiki.special/blocklist.less', - 'targets' => [ 'desktop', 'mobile' ], - ], 'mediawiki.special.changecredentials.js' => [ 'scripts' => 'resources/src/mediawiki.special.changecredentials.js', 'dependencies' => [ @@ -2503,12 +2501,16 @@ return [ 'scripts' => [ 'resources/src/mediawiki.widgets/mw.widgets.NamespaceInputWidget.js', 'resources/src/mediawiki.widgets/mw.widgets.ComplexNamespaceInputWidget.js', + 'resources/src/mediawiki.widgets/mw.widgets.CopyTextLayout.js', 'resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js', 'resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js', 'resources/src/mediawiki.widgets/mw.widgets.TitleSearchWidget.js', 'resources/src/mediawiki.widgets/mw.widgets.ComplexTitleInputWidget.js', 'resources/src/mediawiki.widgets/mw.widgets.TitleOptionWidget.js', ], + 'styles' => [ + 'resources/src/mediawiki.widgets/mw.widgets.CopyTextLayout.css', + ], 'skinStyles' => [ 'default' => [ 'resources/src/mediawiki.widgets/mw.widgets.TitleWidget.less', @@ -2522,11 +2524,17 @@ return [ 'mediawiki.Title', 'mediawiki.api', 'mediawiki.String', + // CopyTextLayout + 'mediawiki.notify', ], 'messages' => [ // NamespaceInputWidget 'blanknamespace', 'namespacesall', + // CopyTextLayout + 'mw-widgets-copytextlayout-copy', + 'mw-widgets-copytextlayout-copy-fail', + 'mw-widgets-copytextlayout-copy-success', // TitleInputWidget 'mw-widgets-titleinput-description-new-page', 'mw-widgets-titleinput-description-redirect', diff --git a/resources/src/jquery/jquery.suggestions.js b/resources/src/jquery/jquery.suggestions.js index a585cf384e..9e6ecc888d 100644 --- a/resources/src/jquery/jquery.suggestions.js +++ b/resources/src/jquery/jquery.suggestions.js @@ -776,7 +776,10 @@ } $.suggestions.hide( context ); $.suggestions.cancel( context ); - } ); + } ) + // Simulate a keypress on load. This loads the search suggestions when there are already + // typed characters before the JavaScript is loaded. + .trigger( 'keypress' ); } // Store the context for next time diff --git a/resources/src/mediawiki.special.apisandbox/apisandbox.js b/resources/src/mediawiki.special.apisandbox/apisandbox.js index e063a394c0..631a5c6ac8 100644 --- a/resources/src/mediawiki.special.apisandbox/apisandbox.js +++ b/resources/src/mediawiki.special.apisandbox/apisandbox.js @@ -724,37 +724,32 @@ * @return {OO.ui.MenuOptionWidget[]} Each item's data should be an OO.ui.FieldLayout */ formatRequest: function ( displayParams, rawParams ) { - var jsonInput, + var jsonLayout, items = [ new OO.ui.MenuOptionWidget( { label: Util.parseMsg( 'apisandbox-request-format-url-label' ), - data: new OO.ui.FieldLayout( - new OO.ui.TextInputWidget( { - readOnly: true, - value: mw.util.wikiScript( 'api' ) + '?' + $.param( displayParams ) - } ), { - label: Util.parseMsg( 'apisandbox-request-url-label' ) - } - ) + data: new mw.widgets.CopyTextLayout( { + label: Util.parseMsg( 'apisandbox-request-url-label' ), + copyText: mw.util.wikiScript( 'api' ) + '?' + $.param( displayParams ) + } ) } ), new OO.ui.MenuOptionWidget( { label: Util.parseMsg( 'apisandbox-request-format-json-label' ), - data: new OO.ui.FieldLayout( - jsonInput = new OO.ui.MultilineTextInputWidget( { + data: jsonLayout = new mw.widgets.CopyTextLayout( { + label: Util.parseMsg( 'apisandbox-request-json-label' ), + copyText: JSON.stringify( displayParams, null, '\t' ), + multiline: true, + textInput: { classes: [ 'mw-apisandbox-textInputCode' ], - readOnly: true, autosize: true, - maxRows: 6, - value: JSON.stringify( displayParams, null, '\t' ) - } ), { - label: Util.parseMsg( 'apisandbox-request-json-label' ) + maxRows: 6 } - ).on( 'toggle', function ( visible ) { + } ).on( 'toggle', function ( visible ) { if ( visible ) { // Call updatePosition instead of adjustSize // because the latter has weird caching // behavior and the former bypasses it. - jsonInput.updatePosition(); + jsonLayout.textInput.updatePosition(); } } ) } ) @@ -1083,12 +1078,11 @@ progressLoading = false; $progressText = $( '' ).text( mw.message( 'apisandbox-sending-request' ).text() ); progress = new OO.ui.ProgressBarWidget( { - progress: false, - $content: $progressText + progress: false } ); $result = $( '
' ) - .append( progress.$element ); + .append( $progressText, progress.$element ); resultPage = page = new OO.ui.PageLayout( '|results|', { expanded: false } ); page.setupOutlineItem = function () { @@ -1781,10 +1775,12 @@ }; this.$element.empty() - .append( new OO.ui.ProgressBarWidget( { - progress: false, - text: mw.message( 'apisandbox-loading', this.displayText ).text() - } ).$element ); + .append( + document.createTextNode( + mw.message( 'apisandbox-loading', this.displayText ).text() + ), + new OO.ui.ProgressBarWidget( { progress: false } ).$element + ); Util.fetchModuleInfo( this.apiModule ) .done( function ( pi ) { diff --git a/resources/src/mediawiki.special.block.js b/resources/src/mediawiki.special.block.js index 58657dbd3e..6d003aa5bc 100644 --- a/resources/src/mediawiki.special.block.js +++ b/resources/src/mediawiki.special.block.js @@ -59,14 +59,17 @@ pageRestrictionsWidget.setDisabled( !editingIsSelected || isSitewide ); namespaceRestrictionsWidget.setDisabled( !editingIsSelected || isSitewide ); if ( blockAllowsUTEdit ) { - // This option is disabled for partial blocks unless a namespace restriction - // for the User_talk namespace is in place. + // Disable for partial blocks, unless the block is against the User_talk namespace preventTalkPageEditWidget.setDisabled( - editingIsSelected && - editingRestrictionValue === 'partial' && - namespaceRestrictionsWidget.getValue().indexOf( - String( mw.config.get( 'wgNamespaceIds' ).user_talk ) - ) === -1 + // Partial block that doesn't block editing + !editingIsSelected || + // Partial block that blocks editing and doesn't block the User_talk namespace + ( + editingRestrictionValue === 'partial' && + namespaceRestrictionsWidget.getValue().indexOf( + String( mw.config.get( 'wgNamespaceIds' ).user_talk ) + ) === -1 + ) ); } } diff --git a/resources/src/mediawiki.widgets/mw.widgets.CopyTextLayout.css b/resources/src/mediawiki.widgets/mw.widgets.CopyTextLayout.css new file mode 100644 index 0000000000..f09128a0f0 --- /dev/null +++ b/resources/src/mediawiki.widgets/mw.widgets.CopyTextLayout.css @@ -0,0 +1,19 @@ +/*! + * MediaWiki Widgets – CopyTextLayout styles. + * + * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt + * @license The MIT License (MIT); see LICENSE.txt + */ + +.mw-widget-copyTextLayout > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field { + /* TODO: This should be upstreamed to OOUI */ + max-width: 50em; +} + +.mw-widget-copyTextLayout-multiline-button { + display: block; + max-width: 50em; + margin-top: 0.5em; + /* Float to right of inline help */ + float: right; +} diff --git a/resources/src/mediawiki.widgets/mw.widgets.CopyTextLayout.js b/resources/src/mediawiki.widgets/mw.widgets.CopyTextLayout.js new file mode 100644 index 0000000000..65e7eb782a --- /dev/null +++ b/resources/src/mediawiki.widgets/mw.widgets.CopyTextLayout.js @@ -0,0 +1,114 @@ +/*! + * MediaWiki Widgets - CopyTextLayout class. + * + * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt + * @license The MIT License (MIT); see LICENSE.txt + */ +( function () { + + /** + * An action field layout containing some readonly text and a button to copy + * it to the clipboard. + * + * @class + * @extends OO.ui.ActionFieldLayout + * + * @constructor + * @param {Object} [config] Configuration options + * @cfg {string} copyText Text to copy, can also be provided as textInput.value + * @cfg {Object} textInput Config for text input + * @cfg {Object} button Config for button + * @cfg {string} successMessage Success message, + * defaults to 'mw-widgets-copytextlayout-copy-success'. + * @cfg {string} failMessage Failure message, + * defaults to 'mw-widgets-copytextlayout-copy-fail'. + */ + mw.widgets.CopyTextLayout = function MwWidgetsCopyTextLayout( config ) { + var TextClass; + config = config || {}; + + // Properties + TextClass = config.multiline ? OO.ui.MultilineTextInputWidget : OO.ui.TextInputWidget; + this.textInput = new TextClass( $.extend( { + value: config.copyText, + readOnly: true + }, config.textInput ) ); + this.button = new OO.ui.ButtonWidget( $.extend( { + label: mw.msg( 'mw-widgets-copytextlayout-copy' ), + icon: 'articles' + }, config.button ) ); + this.successMessage = config.successMessage || mw.msg( 'mw-widgets-copytextlayout-copy-success' ); + this.failMessage = config.failMessage || mw.msg( 'mw-widgets-copytextlayout-copy-fail' ); + + // Parent constructor + mw.widgets.CopyTextLayout.super.call( this, this.textInput, this.button, config ); + + // HACK: Remove classes which connect widgets when using + // a multiline text input. TODO: This should be handled in OOUI. + if ( config.multiline ) { + this.$input.removeClass( 'oo-ui-actionFieldLayout-input' ); + this.$button + .removeClass( 'oo-ui-actionFieldLayout-button' ) + .addClass( 'mw-widget-copyTextLayout-multiline-button' ); + } + + // Events + this.button.connect( this, { click: 'onButtonClick' } ); + this.textInput.$input.on( 'click', this.onInputClick.bind( this ) ); + + this.$element.addClass( 'mw-widget-copyTextLayout' ); + }; + + /* Inheritence */ + + OO.inheritClass( mw.widgets.CopyTextLayout, OO.ui.ActionFieldLayout ); + + /* Methods */ + + /** + * Handle button click events + * + * @fires copy + */ + mw.widgets.CopyTextLayout.prototype.onButtonClick = function () { + var copied; + + this.selectText(); + + try { + copied = document.execCommand( 'copy' ); + } catch ( e ) { + copied = false; + } + if ( copied ) { + mw.notify( this.successMessage ); + } else { + mw.notify( this.failMessage, { type: 'error' } ); + } + + this.emit( 'copy', copied ); + }; + + /** + * Handle button click events + */ + mw.widgets.CopyTextLayout.prototype.onInputClick = function () { + this.selectText(); + }; + + /** + * Select the text to copy + */ + mw.widgets.CopyTextLayout.prototype.selectText = function () { + var input = this.textInput.$input[ 0 ], + scrollTop = input.scrollTop, + scrollLeft = input.scrollLeft; + + this.textInput.select(); + + // Restore scroll position + input.scrollTop = scrollTop; + input.scrollLeft = scrollLeft; + }; + +}() ); diff --git a/tests/phpunit/includes/MovePageTest.php b/tests/phpunit/includes/MovePageTest.php index 1b2b159f0a..db9d2ab8bc 100644 --- a/tests/phpunit/includes/MovePageTest.php +++ b/tests/phpunit/includes/MovePageTest.php @@ -5,6 +5,13 @@ */ class MovePageTest extends MediaWikiTestCase { + public function setUp() { + parent::setUp(); + $this->tablesUsed[] = 'page'; + $this->tablesUsed[] = 'revision'; + $this->tablesUsed[] = 'comment'; + } + /** * @dataProvider provideIsValidMove * @covers MovePage::isValidMove @@ -83,4 +90,108 @@ class MovePageTest extends MediaWikiTestCase { $status = $mp->move( $user, 'Reason', true ); $this->assertTrue( $status->hasMessage( $error ) ); } + + /** + * Test moving subpages from one page to another + * @covers MovePage::moveSubpages + */ + public function testMoveSubpages() { + $name = ucfirst( __FUNCTION__ ); + + $subPages = [ "Talk:$name/1", "Talk:$name/2" ]; + $ids = []; + $pages = [ + $name, + "Talk:$name", + "$name 2", + "Talk:$name 2", + ]; + foreach ( array_merge( $pages, $subPages ) as $page ) { + $ids[$page] = $this->createPage( $page ); + } + + $oldTitle = Title::newFromText( "Talk:$name" ); + $newTitle = Title::newFromText( "Talk:$name 2" ); + $mp = new MovePage( $oldTitle, $newTitle ); + $status = $mp->moveSubpages( $this->getTestUser()->getUser(), 'Reason', true ); + + $this->assertTrue( $status->isGood(), + "Moving subpages from Talk:{$name} to Talk:{$name} 2 was not completely successful." ); + foreach ( $subPages as $page ) { + $this->assertMoved( $page, str_replace( $name, "$name 2", $page ), $ids[$page] ); + } + } + + /** + * Test moving subpages from one page to another + * @covers MovePage::moveSubpagesIfAllowed + */ + public function testMoveSubpagesIfAllowed() { + $name = ucfirst( __FUNCTION__ ); + + $subPages = [ "Talk:$name/1", "Talk:$name/2" ]; + $ids = []; + $pages = [ + $name, + "Talk:$name", + "$name 2", + "Talk:$name 2", + ]; + foreach ( array_merge( $pages, $subPages ) as $page ) { + $ids[$page] = $this->createPage( $page ); + } + + $oldTitle = Title::newFromText( "Talk:$name" ); + $newTitle = Title::newFromText( "Talk:$name 2" ); + $mp = new MovePage( $oldTitle, $newTitle ); + $status = $mp->moveSubpagesIfAllowed( $this->getTestUser()->getUser(), 'Reason', true ); + + $this->assertTrue( $status->isGood(), + "Moving subpages from Talk:{$name} to Talk:{$name} 2 was not completely successful." ); + foreach ( $subPages as $page ) { + $this->assertMoved( $page, str_replace( $name, "$name 2", $page ), $ids[$page] ); + } + } + + /** + * Shortcut function to create a page and return its id. + * + * @param string $name Page to create + * @return int ID of created page + */ + protected function createPage( $name ) { + return $this->editPage( $name, 'Content' )->value['revision']->getPage(); + } + + /** + * @param string $from Prefixed name of source + * @param string $to Prefixed name of destination + * @param string $id Page id of the page to move + * @param array|string|null $opts Options: 'noredirect' to expect no redirect + */ + protected function assertMoved( $from, $to, $id, $opts = null ) { + $opts = (array)$opts; + + Title::clearCaches(); + $fromTitle = Title::newFromText( $from ); + $toTitle = Title::newFromText( $to ); + + $this->assertTrue( $toTitle->exists(), + "Destination {$toTitle->getPrefixedText()} does not exist" ); + + if ( in_array( 'noredirect', $opts ) ) { + $this->assertFalse( $fromTitle->exists(), + "Source {$fromTitle->getPrefixedText()} exists" ); + } else { + $this->assertTrue( $fromTitle->exists(), + "Source {$fromTitle->getPrefixedText()} does not exist" ); + $this->assertTrue( $fromTitle->isRedirect(), + "Source {$fromTitle->getPrefixedText()} is not a redirect" ); + + $target = Revision::newFromTitle( $fromTitle )->getContent()->getRedirectTarget(); + $this->assertSame( $toTitle->getPrefixedText(), $target->getPrefixedText() ); + } + + $this->assertSame( $id, $toTitle->getArticleID() ); + } } diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php index afc6bb582d..ebd9f1d068 100644 --- a/tests/phpunit/includes/OutputPageTest.php +++ b/tests/phpunit/includes/OutputPageTest.php @@ -526,9 +526,9 @@ class OutputPageTest extends MediaWikiTestCase { function ( $op ) { $op->getContext()->setUser( $this->getTestUser()->getUser() ); } ], - 'After Squid expiry' => + 'After CDN expiry' => [ $lastModified, $lastModified, false, - [ 'UseSquid' => true, 'SquidMaxage' => 3599 ] ], + [ 'UseCdn' => true, 'CdnMaxAge' => 3599 ] ], 'Hook allows cache use' => [ $lastModified + 1, $lastModified, true, [], function ( $op, $that ) { @@ -2225,7 +2225,7 @@ class OutputPageTest extends MediaWikiTestCase { } public function provideAdaptCdnTTL() { - global $wgSquidMaxage; + global $wgCdnMaxAge; $now = time(); self::$fakeTime = $now; return [ @@ -2234,7 +2234,7 @@ class OutputPageTest extends MediaWikiTestCase { 'Five minutes from now' => [ [ $now + 300 ], IExpiringStore::TTL_MINUTE ], 'Five minutes ago, initial maxage four minutes' => [ [ $now - 300 ], 270, [ 'initialMaxage' => 240 ] ], - 'A very long time ago' => [ [ $now - 1000000000 ], $wgSquidMaxage ], + 'A very long time ago' => [ [ $now - 1000000000 ], $wgCdnMaxAge ], 'Initial maxage zero' => [ [ $now - 300 ], 270, [ 'initialMaxage' => 0 ] ], 'false' => [ [ false ], IExpiringStore::TTL_MINUTE ], diff --git a/tests/phpunit/includes/WebRequestTest.php b/tests/phpunit/includes/WebRequestTest.php index cda56603f9..0d5c59b0de 100644 --- a/tests/phpunit/includes/WebRequestTest.php +++ b/tests/phpunit/includes/WebRequestTest.php @@ -391,7 +391,7 @@ class WebRequestTest extends MediaWikiTestCase { * @dataProvider provideGetIP * @covers WebRequest::getIP */ - public function testGetIP( $expected, $input, $squid, $xffList, $private, $description ) { + public function testGetIP( $expected, $input, $cdn, $xffList, $private, $description ) { $this->setServerVars( $input ); $this->setMwGlobals( [ 'wgUsePrivateIPs' => $private, @@ -405,7 +405,7 @@ class WebRequestTest extends MediaWikiTestCase { ] ] ); - $this->setService( 'ProxyLookup', new ProxyLookup( [], $squid ) ); + $this->setService( 'ProxyLookup', new ProxyLookup( [], $cdn ) ); $request = new WebRequest(); $result = $request->getIP(); @@ -587,8 +587,8 @@ class WebRequestTest extends MediaWikiTestCase { public function testGetIpLackOfRemoteAddrThrowAnException() { // ensure that local install state doesn't interfere with test $this->setMwGlobals( [ - 'wgSquidServersNoPurge' => [], - 'wgSquidServers' => [], + 'wgCdnServers' => [], + 'wgCdnServersNoPurge' => [], 'wgUsePrivateIPs' => false, 'wgHooks' => [], ] ); diff --git a/tests/phpunit/includes/api/ApiMainTest.php b/tests/phpunit/includes/api/ApiMainTest.php index 9cb84e23bc..a5518a1252 100644 --- a/tests/phpunit/includes/api/ApiMainTest.php +++ b/tests/phpunit/includes/api/ApiMainTest.php @@ -490,7 +490,7 @@ class ApiMainTest extends ApiTestCase { * @param int $status Expected response status * @param array $options Array of options: * post => true Request is a POST - * cdn => true CDN is enabled ($wgUseSquid) + * cdn => true CDN is enabled ($wgUseCdn) */ public function testCheckConditionalRequestHeaders( $headers, $conditions, $status, $options = [] @@ -508,7 +508,7 @@ class ApiMainTest extends ApiTestCase { $priv->mInternalMode = false; if ( !empty( $options['cdn'] ) ) { - $this->setMwGlobals( 'wgUseSquid', true ); + $this->setMwGlobals( 'wgUseCdn', true ); } // Can't do this in TestSetup.php because Setup.php will override it @@ -531,7 +531,7 @@ class ApiMainTest extends ApiTestCase { } public static function provideCheckConditionalRequestHeaders() { - global $wgSquidMaxage; + global $wgCdnMaxAge; $now = time(); return [ @@ -614,15 +614,15 @@ class ApiMainTest extends ApiTestCase { [ [ 'If-Modified-Since' => 'a potato' ], [ 'last-modified' => wfTimestamp( TS_MW, $now - 1 ) ], 200 ], - // Anything before $wgSquidMaxage seconds ago should be considered + // Anything before $wgCdnMaxAge seconds ago should be considered // expired. 'If-Modified-Since with CDN post-expiry' => - [ [ 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now - $wgSquidMaxage * 2 ) ], - [ 'last-modified' => wfTimestamp( TS_MW, $now - $wgSquidMaxage * 3 ) ], + [ [ 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now - $wgCdnMaxAge * 2 ) ], + [ 'last-modified' => wfTimestamp( TS_MW, $now - $wgCdnMaxAge * 3 ) ], 200, [ 'cdn' => true ] ], 'If-Modified-Since with CDN pre-expiry' => - [ [ 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now - $wgSquidMaxage / 2 ) ], - [ 'last-modified' => wfTimestamp( TS_MW, $now - $wgSquidMaxage * 3 ) ], + [ [ 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now - $wgCdnMaxAge / 2 ) ], + [ 'last-modified' => wfTimestamp( TS_MW, $now - $wgCdnMaxAge * 3 ) ], 304, [ 'cdn' => true ] ], ]; } diff --git a/tests/phpunit/includes/debug/logger/LegacyLoggerTest.php b/tests/phpunit/includes/debug/logger/LegacyLoggerTest.php index 37a28c36ca..6c2fddaebf 100644 --- a/tests/phpunit/includes/debug/logger/LegacyLoggerTest.php +++ b/tests/phpunit/includes/debug/logger/LegacyLoggerTest.php @@ -124,6 +124,26 @@ class LegacyLoggerTest extends MediaWikiTestCase { ]; } + /** + * @covers MediaWiki\Logger\LegacyLogger::interpolate + */ + public function testInterpolate_Error() { + // @todo Merge this into provideInterpolate once we drop HHVM support + if ( !class_exists( \Error::class ) ) { + $this->markTestSkipped( 'Error class does not exist' ); + } + + $err = new \Error( 'Test error' ); + $message = '{exception}'; + $context = [ 'exception' => $err ]; + $expect = '[Error ' . get_class( $err ) . '( ' . + $err->getFile() . ':' . $err->getLine() . ') ' . + $err->getMessage() . ']'; + + $this->assertEquals( + $expect, LegacyLogger::interpolate( $message, $context ) ); + } + /** * @covers MediaWiki\Logger\LegacyLogger::shouldEmit * @dataProvider provideShouldEmit diff --git a/tests/phpunit/includes/debug/logger/monolog/LineFormatterTest.php b/tests/phpunit/includes/debug/logger/monolog/LineFormatterTest.php index 2768d32939..bdd5c81118 100644 --- a/tests/phpunit/includes/debug/logger/monolog/LineFormatterTest.php +++ b/tests/phpunit/includes/debug/logger/monolog/LineFormatterTest.php @@ -20,6 +20,7 @@ namespace MediaWiki\Logger\Monolog; +use AssertionError; use InvalidArgumentException; use LengthException; use LogicException; @@ -72,4 +73,50 @@ class LineFormatterTest extends MediaWikiTestCase { $this->assertContains( "\nCaused by: [Exception LogicException]", $out ); $this->assertContains( "\n #0", $out ); } + + /** + * @covers MediaWiki\Logger\Monolog\LineFormatter::normalizeException + */ + public function testNormalizeExceptionErrorNoTrace() { + if ( !class_exists( AssertionError::class ) ) { + $this->markTestSkipped( 'AssertionError class does not exist' ); + } + + $fixture = new LineFormatter(); + $fixture->includeStacktraces( false ); + $fixture = TestingAccessWrapper::newFromObject( $fixture ); + $boom = new InvalidArgumentException( 'boom', 0, + new LengthException( 'too long', 0, + new AssertionError( 'Spock wuz here' ) + ) + ); + $out = $fixture->normalizeException( $boom ); + $this->assertContains( "\n[Exception InvalidArgumentException]", $out ); + $this->assertContains( "\nCaused by: [Exception LengthException]", $out ); + $this->assertContains( "\nCaused by: [Error AssertionError]", $out ); + $this->assertNotContains( "\n #0", $out ); + } + + /** + * @covers MediaWiki\Logger\Monolog\LineFormatter::normalizeException + */ + public function testNormalizeExceptionErrorTrace() { + if ( !class_exists( AssertionError::class ) ) { + $this->markTestSkipped( 'AssertionError class does not exist' ); + } + + $fixture = new LineFormatter(); + $fixture->includeStacktraces( true ); + $fixture = TestingAccessWrapper::newFromObject( $fixture ); + $boom = new InvalidArgumentException( 'boom', 0, + new LengthException( 'too long', 0, + new AssertionError( 'Spock wuz here' ) + ) + ); + $out = $fixture->normalizeException( $boom ); + $this->assertContains( "\n[Exception InvalidArgumentException]", $out ); + $this->assertContains( "\nCaused by: [Exception LengthException]", $out ); + $this->assertContains( "\nCaused by: [Error AssertionError]", $out ); + $this->assertContains( "\n #0", $out ); + } } diff --git a/thumb.php b/thumb.php index 70329093c6..43dd5d472f 100644 --- a/thumb.php +++ b/thumb.php @@ -272,7 +272,7 @@ function wfStreamThumb( array $params ) { // For 404 handled thumbnails, we only use the base name of the URI // for the thumb params and the parent directory for the source file name. - // Check that the zone relative path matches up so squid caches won't pick + // Check that the zone relative path matches up so CDN caches won't pick // up thumbs that would not be purged on source file deletion (T36231). if ( $rel404 !== null ) { // thumbnail was handled via 404 if ( rawurldecode( $rel404 ) === $img->getThumbRel( $thumbName ) ) {