* Added: kbp (Kabɩyɛ / Kabiyè)
* Added: skr (Saraiki, سرائیکی)
* Added: tay (Tayal / Atayal)
+* Removed: tokipona (Toki Pona)
==== Pig Latin added ====
* (T45547) Added Pig Latin, a made-up English variant (en-x-piglatin),
essential.
* $wgUsejQueryThree was removed, as it is now the default. This was documented as a
temporary variable during the migration period, deprecated since 1.29.
+* $wgLogoHD has been updated to support svg images and uses $wgLogo where
+ possible for fallback images such as png.
* …
=== New features in 1.31 ===
* The OutputPage class constructor now requires a context parameter,
(instantiating without context was deprecated in 1.18)
* mw.page (deprecated in 1.30) was removed.
+* Article::getLastPurgeTimestamp(), WikiPage::getLastPurgeTimestamp(), and the
+ related WikiPage::PURGE_* constants, deprecated in 1.29, were removed.
== Compatibility ==
MediaWiki 1.31 requires PHP 5.5.9 or later. There is experimental support for
// than getting the msg raw and explode()'ing it.
$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
$lines = $cache->getWithSetCallback(
- $cache->makeKey( 'ipb', 'autoblock', 'whitelist' ),
+ $cache->makeKey( 'ip-autoblock', 'whitelist' ),
$cache::TTL_DAY,
function ( $curValue, &$ttl, array &$setOpts ) {
$setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
* ];
* @endcode
*
+ * SVG is also supported but when enabled, it
+ * disables 1.5x and 2x as svg will already
+ * be optimised for screen resolution.
+ *
+ * @par Example:
+ * @code
+ * $wgLogoHD = [
+ * "svg" => "path/to/svg_version.svg",
+ * ];
+ * @endcode
+ *
* @since 1.25
*/
$wgLogoHD = false;
# Render error page if no LocalSettings file can be found
try {
+ global $wgVersion;
echo $templateParser->processTemplate(
'NoLocalSettings',
[
return;
}
+ if ( isset( $logo['svg'] ) ) {
+ // No media queries required if we only have a 1x and svg variant
+ // because all preload-capable browsers support SVGs
+ $this->addLinkHeader( '<' . $logo['svg'] . '>;rel=preload;as=image' );
+ return;
+ }
+
foreach ( $logo as $dppx => $src ) {
// Keys are in this format: "1.5x"
$dppx = substr( $dppx, 0, -1 );
+++ /dev/null
-<?php
-/**
- * File-scope setup actions, loaded before LocalSettings.php, shared by
- * WebStart.php and doMaintenance.php
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- *
- * @file
- */
-
-if ( !defined( 'MEDIAWIKI' ) ) {
- // Not an entry point
- exit( 1 );
-}
-
-// Grab profiling functions
-require_once "$IP/includes/profiler/ProfilerFunctions.php";
-
-// Start the autoloader, so that extensions can derive classes from core files
-require_once "$IP/includes/AutoLoader.php";
-
-// Load up some global defines.
-require_once "$IP/includes/Defines.php";
-
-// Start the profiler
-$wgProfiler = [];
-if ( file_exists( "$IP/StartProfiler.php" ) ) {
- require "$IP/StartProfiler.php";
-}
-
-// Load default settings
-require_once "$IP/includes/DefaultSettings.php";
-
-// Load global functions
-require_once "$IP/includes/GlobalFunctions.php";
-
-// Load composer's autoloader if present
-if ( is_readable( "$IP/vendor/autoload.php" ) ) {
- require_once "$IP/vendor/autoload.php";
-}
exit( 1 );
}
+/**
+ * Pre-config setup: Before loading LocalSettings.php
+ */
+
+// Grab profiling functions
+require_once "$IP/includes/profiler/ProfilerFunctions.php";
+
+// Start the autoloader, so that extensions can derive classes from core files
+require_once "$IP/includes/AutoLoader.php";
+
+// Load up some global defines
+require_once "$IP/includes/Defines.php";
+
+// Start the profiler
+$wgProfiler = [];
+if ( file_exists( "$IP/StartProfiler.php" ) ) {
+ require "$IP/StartProfiler.php";
+}
+
+// Load default settings
+require_once "$IP/includes/DefaultSettings.php";
+
+// Load global functions
+require_once "$IP/includes/GlobalFunctions.php";
+
+// Load composer's autoloader if present
+if ( is_readable( "$IP/vendor/autoload.php" ) ) {
+ require_once "$IP/vendor/autoload.php";
+}
+
+// Assert that composer dependencies were successfully loaded
+// Purposely no leading \ due to it breaking HHVM RepoAuthorative mode
+// PHP works fine with both versions
+// See https://github.com/facebook/hhvm/issues/5833
+if ( !interface_exists( 'Psr\Log\LoggerInterface' ) ) {
+ $message = (
+ 'MediaWiki requires the <a href="https://github.com/php-fig/log">PSR-3 logging ' .
+ "library</a> to be present. This library is not embedded directly in MediaWiki's " .
+ "git repository and must be installed separately by the end user.\n\n" .
+ 'Please see <a href="https://www.mediawiki.org/wiki/Download_from_Git' .
+ '#Fetch_external_libraries">mediawiki.org</a> for help on installing ' .
+ 'the required components.'
+ );
+ echo $message;
+ trigger_error( $message, E_USER_ERROR );
+ die( 1 );
+}
+
+// Install a header callback
+MediaWiki\HeaderCallback::register();
+
+/**
+ * Load LocalSettings.php
+ */
+
+if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
+ call_user_func( MW_CONFIG_CALLBACK );
+} else {
+ if ( !defined( 'MW_CONFIG_FILE' ) ) {
+ define( 'MW_CONFIG_FILE', "$IP/LocalSettings.php" );
+ }
+ require_once MW_CONFIG_FILE;
+}
+
+/**
+ * Customization point after all loading (constants, functions, classes,
+ * DefaultSettings, LocalSettings). Specifically, this is before usage of
+ * settings, before instantiation of Profiler (and other singletons), and
+ * before any setup functions or hooks run.
+ */
+
+if ( defined( 'MW_SETUP_CALLBACK' ) ) {
+ call_user_func( MW_SETUP_CALLBACK );
+}
+
+/**
+ * Main setup
+ */
+
$fname = 'Setup.php';
$ps_setup = Profiler::instance()->scopedProfileIn( $fname );
$IP = realpath( '.' ) ?: dirname( __DIR__ );
}
-require_once "$IP/includes/PreConfigSetup.php";
-
-# Assert that composer dependencies were successfully loaded
-# Purposely no leading \ due to it breaking HHVM RepoAuthorative mode
-# PHP works fine with both versions
-# See https://github.com/facebook/hhvm/issues/5833
-if ( !interface_exists( 'Psr\Log\LoggerInterface' ) ) {
- $message = (
- 'MediaWiki requires the <a href="https://github.com/php-fig/log">PSR-3 logging ' .
- "library</a> to be present. This library is not embedded directly in MediaWiki's " .
- "git repository and must be installed separately by the end user.\n\n" .
- 'Please see <a href="https://www.mediawiki.org/wiki/Download_from_Git' .
- '#Fetch_external_libraries">mediawiki.org</a> for help on installing ' .
- 'the required components.'
- );
- echo $message;
- trigger_error( $message, E_USER_ERROR );
- die( 1 );
-}
-
-# Install a header callback
-MediaWiki\HeaderCallback::register();
-
-if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
- # Use a callback function to configure MediaWiki
- call_user_func( MW_CONFIG_CALLBACK );
-} else {
+// If no LocalSettings file exists, try to display an error page
+// (use a callback because it depends on TemplateParser)
+if ( !defined( 'MW_CONFIG_CALLBACK' ) ) {
if ( !defined( 'MW_CONFIG_FILE' ) ) {
define( 'MW_CONFIG_FILE', "$IP/LocalSettings.php" );
}
-
- # LocalSettings.php is the per site customization file. If it does not exist
- # the wiki installer needs to be launched or the generated file uploaded to
- # the root wiki directory. Give a hint, if it is not readable by the server.
if ( !is_readable( MW_CONFIG_FILE ) ) {
- require_once "$IP/includes/NoLocalSettings.php";
- die();
+ function wfWebStartNoLocalSettings() {
+ # LocalSettings.php is the per-site customization file. If it does not exist
+ # the wiki installer needs to be launched or the generated file uploaded to
+ # the root wiki directory. Give a hint, if it is not readable by the server.
+ global $IP;
+ require_once "$IP/includes/NoLocalSettings.php";
+ die();
+ }
+ define( 'MW_CONFIG_CALLBACK', 'wfWebStartNoLocalSettings' );
}
-
- # Include site settings. $IP may be changed (hopefully before the AutoLoader is invoked)
- require_once MW_CONFIG_FILE;
}
-# Initialise output buffering
-# Check that there is no previous output or previously set up buffers, because
-# that would cause us to potentially mix gzip and non-gzip output, creating a
-# big mess.
-if ( ob_get_level() == 0 ) {
- require_once "$IP/includes/OutputHandler.php";
- ob_start( 'wfOutputHandler' );
+// Custom setup for WebStart entry point
+if ( !defined( 'MW_SETUP_CALLBACK' ) ) {
+ function wfWebStartSetup() {
+ # Initialise output buffering
+ # Check that there is no previous output or previously set up buffers, because
+ # that would cause us to potentially mix gzip and non-gzip output, creating a
+ # big mess.
+ global $IP;
+ if ( ob_get_level() == 0 ) {
+ require_once "$IP/includes/OutputHandler.php";
+ ob_start( 'wfOutputHandler' );
+ }
+ }
+ define( 'MW_SETUP_CALLBACK', 'wfWebStartSetup' );
}
require_once "$IP/includes/Setup.php";
$context->setOutput( $outputPage );
if ( $skin ) {
+ // Based on OutputPage::headElement()
+ $skin->setupSkinUserCss( $outputPage );
// Based on OutputPage::output()
foreach ( $skin->getDefaultModules() as $group ) {
$outputPage->addModules( $group );
$updates = $content->getSecondaryDataUpdates(
$title, null, $forceRecursiveLinkUpdate, $p_result );
foreach ( $updates as $update ) {
+ $update->setCause( 'api-purge', $this->getUser()->getName() );
DeferredUpdates::addUpdate( $update, DeferredUpdates::PRESEND );
}
abstract class DataUpdate implements DeferrableUpdate {
/** @var mixed Result from LBFactory::getEmptyTransactionTicket() */
protected $ticket;
+ /** @var string Short update cause action description */
+ protected $causeAction = 'unknown';
+ /** @var string Short update cause user description */
+ protected $causeAgent = 'unknown';
public function __construct() {
// noop
$this->ticket = $ticket;
}
+ /**
+ * @param string $action Action type
+ * @param string $user User name
+ */
+ public function setCause( $action, $user ) {
+ $this->causeAction = $action;
+ $this->causeAgent = $user;
+ }
+
+ /**
+ * @return string
+ */
+ public function getCauseAction() {
+ return $this->causeAction;
+ }
+
+ /**
+ * @return string
+ */
+ public function getCauseAgent() {
+ return $this->causeAgent;
+ }
+
/**
* Convenience method, calls doUpdate() on every DataUpdate in the array.
*
* using the job queue.
*/
protected function queueRecursiveJobs() {
- self::queueRecursiveJobsForTable( $this->mTitle, 'templatelinks' );
+ $action = $this->getCauseAction();
+ $agent = $this->getCauseAgent();
+
+ self::queueRecursiveJobsForTable( $this->mTitle, 'templatelinks', $action, $agent );
if ( $this->mTitle->getNamespace() == NS_FILE ) {
// Process imagelinks in case the title is or was a redirect
- self::queueRecursiveJobsForTable( $this->mTitle, 'imagelinks' );
+ self::queueRecursiveJobsForTable( $this->mTitle, 'imagelinks', $action, $agent );
}
$bc = $this->mTitle->getBacklinkCache();
// Which ever runs first generally no-ops the other one.
$jobs = [];
foreach ( $bc->getCascadeProtectedLinks() as $title ) {
- $jobs[] = RefreshLinksJob::newPrioritized( $title, [] );
+ $jobs[] = RefreshLinksJob::newPrioritized(
+ $title,
+ [
+ 'causeAction' => $action,
+ 'causeAgent' => $agent
+ ]
+ );
}
JobQueueGroup::singleton()->push( $jobs );
}
*
* @param Title $title Title to do job for
* @param string $table Table to use (e.g. 'templatelinks')
+ * @param string $action Triggering action
+ * @param string $userName Triggering user name
*/
- public static function queueRecursiveJobsForTable( Title $title, $table ) {
+ public static function queueRecursiveJobsForTable(
+ Title $title, $table, $action = 'unknown', $userName = 'unknown'
+ ) {
if ( $title->getBacklinkCache()->hasLinks( $table ) ) {
$job = new RefreshLinksJob(
$title,
'recursive' => true,
] + Job::newRootJobParams( // "overall" refresh links job info
"refreshlinks:{$table}:{$title->getPrefixedText()}"
- )
+ ) + [ 'causeAction' => $action, 'causeAgent' => $userName ]
);
JobQueueGroup::singleton()->push( $job );
'useRecursiveLinksUpdate' => $this->mRecursive,
'triggeringUser' => $userInfo,
'triggeringRevisionId' => $triggeringRevisionId,
+ 'causeAction' => $this->getCauseAction(),
+ 'causeAgent' => $this->getCauseAgent()
],
[ 'removeDuplicates' => true ],
$this->getTitle()
);
} else {
# Update backlink pages pointing to this title if created
- LinksUpdate::queueRecursiveJobsForTable( $this->getTitle(), 'imagelinks' );
+ LinksUpdate::queueRecursiveJobsForTable(
+ $this->getTitle(),
+ 'imagelinks',
+ 'upload-image',
+ $user->getName()
+ );
}
$this->prerenderThumbnails();
"config-localsettings-badkey": "Sartu duzun eguneratze-gakoa ez da zuzena.",
"config-upgrade-key-missing": "Detektatu egin da dagoeneko MediaWiki instalatu dagoela.\n\nInstalazio hau gaurkotzeko, jarri hurrengo lerroa behekoaldean <code> LocalSettings.php </code>\n\n$1",
"config-localsettings-incomplete": "Existitzen den <code>LocalSettings.php</code> bukatu gabe dagoela ematen du.\n$1 aldagaia ez dago finkatuta.\nMesedez, aldatu <code>LocalSettings.php</code>, aldagaia aldatzeko eta gero klikatu {{int:Config-continue}}\".",
- "config-localsettings-connection-error": "Arazo bat sortu da datu-basearekin konektatzen <code>LocalSettings.php</code>-ean zehaztutako ezarpenak erabilita. Mesedez konpondu ezarpen hauek eta berriro saiatu.",
+ "config-localsettings-connection-error": "Arazo bat sortu da datu-basearekin konektatzen <code>LocalSettings.php</code>-ean zehaztutako ezarpenak erabilita. Mesedez konpondu ezarpen hauek eta berriro saiatu.\n\n$1",
"config-session-error": "Saio hasierako errorea: $1",
"config-session-expired": "Saioren informazio galdu egin dela ematen du.\nSaioak konfiguratutak daude $1 -eko iraupenerako.\nHau handitu ahal duzu <code>code>session.gc_maxlifetime</code> jartzen php.ini -n.\n\nBerrabiatu instalazio prozesua.",
"config-no-session": "Saioren informazio galdu egin da!\nEgiaztatu zure php.ini eta ziurtatu <code>session.save_path</code> egoki zaion direktorioan kokatu dagoela.",
"config-diff3-bad": "GNU diff3 ez da aurkitu.",
"config-git": "Git bertsio-kontrol software aurkitu da: <code>$1</code>",
"config-git-bad": "Git bertsio-kontrol software ez da aurkitu.",
+ "config-imagemagick": "ImageMagick aurkitu da: <code>$1</code>.\nIrudi koadro txikiak gaitu egingo dira igoerak gaitzen badituzu.",
+ "config-gd": "Liburutegiko GD grafiko integratua aurkitu da.\nIrudi koadro txikiak gaitu egingo dira igoerak gaitzen badituzu.",
+ "config-no-scaling": "Ezin izan da GD liburutegia edo ImageMagick aurkitu.\nIrudiaren miniatura desgaitu egingo da.",
"config-no-uri": "<strong>Errore:</strong> Ezin izan da zehaztu URI. Instalazio geldiarazi egin da.",
"config-no-cli-uri": "<strong>Oharra</strong>. Ez da zehaztu <code>--scriptpath</code>, erabiltzen estandar <code>$1</code> .",
"config-using-server": "\"<nowiki>$1</nowiki>\" zerbitzari-izena erabiltzen.",
"config-brokenlibxml": "Zure sistemak dauka PHP-ko eta libxml2-ko konbinazio akastun bat eta eragin ahal du korrupzioa datarekin MediaWikin eta beste web aplikazioetan.\nAktualizatu libxml2 2.7.3-era edo berrietara ([https://bugs.php.net/bug.php?id=45996 bug filed with PHP]).\nInstalazioa geldiarazi egin da.",
"config-db-type": "Datu-base mota:",
"config-db-host": "Datu-basearen zerbitzaria:",
+ "config-db-host-help": "Zure datu-basearen zerbitzaria beste zerbitzari batean badago, sartu ostalariaren izena edo IP helbidea hemen.\n\nPartekatutako web-ostatua erabiltzen ari bazara, zure ostalaritza-hornitzaileak dokumentazio-ostalariaren izen egokia eman beharko lizuke.\n\nWindows zerbitzari batean instalatzen bazara eta MySQL erabiliz, \"localhost\" agian ez du zerbitzariaren izenerako funtzionatuko. Ez badago, saiatu \"127.0.0.1\" tokiko IP helbideetarako.\n\nPostgreSQL erabiltzen ari bazara, utzi eremu hau hutsik Unix socket bidez konektatzeko.",
"config-db-host-oracle": "Datu-baseko TNS:",
"config-db-wiki-settings": "Wiki hau identifikatu",
"config-db-name": "Datu-base izena:",
"config-db-name-help": "Aukeratu zure Wikia identifikatzen duen izena.\nEzin dira espazioak eabili.\n\nErabiltzen ari bazara web hosting partekatua, hostin-eko hornitzaileak emango dizu datu-basearen izen espezifikoa edo kontrol panel baten bitzrtez zure datu-basea sortzea utziko dizu.",
"config-db-name-oracle": "Datu-baseko eskema:",
+ "config-db-account-oracle-warn": "Hiru euskarri onartzen dira Oracle datu-basearen euskarri gisa instalatzeko:\n\nInstalazio-prozesuaren zati gisa datu-basearen kontua sortu nahi baduzu, hornitu kontu bat SYSDBA rol datu-baseko kontu gisa instalatzeko eta webgunerako sarbide konturako nahi dituzun kredentzialak zehazteko; bestela, web-sarbideen kontua eskuz sortu eta hornitu kontu hori bakarrik (eskemaren objektuak sortzeko baimenak behar baditu) edo bi kontu ezberdin, bi pribilegio sortu eta sarbide mugatua eskaintzen dutenak.\n\nBeharrezko baimenak dituen kontu bat sortzeko gidoia instalazio honen \"mantentze/orakulu/\" direktorioan aurki daiteke. Kontuan izan kontu mugatu bat erabiliz kontu lehenetsiarekin mantentze-gaitasun guztiak desgaituko dituela.",
"config-db-install-account": "Instalazio prozesuan erabili erabiltzaile kontua.",
"config-db-username": "Datu-base lankide izena:",
"config-db-password": "Datu-base pasahitza:",
"config-db-schema-help": "Patroi hau normalean egokia da. Bakarrik aldatu beharrezkoa bada.",
"config-pg-test-error": "Ezin da datu-basearekin konektatu <strong>$1</strong>: $2",
"config-sqlite-dir": "SQLite -eko informazioaren direktorioa:",
+ "config-oracle-def-ts": "Taula-toki lehenetsia:",
"config-oracle-temp-ts": "Aldi baterako taula:",
"config-type-mysql": "MySQL (edo bateragarria)",
"config-type-postgres": "PostgreSQL",
"config-type-oracle": "Oracle",
"config-type-mssql": "Microsoft SQL Server",
"config-support-info": "MediaWiki-k onartzen du hurrengo datu-base sistemak:\n\n$1\n\nListan ez baduzu ikusten erabili nahi duzun sistema, jarraitu goiko argibideak aktibatzeko.",
+ "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] MediaWikiren lehenengoko helburua da eta primeran babesturik dago. MediaWikik ere [{{int:version-db-mariadb-url}} MariaDB]-rekin egiten du lan baita [{{int:version-db-percona-url}} Percona Server]-kin, MySQL-rekin balio dutenak. ([http://www.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL support])",
+ "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] iturburu irekiko datu basea sistema famatua da MySQL-rako alternatiba bezala. ([http://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
+ "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] oso ondo onartzen duen datu-basearen sistema arina da.\n ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
+ "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] enpresa komertzial baten datu-basea da. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
+ "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] Windows-entzako enpresa komertzial baten datu-basea da. ([http://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
"config-header-mysql": "MySQL hobespenak",
"config-header-postgres": "PostgreSQL hobespenak",
"config-header-sqlite": "SQLite hobespenak",
"config-missing-db-name": "\"{{int:config-db-name}}\"-rentzako balioa sartu behar duzu.",
"config-missing-db-host": "\"{{int:config-db-host}}\"-rentzako balioa sartu behar duzu.",
"config-missing-db-server-oracle": "\"{{int:config-db-host-oracle}}\"-rentzako balioa sartu behar duzu.",
+ "config-invalid-db-server-oracle": "\"$1\" TNS datu basea baliogabea.\nErabili \"TNS izena\" edo \"Konektagarritasun erraza\" katea ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Oracle Naming Methods]).",
"config-connection-error": "$1\n\nHost-a, erabiltzaile izena eta pasahitza egiaztatu eta saiatu berriro.",
"config-db-sys-create-oracle": "Instalatzaileak bakarrik jasaten du SYSBDA kontu bat erabiltzaile kontu berri bat sortzeko.",
"config-db-sys-user-exists-oracle": "$1 erabiltzaile kontua dagoeneko existitzen da. SYSDBA kontu berri bat sortzeko erabili daiteke soilik!",
"config-sqlite-connection-error": "$1.\n\nDatu direktorioa eta datu-basea egiaztatu eta berriro saiatu.",
"config-sqlite-readonly": "Ezin da idatzi <code>$1</code> fitxategian.",
"config-sqlite-cant-create-db": "Ezin izan da <code>$1</code> datu-basearen artxiboa sortu.",
+ "config-sqlite-fts3-downgrade": "PHPn FTS3 laguntza falta da, taulen gradua jeisten.",
+ "config-can-upgrade": "Datu base honetan MediaWiki taulak daude.\nMediaWiki $1ra graduz igotzeko, <strong>Jarraitu</strong> klikatu.",
"config-upgrade-done-no-regenerate": "Eguneratze prozesua amaitu egin da.\n\nHasi ahal zara [ $1 wikia arabiltzen]",
"config-regenerate": "Birsortu LocalSettings.php →",
"config-show-table-status": "<code>SHOW TABLE STATUS</code> kontsulta huts egin du!",
"config-mysql-engine": "Biltegiratze motorea:",
"config-mysql-innodb": "InnoDB",
"config-mysql-myisam": "MyISAM",
+ "config-mysql-myisam-dep": "<strong>Oharra:</strong> MyISAM MySQL biltegiratze-motor gisa aukeratu duzu, MediaWikirekin erabiltzeko gomendagarria ez dena honengatik:\n*taula blokeoak direla-eta gauza gutxi onartu ohi du\n*beste motore batzuek baino ustelkeria gehiago izateko aukerak ditu\n*MediaWiki-ren kode baseak ez du beti kudeatzen MyISAM behar bezala\n\nZure MySQL instalazioa InnoDB onartzen badu, hori aukeratzeko gomendatzen da.\nZure MySQL instalazioa InnoDB ez badu onartzen, baliteke bertsioa berritzeko ordua izatea.",
+ "config-mysql-only-myisam-dep": "<strong> Oharra: </strong> MyISAM makinaren MySQL biltegiratze motarako bakarra da, eta hau ez da MediaWiki-rekin erabiltzeko gomendatzen, honengatik:\n* maiztasunez taula blokeoek konkurrentzia ez dute onartzen \n* Beste motore batzuek baino ustelkeria gehiago izaten dute\n* MediaWiki-ren kodekak ez du beti kudeatzen MyISAM behar bezala\n\nZure MySQL instalazioak ez du InnoDB onartzen, agian bertsio berritzeko ordua da.",
"config-mysql-binary": "Bitarra",
"config-mysql-utf8": "UTF-8",
"config-mssql-auth": "Autentifikazio mota:",
"config-no-cli-uploads-check": "'''Attention:''' Le directorio predefinite pro files incargate (<code>$1</code>) non es verificate contra le vulnerabilitate\nal execution arbitrari de scripts durante le installation de CLI.",
"config-brokenlibxml": "Vostre systema ha un combination de versiones de PHP e libxml2 que es defectuose e pote causar corruption celate de datos in MediaWiki e altere applicationes web.\nActualisa a libxml2 2.7.3 o plus recente ([https://bugs.php.net/bug.php?id=45996 problema reportate presso PHP]).\nInstallation abortate.",
"config-suhosin-max-value-length": "Suhosin es installate e limita parametro <code>length</code> de GET a $1 bytes.\nLe componente ResourceLoader de MediaWiki va contornar iste limite, ma isto prejudicara le rendimento.\nSi possibile, tu deberea mitter <code>suhosin.get.max_value_length</code> a 1024 o superior in <code>php.ini</code>, e mitter <code>$wgResourceLoaderMaxQueryLength</code> al mesme valor in <code>LocalSettings.php</code>.",
+ "config-using-32bit": "<strong>Attention:</strong> tu systema pare operar con integres de 32 bits. Isto [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit non es recommendate].",
"config-db-type": "Typo de base de datos:",
"config-db-host": "Servitor de base de datos:",
"config-db-host-help": "Si tu servitor de base de datos es in un altere servitor, entra hic le nomine o adresse IP del servitor.\n\nSi tu usa un servitor web usate in commun, tu providitor deberea dar te le correcte nomine de servitor in su documentation.\n\nSi tu face le installation in un servitor Windows e usa MySQL, le nomine \"localhost\" possibilemente non functiona como nomine de servitor. In tal caso, essaya \"127.0.0.1\", i.e. le adresse IP local.\n\nSi tu usa PostgreSQL, lassa iste campo vacue pro connecter via un \"socket\" de Unix.",
"config-help-tooltip": "clicca pro displicar",
"config-nofile": "Le file \"$1\" non poteva esser trovate. Ha illo essite delite?",
"config-extension-link": "Sapeva tu que tu wiki supporta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensiones]?\n\nTu pote explorar le [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensiones per category] o le [https://www.mediawiki.org/wiki/Extension_Matrix matrice de extensiones] pro vider le lista complete de extensiones.",
+ "config-skins-screenshots": "$1 (capturas de schermo: $2)",
+ "config-screenshot": "captura de schermo",
"mainpagetext": "<strong>MediaWiki ha essite installate.</strong>",
"mainpagedocfooter": "Consulta le [https://meta.wikimedia.org/wiki/Help:Contents Guida del usator] pro information sur le uso del software wiki.\n\n== Pro initiar ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista de configurationes]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ FAQ a proposito de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de diffusion pro annuncios de nove versiones de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Traducer MediaWiki in tu lingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Como combatter le spam in tu wiki]"
}
+++ /dev/null
-{
- "@metadata": {
- "authors": [
- "Robin0van0der0vliet"
- ]
- },
- "config-page-language": "toki"
-}
// Multiple pages per job make matches unlikely
!( isset( $params['pages'] ) && count( $params['pages'] ) != 1 )
);
+ $this->params += [ 'causeAction' => 'unknown', 'causeAgent' => 'unknown' ];
}
/**
// Carry over information for de-duplication
$extraParams = $this->getRootJobParams();
$extraParams['triggeredRecursive'] = true;
+ // Carry over cause information for logging
+ $extraParams['causeAction'] = $this->params['causeAction'];
+ $extraParams['causeAgent'] = $this->params['causeAgent'];
// Convert this into no more than $wgUpdateRowsPerJob RefreshLinks per-title
// jobs and possibly a recursive RefreshLinks job for the rest of the backlinks
$jobs = BacklinkJobUtils::partitionBacklinkJob(
$lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
foreach ( $updates as $update ) {
+ // Carry over cause in case so the update can do extra logging
+ $update->setCause( $this->params['causeAction'], $this->params['causeAgent'] );
// FIXME: This code probably shouldn't be here?
// Needed by things like Echo notifications which need
// to know which user caused the links update
public function getDeduplicationInfo() {
$info = parent::getDeduplicationInfo();
+ unset( $info['causeAction'] );
+ unset( $info['causeAgent'] );
if ( is_array( $info['params'] ) ) {
// For per-pages jobs, the job title is that of the template that changed
// (or similar), so remove that since it ruins duplicate detection
return $this->mPage->doPurge();
}
- /**
- * Call to WikiPage function for backwards compatibility.
- * @see WikiPage::getLastPurgeTimestamp
- * @deprecated since 1.29
- */
- public function getLastPurgeTimestamp() {
- wfDeprecated( __METHOD__, '1.29' );
- return $this->mPage->getLastPurgeTimestamp();
- }
-
/**
* Call to WikiPage function for backwards compatibility.
* @see WikiPage::doViewUpdates
*/
protected $mLinksUpdated = '19700101000000';
- /** @deprecated since 1.29. Added in 1.28 for partial purging, no longer used. */
- const PURGE_CDN_CACHE = 1;
- const PURGE_CLUSTER_PCACHE = 2;
- const PURGE_GLOBAL_PCACHE = 4;
- const PURGE_ALL = 7;
-
/**
* Constructor and clear the article
* @param Title $title Reference to a Title object.
$cache = ObjectCache::getMainWANInstance();
return $cache->getWithSetCallback(
- $cache->makeKey( 'page', 'content-model', $this->getLatest() ),
+ $cache->makeKey( 'page-content-model', $this->getLatest() ),
$cache::TTL_MONTH,
function () {
$rev = $this->getRevision();
return true;
}
- /**
- * Get the last time a user explicitly purged the page via action=purge
- *
- * @return string|bool TS_MW timestamp or false
- * @since 1.28
- * @deprecated since 1.29. It will always return false.
- */
- public function getLastPurgeTimestamp() {
- wfDeprecated( __METHOD__, '1.29' );
- return false;
- }
-
/**
* Insert a new empty page record for this article.
* This *must* be followed up by creating a revision
$this->getTitle(), null, $recursive, $editInfo->output
);
foreach ( $updates as $update ) {
+ $update->setCause( 'edit-page', $user->getName() );
if ( $update instanceof LinksUpdate ) {
$update->setRevision( $revision );
$update->setTriggeringUser( $user );
$dbw->endAtomic( __METHOD__ );
- $this->doDeleteUpdates( $id, $content, $revision );
+ $this->doDeleteUpdates( $id, $content, $revision, $user );
Hooks::run( 'ArticleDeleteComplete', [
&$wikiPageBeforeDelete,
* the required updates. This may be needed because $this->getContent()
* may already return null when the page proper was deleted.
* @param Revision|null $revision The latest page revision
+ * @param User|null $user The user that caused the deletion
*/
- public function doDeleteUpdates( $id, Content $content = null, Revision $revision = null ) {
+ public function doDeleteUpdates(
+ $id, Content $content = null, Revision $revision = null, User $user = null
+ ) {
try {
$countable = $this->isCountable();
} catch ( Exception $ex ) {
DeferredUpdates::addUpdate( $update );
}
+ $causeAgent = $user ? $user->getName() : 'unknown';
// Reparse any pages transcluding this page
- LinksUpdate::queueRecursiveJobsForTable( $this->mTitle, 'templatelinks' );
-
+ LinksUpdate::queueRecursiveJobsForTable(
+ $this->mTitle, 'templatelinks', 'delete-page', $causeAgent );
// Reparse any pages including this image
if ( $this->mTitle->getNamespace() == NS_FILE ) {
- LinksUpdate::queueRecursiveJobsForTable( $this->mTitle, 'imagelinks' );
+ LinksUpdate::queueRecursiveJobsForTable(
+ $this->mTitle, 'imagelinks', 'delete-page', $causeAgent );
}
// Clear caches
}
foreach ( $info['config'] as $key => $val ) {
if ( $key[0] !== '@' ) {
- $this->globals["$prefix$key"] = $val;
+ $this->addConfigGlobal( "$prefix$key", $val );
}
}
}
if ( isset( $data['path'] ) && $data['path'] ) {
$value = "$dir/$value";
}
- $this->globals["$prefix$key"] = $value;
+ $this->addConfigGlobal( "$prefix$key", $value );
}
}
}
+ /**
+ * Helper function to set a value to a specific global, if it isn't set already.
+ *
+ * @param string $key The config key with the prefix and anything
+ * @param mixed $value The value of the config
+ */
+ private function addConfigGlobal( $key, $value ) {
+ if ( array_key_exists( $key, $this->globals ) ) {
+ throw new RuntimeException(
+ "The configuration setting '$key' was already set by another extension,"
+ . " and cannot be set again." );
+ }
+ $this->globals[$key] = $value;
+ }
+
protected function extractServiceWiringFiles( $dir, array $info ) {
if ( isset( $info['ServiceWiringFiles'] ) ) {
foreach ( $info['ServiceWiringFiles'] as $path ) {
* @return array
*/
public function getStyles( ResourceLoaderContext $context ) {
- $logo = $this->getLogo( $this->getConfig() );
+ $logo = $this->getLogoData( $this->getConfig() );
$styles = parent::getStyles( $context );
$this->normalizeStyles( $styles );
'; }';
if ( is_array( $logo ) ) {
- if ( isset( $logo['1.5x'] ) ) {
- $styles[
- '(-webkit-min-device-pixel-ratio: 1.5), ' .
- '(min--moz-device-pixel-ratio: 1.5), ' .
+ if ( isset( $logo['svg'] ) ) {
+ $styles['all'][] = '.mw-wiki-logo { ' .
+ 'background-image: -webkit-linear-gradient(transparent, transparent), ' .
+ CSSMin::buildUrlValue( $logo['svg'] ) . '; ' .
+ 'background-image: linear-gradient(transparent, transparent), ' .
+ CSSMin::buildUrlValue( $logo['svg'] ) . ';' .
+ 'background-size: 135px auto; }';
+ } else {
+ if ( isset( $logo['1.5x'] ) ) {
+ $styles[
+ '(-webkit-min-device-pixel-ratio: 1.5), ' .
+ '(min--moz-device-pixel-ratio: 1.5), ' .
'(min-resolution: 1.5dppx), ' .
- '(min-resolution: 144dpi)'
- ][] = '.mw-wiki-logo { background-image: ' .
- CSSMin::buildUrlValue( $logo['1.5x'] ) . ';' .
- 'background-size: 135px auto; }';
- }
- if ( isset( $logo['2x'] ) ) {
- $styles[
- '(-webkit-min-device-pixel-ratio: 2), ' .
- '(min--moz-device-pixel-ratio: 2),' .
- '(min-resolution: 2dppx), ' .
- '(min-resolution: 192dpi)'
- ][] = '.mw-wiki-logo { background-image: ' .
- CSSMin::buildUrlValue( $logo['2x'] ) . ';' .
- 'background-size: 135px auto; }';
+ '(min-resolution: 144dpi)'
+ ][] = '.mw-wiki-logo { background-image: ' .
+ CSSMin::buildUrlValue( $logo['1.5x'] ) . ';' .
+ 'background-size: 135px auto; }';
+ }
+ if ( isset( $logo['2x'] ) ) {
+ $styles[
+ '(-webkit-min-device-pixel-ratio: 2), ' .
+ '(min--moz-device-pixel-ratio: 2), ' .
+ '(min-resolution: 2dppx), ' .
+ '(min-resolution: 192dpi)'
+ ][] = '.mw-wiki-logo { background-image: ' .
+ CSSMin::buildUrlValue( $logo['2x'] ) . ';' .
+ 'background-size: 135px auto; }';
+ }
}
}
}
}
+ /**
+ * @since 1.31
+ * @param Config $conf
+ * @return string|array
+ */
+ protected function getLogoData( Config $conf ) {
+ return static::getLogo( $conf );
+ }
+
/**
* @param Config $conf
- * @return string|array Single url if no variants are defined
- * or array of logo urls keyed by dppx in form "<float>x".
- * Key "1x" is always defined.
+ * @return string|array Single url if no variants are defined,
+ * or an array of logo urls keyed by dppx in form "<float>x".
+ * Key "1x" is always defined. Key "svg" may also be defined,
+ * in which case variants other than "1x" are omitted.
*/
public static function getLogo( Config $conf ) {
$logo = $conf->get( 'Logo' );
'1x' => $logo1Url,
];
- // Only 1.5x and 2x are supported
- if ( isset( $logoHD['1.5x'] ) ) {
- $logoUrls['1.5x'] = OutputPage::transformResourcePath(
+ if ( isset( $logoHD['svg'] ) ) {
+ $logoUrls['svg'] = OutputPage::transformResourcePath(
$conf,
- $logoHD['1.5x']
- );
- }
- if ( isset( $logoHD['2x'] ) ) {
- $logoUrls['2x'] = OutputPage::transformResourcePath(
- $conf,
- $logoHD['2x']
+ $logoHD['svg']
);
+ } else {
+ // Only 1.5x and 2x are supported
+ if ( isset( $logoHD['1.5x'] ) ) {
+ $logoUrls['1.5x'] = OutputPage::transformResourcePath(
+ $conf,
+ $logoHD['1.5x']
+ );
+ }
+ if ( isset( $logoHD['2x'] ) ) {
+ $logoUrls['2x'] = OutputPage::transformResourcePath(
+ $conf,
+ $logoHD['2x']
+ );
+ }
}
return $logoUrls;
'tly' => 'толышә зывон', # Talysh
'tn' => 'Setswana', # Setswana
'to' => 'lea faka-Tonga', # Tonga (Tonga Islands)
- 'tokipona' => 'Toki Pona', # Toki Pona
'tpi' => 'Tok Pisin', # Tok Pisin
'tr' => 'Türkçe', # Turkish
'tru' => 'Ṫuroyo', # Turoyo
"recentchanges-legend": "Opciones de cambios recientes",
"recentchanges-summary": "Sigui los cambios más recientes na wiki nesta páxina.",
"recentchanges-noresult": "Nengún cambiu nel periodu conseñáu coincide con esos criterios.",
+ "recentchanges-timeout": "Esta gueta escosó'l tiempu. Escurque quieras tentar con parámetros de gueta distintos.",
"recentchanges-feed-description": "Sigui nesta canal los últimos cambios de la wiki.",
"recentchanges-label-newpage": "Esta edición creó una páxina nueva",
"recentchanges-label-minor": "Esta ye una edición menor",
"views": "Görünüş",
"toolbox": "Alətlər",
"tool-link-userrights": "{{GENDER:$1|İstifadəçi}} qruplarını dəyişdir",
- "tool-link-userrights-readonly": "İstifadəçi qruplarına bax",
+ "tool-link-userrights-readonly": "{{GENDER:$1|İstifadəçi}} qruplarına bax",
"imagepage": "Fayl səhifəsini göstər",
"mediawikipage": "Mesaj səhifəsini göstər",
"templatepage": "Şablon səhifəsini göstər",
"password-login-forbidden": "Bu istifadəçi adından və paroldan istifadə qadağan olunub.",
"mailmypassword": "E-mail ilə yeni parol göndər",
"passwordremindertitle": "{{SITENAME}} parol xatırladıcı",
- "passwordremindertext": "Kimsə (ehtimal ki siz özünüz, $1 IP ünvanından) {{SITENAME}} ($4) layihəsi \nüçün yeni bir parol göndərilməsini istəyib. \"$2\" adlı istifadəçi üçün müvəqqəti \nolaraq \"$3\" parolu yaradılıb. Əgər bu sizin istəyiniz əsasında olubsa, \nhesabınıza daxil olaraq yeni bir parol yaratmağınız vacibdir. Müvəqqəti parolunuz\n{{PLURAL:$5|1 gün|$5 gün}} ərzində qüvvədə olacaqdır.\n\nParol dəyişdirməni siz istəməmisinizsə və ya parolunuzu xatırladınızsa \nvə artıq parolunuzu dəyişdirmək istəmirsinizsə, bu mesaja əhəmiyyət vermədən \nəvvəlki parolunuzdan istifadə etməyə davam edə bilərsiniz.",
+ "passwordremindertext": "Kimsə (ehtimal ki, siz özünüz, $1 IP ünvanından) {{SITENAME}} ($4) layihəsi \nüçün yeni bir parol göndərilməsini istəyib. \"$2\" adlı istifadəçi üçün müvəqqəti \nolaraq \"$3\" parolu yaradılıb. Əgər bu sizin istəyiniz əsasında olubsa, \nhesabınıza daxil olaraq yeni bir parol yaratmağınız vacibdir. Müvəqqəti parolunuz\n{{PLURAL:$5|1 gün|$5 gün}} ərzində qüvvədə olacaqdır.\n\nParol dəyişdirməni siz istəməmisinizsə və ya parolunuzu xatırladınızsa \nvə artıq parolunuzu dəyişdirmək istəmirsinizsə, bu mesaja əhəmiyyət vermədən \nəvvəlki parolunuzdan istifadə etməyə davam edə bilərsiniz.",
"noemail": "\"$1\" adlı istifadəçi e-poçt ünvanını qeyd etməmişdir.",
"noemailcreate": "Düzgün e-poçt ünvanı qeyd etməlisiniz",
"passwordsent": "Yeni parol \"$1\" üçün qeydiyyata alınan e-poçt ünvanına göndərilmişdir.\nXahiş edirik, e-məktubu aldıqdan sonra yenidən daxil olasınız.",
"anoneditwarning": "<strong>Diqqət:</strong> Siz sistemə daxil olmamısınız. Hər hansı dəyişiklik etsəniz, sizin IP-ünvanınız hamıya görünəcək. Əgər <strong>[$1 daxil olsanız]</strong> və ya <strong>[$2 hesab yaratsanız]</strong>, redaktələriniz sizin istifadəçi adınıza yazılacaq və digər üstünlüklər də qazanacaqsınız.",
"anonpreviewwarning": "Sistemə daxil olmamısınız. \"Səhifəni qeyd et\" düyməsini bassanız IP ünvanınız səhifənin tarixçəsində qeyd olunacaq.",
"missingsummary": "'''Xatırlatma.''' Siz dəyişikliklərin qısa şərhini verməmisiniz. \"Səhifəni qeyd et\" düyməsinə təkrar basandan sonra sizin dəyişiklikləriniz şərhsiz qeyd olunacaq.",
- "missingcommenttext": "Zəhmət olmasa, aşağıda şərhinizi yazın.",
+ "missingcommenttext": "Zəhmət olmasa, şərh yazın.",
"summary-preview": "Dəyişikliyin izahının görünüşü:",
"subject-preview": "Sərlövhə belə olacaq:",
"blockedtitle": "İstifadəçi bloklanıb",
"timezoneregion-europe": "Avropa",
"timezoneregion-indian": "Hind Okeanı",
"timezoneregion-pacific": "Sakit Okean",
- "allowemail": "Digər istifadəçilər mənə e-məktub göndərə bilər",
+ "allowemail": "Digər istifadəçilərin mənə e-məktub göndərməsinə icazə ver",
"prefs-searchoptions": "Axtar",
"prefs-namespaces": "Adlar fəzası",
"default": "boş",
"editusergroup": "İstifadəçi qruplarını yüklə",
"editinguser": "İstifadəçi <strong>[[User:$1|$1]]</strong> $2 üçün istifadəçi hüquqları dəyişdirilir",
"userrights-editusergroup": "İstifadəçinin qruplarını redaktə et",
- "userrights-viewusergroup": "İstifadəçi qruplarına bax",
+ "userrights-viewusergroup": "{{GENDER:$1|İstifadəçi}} qruplarına bax",
"saveusergroups": "{{GENDER:$1|İstifadəçi}} qruplarını qeyd et",
"userrights-groupsmember": "Daxil olduğu qruplar:",
"userrights-groupsmember-auto": "Güman edilən üzv:",
"rcfilters-days-show-days": "$1 {{PLURAL:$1|gün|gün}}",
"rcfilters-days-show-hours": "$1 {{PLURAL:$1|saat|saat}}",
"rcfilters-quickfilters": "Yaddaşdakı filtrlər",
- "rcfilters-quickfilters-placeholder-title": "Yaddaşa verilmiş keçid yoxdur",
+ "rcfilters-quickfilters-placeholder-title": "Yaddaşa verilmiş filtr yoxdur",
"rcfilters-quickfilters-placeholder-description": "Filtr nizamlamalarını yaddaşda saxlamaq və sonradan təkrar istifadə etmək üçün aşağıdakı Aktiv Filtrlər bölməsindəki əlfəcin nişanını tıqlayın.",
"rcfilters-savedqueries-rename": "Adını dəyiş",
"rcfilters-savedqueries-setdefault": "Standart filtr et",
"exbeforeblank": "Silinmədən əvvəlki məzmun: '$1'",
"delete-confirm": "Silinən səhifə: \"$1\"",
"delete-legend": "Sil",
- "historywarning": "'''Xəbərdarlıq:''' Silinəcək səhifənin tarixçəsində qeyd olunmuş $1 {{PLURAL:$1|redaktə|redaktə}} var:",
+ "historywarning": "'''Xəbərdarlıq:''' Silmək istədiyiniz səhifənin tarixçəsində qeyd olunmuş $1 {{PLURAL:$1|redaktə|redaktə}} var:",
"historyaction-submit": "Göstər",
"confirmdeletetext": "Bu səhifə və ya fayl bütün tarixçəsi ilə birlikdə birdəfəlik silinəcək. Bunu [[{{MediaWiki:Policy-url}}|qaydalara]] uyğun etdiyinizi və əməliyyatın nəticələrini başa düşdüyünüzü təsdiq edin.",
"actioncomplete": "Fəaliyyət tamamlandı",
"rollbackfailed": "Geri qaytarma uğursuzdur",
"cantrollback": "Redaktə geri qaytarıla bilməz; axırıncı redaktə səhifədə olan yeganə fəaliyyətdir.",
"revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|Müzakirə]]) tərəfindən edilmiş dəyişikliklər [[User:$1|$1]] tərəfindən edilmiş dəyişikliklərə qaytarıldı.",
- "revertpage-nouser": "(istifadəçi adı çıxarılmış) tərəfindən edilən dəyişikliklər [[User:$1|$1]] tərəfindən edilən son dəyişikliyə geri alındı",
+ "revertpage-nouser": "İstifadəçi adı gizlədilmiş istifadəçi tərəfindən edilən dəyişikliklər {{GENDER:$1|[[User:$1|$1]]}} tərəfindən edilmiş son redaktəyə geri qaytarıldı",
"rollback-success": "$1 tərəfindən edilmiş redaktələr geri qaytarıldı; $2 tərəfindən yaradılmış son versiya bərpa olundu.",
"sessionfailure-title": "Giriş səhvi",
"changecontentmodel-reason-label": "Səbəb:",
"mergelog": "Zapisnik spajanja",
"revertmerge": "Vrati spajanje",
"mergelogpagetext": "Ispod je spisak nedavnih spajanja historija stranica.",
- "history-title": "$1: Historija izmjena",
- "difference-title": "$1: Razlike između izmjena",
+ "history-title": "Historija izmjena stranice \"$1\"",
+ "difference-title": "Razlike između verzija stranice \"$1\"",
"difference-title-multipage": "$1 i $2: Razlike između stranica",
"difference-multipage": "(Razlika između stranica)",
"lineno": "Red $1:",
"recentchanges-legend": "Anzeigeoptionen",
"recentchanges-summary": "Auf dieser Seite kannst du die letzten Änderungen in diesem Wiki nachverfolgen.",
"recentchanges-noresult": "Keine Änderungen während des angegebenen Zeitraums entsprechen diesen Kriterien.",
+ "recentchanges-timeout": "Die Zeit für diese Suche wurde überschritten. Du kannst verschiedene Suchparameter ausprobieren.",
"recentchanges-feed-description": "Verfolge mit diesem Feed die letzten Änderungen in {{SITENAME}}.",
"recentchanges-label-newpage": "Neue Seite",
"recentchanges-label-minor": "Kleine Änderung",
"recentchanges-legend": "Azken aldaketen aukerak",
"recentchanges-summary": "Orrialde honetan ikus ditzakezu wiki honetan egindako azken aldaketak.",
"recentchanges-noresult": "Ez da egon aldaketarik emandako tartean irizpide hau betetzen dutenik.",
+ "recentchanges-timeout": "Bilaketa honek denbora muga gainditu du. Agian beste parametro batzuekin bilatu nahi duzu.",
"recentchanges-feed-description": "Sindikazio honetan wikian eginiko azkeneko aldaketak jarrai daitezke.",
"recentchanges-label-newpage": "Aldaketa honek orri berri bat sortu du",
"recentchanges-label-minor": "Aldaketa hau txikia da",
"anonpreviewwarning": "''شما به سامانه وارد نشدهاید. ذخیره کردن باعث میشود که نشانی آیپی شما در تاریخچهٔ این صفحه ثبت گردد.''",
"missingsummary": "'''یادآوری:''' شما خلاصهٔ ویرایش ننوشتهاید.\nاگر دوباره دکمهٔ «$1» را فشار دهید ویرایش شما بدون آن ذخیره خواهد شد.",
"selfredirect": "<strong>هشدار:</strong> شما در حال تغییرمسیر صفحه به خودش هستید.\nامکان دارد هدف اشتباهی را برای تغییرمسیر انتخاب کردید، یا ممکن است صفحهٔ اشتباهی را ویرایش میکنید.\n\nاگر بر روی «$1» دوباره کلیک کنید، تغییرمسیر ساخته خواهد شد.",
- "missingcommenttext": "Ù\84Ø·Ù\81اÙ\8b تÙ\88ضÛ\8cØÛ\8c در زÛ\8cر بÛ\8cÙ\81زاÛ\8cÛ\8cد.",
+ "missingcommenttext": "لطفاً توضیحی بیفزایید.",
"missingcommentheader": "<strong>یادآوری:</strong> شما موضوع/عنوان این یادداشت را مشخص نکردهاید.\nاگر دوباره دکمهٔ «$1» را فشار دهید ویرایش شما بدون آن ذخیره خواهد شد.",
"summary-preview": "پیشنمایش خلاصه:",
"subject-preview": "پیشنمایش موضوع:",
"recentchanges-legend": "گزینههای تغییرات اخیر",
"recentchanges-summary": "آخرین تغییرات ویکی را در این صفحه پیگیری کنید.",
"recentchanges-noresult": "در فاصله زمانی ارائه شده هیچ تغییری با این معیارهای صورت نگرفته است",
+ "recentchanges-timeout": "این جستجو زمانش تمام شد. اگر مایلید کلیدواژههای دیگری را جستجو کنید.",
"recentchanges-feed-description": "آخرین تغییرات ویکی را در این خوراک پیگیری کنید.",
"recentchanges-label-newpage": "این ویرایش صفحهای تازه ایجاد کرد",
"recentchanges-label-minor": "این یک ویرایش جزئی است",
"rcfilters-days-show-hours": "$1 {{PLURAL:$1|ساعت|ساعت}}",
"rcfilters-highlighted-filters-list": "پررنگ شده: $1",
"rcfilters-quickfilters": "پالایههای ذخیرهشده",
- "rcfilters-quickfilters-placeholder-title": "هنوز پیوندی ذخیره نشدهاست",
+ "rcfilters-quickfilters-placeholder-title": "هنوز پالایهای ذخیره نشدهاست",
"rcfilters-quickfilters-placeholder-description": "برای ذخیره پالایههایتان و استفاده مجدد آنها، در محیط فعال پالایه در پایین بر روی دکمهٔ بوکمارک کلیک کنید.",
"rcfilters-savedqueries-defaultlabel": "پالایههای ذخیرهشده",
"rcfilters-savedqueries-rename": "تغییر نام",
"anonpreviewwarning": "''Et ole kirjautunut sisään. Tallentaminen kirjaa IP-osoitteesi tämän sivun muutoshistoriaan.''",
"missingsummary": "Et ole antanut yhteenvetoa. Jos valitset Tallenna uudelleen, niin muokkauksesi tallennetaan ilman yhteenvetoa.",
"selfredirect": "<strong>Varoitus:</strong> Olet tekemässä uudelleenohjausta, joka johtaa tästä sivusta tähän samaan sivuun. \n\nOlet ehkä määrittänyt ohjauksen kohteen väärin tai kenties muokkaat parhaillaan väärää sivua.\n\nJos painat toimintoa \"$1\" uudestaan, tämä ohjaussivu luodaan joka tapauksessa.",
- "missingcommenttext": "Kirjoita viesti alle.",
+ "missingcommenttext": "Kirjoita kommentti.",
"missingcommentheader": "<strong>Muistutus:</strong> Et ole antanut aiheotsikkoa tälle kommentille. Napsauta ”$1”, jos haluat tallentaa kommenttisi ilman sellaista.",
"summary-preview": "Yhteenvedon esikatselu:",
"subject-preview": "Aiheotsikon esikatselu:",
"grant-editprotected": "Muokata suojattuja sivuja",
"grant-highvolume": "Suorittaa paljon muokkauksia",
"grant-oversight": "Piilottaa käyttäjiä ja häivyttää yksittäisiä versioita",
- "grant-patrol": "Partioida sivuihin tehtyjä muutoksia",
+ "grant-patrol": "Tarkastaa sivuihin tehtyjä muutoksia",
"grant-privateinfo": "Päästä näkemään yksityiset tiedot",
"grant-protect": "Suojata sivuja tai poistaa suojauksia",
"grant-rollback": "Palauttaa sivuun tehtyjä muutoksia",
"rcfilters-filter-user-experience-level-unregistered-label": "Rekisteröimätön",
"rcfilters-filter-user-experience-level-unregistered-description": "Muokkaajat, jotka eivät ole kirjautuneet sisään.",
"rcfilters-filter-user-experience-level-newcomer-label": "Tulokkaat",
- "rcfilters-filter-user-experience-level-newcomer-description": "Rekisteröityneet muokkaajat, joilla vähemmän kuin 10 muokkausta ja 4 päivää aktiivisuutta.",
+ "rcfilters-filter-user-experience-level-newcomer-description": "Rekisteröityneet muokkaajat, joilla vähemmän kuin 10 muokkausta tai 4 päivää aktiivisuutta.",
"rcfilters-filter-user-experience-level-learner-label": "Oppijat",
"rcfilters-filter-user-experience-level-learner-description": "Rekisteröityneet muokkaajat, joiden kokemus on välillä \"tulokas\" ja \"kokenut käyttäjä\".",
"rcfilters-filter-user-experience-level-experienced-label": "Kokeneet käyttäjät",
"delete-warning-toobig": "Tällä sivulla on pitkä muutoshistoria – yli $1 {{PLURAL:$1|versio|versiota}}. Näin suurien muutoshistorioiden poistaminen voi haitata sivuston suorituskykyä.",
"deleteprotected": "Et voi poistaa tätä sivua, koska se on suojattu.",
"deleting-backlinks-warning": "<strong>Varoitus:</strong> Sivulle, jota olet poistamassa, johtaa [[Special:WhatLinksHere/{{FULLPAGENAME}}|linkkejä muilta sivuilta]], taikka sivu on sisällytetty muuhun sivuun.",
+ "deleting-subpages-warning": "<strong>Varoitus:</strong> Sivu jota olet poistamassa on [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|alasivu|$1 alasivua|51=yli 50 alasivua}}]].",
"rollback": "palauta aiempaan versioon",
"rollbacklink": "palauta",
"rollbacklinkcount": "palauta $1 {{PLURAL:$1|muutos|muutosta}}",
"undelete-search-title": "Etsi poistettuja sivuja",
"undelete-search-box": "Etsi poistettuja sivuja",
"undelete-search-prefix": "Näytä sivut, jotka alkavat merkkijonolla:",
+ "undelete-search-full": "Näytä sivut, joiden otsikko sisältää:",
"undelete-search-submit": "Hae",
"undelete-no-results": "Poistoarkistosta ei löytynyt haettuja sivuja.",
"undelete-filename-mismatch": "Tiedoston versiota, jonka aikaleima on $1, ei voi palauttaa, koska tiedostonimi ei ole sama.",
"compare-title-not-exists": "Määrittämääsi sivua ei ole.",
"compare-revision-not-exists": "Määrittämääsi versiota ei ole.",
"diff-form": "Eroavaisuudet",
+ "permanentlink": "Pysyvä linkki",
"dberr-problems": "Tällä sivustolla on teknisiä ongelmia.",
"dberr-again": "Odota hetki ja lataa sivu uudelleen.",
"dberr-info": "(Tietokantaan ei saada yhteyttä: $1)",
"recentchanges-legend": "Options des modifications récentes",
"recentchanges-summary": "Suivez les changements les plus récents du wiki sur cette page.",
"recentchanges-noresult": "Aucune modification correspondant à ces critères sur la période indiquée.",
+ "recentchanges-timeout": "Cette recherche a dépassé le délai imparti. Vous pouvez vouloir essayer avec des paramètres de recherche différents.",
"recentchanges-feed-description": "Suivez les dernières modifications du wiki dans ce flux.",
"recentchanges-label-newpage": "Cette modification a créé une nouvelle page",
"recentchanges-label-minor": "Cette modification est mineure.",
"recentchanges-legend": "אפשרויות בשינויים האחרונים",
"recentchanges-summary": "ניתן לעקוב אחרי השינויים האחרונים באתר בדף זה.",
"recentchanges-noresult": "לא היו בתקופה זו שינויים המתאימים לאפשרויות שנבחרו.",
+ "recentchanges-timeout": "נגמר זמן ההמתנה לקבלת תוצאות החיפוש. ניתן לנסות פרמטרים אחרים לחיפוש.",
"recentchanges-feed-description": "ניתן לעקוב אחרי השינויים האחרונים באתר בדף זה.",
"recentchanges-label-newpage": "בעריכה זו נוצר דף חדש",
"recentchanges-label-minor": "זוהי עריכה משנית",
"prefs-email": "Mogućnosti e-maila",
"prefs-rendering": "Izgled",
"saveprefs": "Spremi",
- "restoreprefs": "Vrati sve postavke na prvotno zadane",
+ "restoreprefs": "Vrati sve postavke na prvobitno zadane (u svim odjeljcima)",
"prefs-editing": "Uređivanje",
"searchresultshead": "Prikaz rezultata pretrage",
"stub-threshold": "Prag za formatiranje poveznice na mrve ($1):",
"rcfilters-filter-user-experience-level-unregistered-description": "Cangiature ca non g'onne trasute.",
"rcfilters-filter-user-experience-level-newcomer-label": "Utinde nuève",
"rcfilters-filter-user-experience-level-learner-label": "Uecchieachiuse",
+ "rcfilters-filter-user-experience-level-experienced-label": "Utinde cu esperienze",
+ "rcfilters-filter-user-experience-level-experienced-description": "Utinde reggistrate cu cchiù de 500 cangiaminde e 30 sciurne de attivitate.",
+ "rcfilters-filtergroup-automated": "Condrebbute automatece",
"rcfilters-filter-bots-label": "Bot",
+ "rcfilters-filter-bots-description": "Cangiaminde fatte da struminde automatece.",
+ "rcfilters-filter-humans-label": "Umane (none bot)",
+ "rcfilters-filter-humans-description": "Cangiaminde fatte da condrebbuture umane.",
+ "rcfilters-filtergroup-reviewstatus": "State d'a revisione",
"rcfilters-filter-patrolled-label": "Condrollate",
"rcfilters-filter-patrolled-description": "Cangiaminde signate cumme condrollate.",
"rcfilters-filter-unpatrolled-label": "Non condrollate",
"recentchanges-legend": "Možnosti zadnjih sprememb",
"recentchanges-summary": "Na tej strani lahko spremljate najnovejše spremembe wikija.",
"recentchanges-noresult": "V danem obdobju nobena sprememba ne ustreza tem merilom.",
+ "recentchanges-timeout": "Čas iskanja je potekel. Poskusite uporabiti drugačne parametre iskanja.",
"recentchanges-feed-description": "Spremljajte zadnje spremembe wikija prek tega vira.",
"recentchanges-label-newpage": "To urejanje je ustvarilo novo stran",
"recentchanges-label-minor": "To je manjše urejanje",
"ncategories": "$1 {{PLURAL:$1|гурӯҳ|гурӯҳҳо}}",
"nlinks": "$1 {{PLURAL:$1|пайванд|пайвандҳо}}",
"nmembers": "$1 {{PLURAL:$1|узв}}",
- "nrevisions": "$1 {{PLURAL:$1|вироиш|вироиш}}",
+ "nrevisions": "{{PLURAL:$1|вироиш|вироиши}} $1",
"specialpage-empty": "Барои ин ҳисобот натиҷае вуҷуд надорад.",
"lonelypages": "Саҳифаҳои ятим",
"lonelypagestext": "Ба саҳифаҳои зерин дар дигар саҳифаи {{SITENAME}} пайванд дода нашудааст.",
"import-comment": "Тавзеҳ:",
"importtext": "Лутфан парвандаро аз вики манбаъ содир кунед, аз тариқи саҳифа [[Special:Export|абзори содирот]].\nПас онро ба компютератон захира карда инҷо боргузорӣ кунед.",
"importstart": "Дар ҳоли ворид кардани саҳифаҳо...",
- "import-revision-count": "$1 {{PLURAL:$1|вироиш|вироиш}}",
+ "import-revision-count": "{{PLURAL:$1|вироиш|вироиши}} $1",
"importnopages": "Саҳифаҳо барои ворид кардан нест.",
"importfailed": "Ворид кардани саҳифаҳо шикаст хӯрд: $1",
"importunknownsource": "Навъи манбаи номаълум барои воридкуни",
+++ /dev/null
-{
- "@metadata": {
- "authors": [
- "http://tokipona.wikia.com sysops"
- ]
- },
- "january": "tenpo mun pi nanpa wan",
- "february": "tenpo mun pi nanpa tu",
- "march": "tenpo mun pi nanpa tu wan",
- "april": "tenpo mun pi nanpa tu tu",
- "may_long": "tenpo mun pi nanpa luka",
- "june": "tenpo mun pi nanpa luka wan",
- "july": "tenpo mun pi nanpa luka tu",
- "august": "tenpo mun pi nanpa luka tu wan",
- "september": "tenpo mun pi nanpa luka tu tu",
- "october": "tenpo mun pi nanpa luka luka",
- "november": "tenpo mun pi nanpa luka luka wan",
- "december": "tenpo mun pi nanpa luka luka tu",
- "category_header": "lipu lon kulupu lipu \"$1\"",
- "subcategories": "kulupu lipu lili",
- "listingcontinuesabbrev": " li awen",
- "article": "lipu sona",
- "newwindow": "(ona li open e lupa sin)",
- "cancel": "ike",
- "mytalk": "toki mi",
- "navigation": "lipu suli",
- "help": "mi sona ala",
- "search": "o lukin jo",
- "go": "o tawa",
- "history": "o lukin e lipu ni pi tenpo pini",
- "history_short": "lipu ni pi tenpo pini",
- "printableversion": "lipu ni o kama lipu len",
- "permalink": "nimi open kiwen",
- "edit": "o ante",
- "editthispage": "o ante e lipu ni",
- "delete": "o weka",
- "deletethispage": "o weka e lipu ni",
- "protect": "mi taso o ken ante",
- "protectthispage": "mi taso o ken ante e lipu ni",
- "unprotect": "jan ali o ken ante",
- "unprotectthispage": "jan ale o ken ante e lipu ni",
- "talkpage": "Talk page",
- "specialpage": "lipu suli",
- "talk": "o toki",
- "toolbox": "ilo",
- "otherlanguages": "toki ante",
- "redirectedfrom": "(tan $1)",
- "aboutsite": "lipu sona pi toki pona li seme?",
- "aboutpage": "Project:lipu sona pi toki pona li seme?",
- "copyright": "lipu ken $1 li lawa e lipu ni.",
- "currentevents": "seme li sin lon ma?",
- "disclaimers": "wile ala",
- "edithelp": "mi sona ala e ante",
- "mainpage": "lipu lawa",
- "mainpage-description": "lipu lawa",
- "portal": "lipu pi kulupu ni",
- "privacy": "ken pi awen weka",
- "ok": "pona",
- "retrievedfrom": "tan $1",
- "editsection": "o ante",
- "toc": "poki lawa",
- "showtoc": "o suli e poki ni.",
- "hidetoc": "o lili e poki ni",
- "nstab-main": "lipu sona",
- "nstab-user": "lipu jan",
- "nstab-special": "suli",
- "nstab-image": "lipu nanpa",
- "nstab-mediawiki": "nimi",
- "nstab-template": "lipu mama",
- "nstab-help": "pana pona",
- "nstab-category": "kulupu lipu",
- "logout": "mi o tawa",
- "userlogout": "mi o tawa",
- "summary": "ante li seme:",
- "minoredit": "ante ni li lili taso",
- "watchthis": "mi wile sona e ante ale pi lipu ni lon tenpo kama",
- "savearticle": "o awen",
- "preview": "lukin taso",
- "showpreview": "mi wile lukin taso e ante",
- "editing": "mi ante e: $1",
- "editingcomment": "mi ante e lipu $1 (wan sin)",
- "copyrightwarning": "o sona e ni: ken $2 (o lukin e $1) li lawa tawa ante ali lon {{SITENAME}} li. jan li ken ante e toki sina li ken pana e ona tawa jan ante. sina wile ala e ni la, o sitelen ala lon lipu ni.<br />\nkin la sina toki e ni: toki sina ni li tan sina taso anu lipu pi ken ali.\n'''SINA KEN ALA LA, O PANA ALA E TOKI PI KEN LILI TAWA LIPU NI!'''",
- "templatesused": "{{PLURAL:$1|Template|Templates}} used on this page:",
- "histfirst": "pini taso",
- "histlast": "sin taso",
- "prevn": "nanpa {{PLURAL:$1|$1}} pini",
- "nextn": "nanpa {{PLURAL:$1|$1}} kama",
- "viewprevnext": "o lukin e ($1 {{int:pipe-separator}} $2) ($3).",
- "preferences": "seme li pona tawa mi",
- "recentchanges": "lipu seme li ante?",
- "minoreditletter": "ante lili",
- "newpageletter": "lipu sin",
- "recentchangeslinked": "ante sama",
- "recentchangeslinked-feed": "ante sama",
- "recentchangeslinked-toolbox": "ante sama",
- "upload": "o pana e lipu nanpa",
- "filedesc": "ante li seme",
- "fileuploadsummary": "ante li seme:",
- "file-anchor-link": "Lipu nanpa",
- "randompage": "mi wile lukin e lipu ante",
- "lonelypages": "lipu ni li jo ala e lipu sama",
- "move": "o tawa",
- "movethispage": "o pana e nimi sin",
- "allpages": "lipu ale",
- "categories": "kulupu lipu",
- "watchlist": "mi sona e ante pi lipu seme",
- "watch": "o sona e ante",
- "watchthispage": "mi wile sona e ante ale pi lipu ni lon tenpo kama",
- "unwatchthispage": "mi wile ala sona e ante ale pi lipu ni lon tenpo kama",
- "mycontris": "mi ante e lipu seme",
- "whatlinkshere": "lipu seme li tawa ni?",
- "specialpages": "lipu suli"
-}
"anonpreviewwarning": "''Ви не увійшли в систему. Якщо ви виконаєте збереження, то в історію сторінки буде записана ваша IP-адреса.''",
"missingsummary": "'''Нагадування''': Ви не дали короткого опису змін.\nНатиснувши кнопку «Зберегти» ще раз, ви збережете зміни без коментаря.",
"selfredirect": "<strong>Попередження:</strong> Ви створюєте перенаправлення на цю ж сторінку.\nВи могли вказати невірну цільову сторінку, або ж редагуєте хибну сторінку.\nЯкщо Ви натиснете \"$1\" ще раз, перенаправлення буде створено.",
- "missingcommenttext": "Ð\91Ñ\83дÑ\8c лаÑ\81ка, введÑ\96Ñ\82Ñ\8c нижÑ\87е ваÑ\88е повÑ\96домленнÑ\8f.",
+ "missingcommenttext": "Ð\91Ñ\83дÑ\8c лаÑ\81ка, введÑ\96Ñ\82Ñ\8c коменÑ\82аÑ\80.",
"missingcommentheader": "<strong>Нагадування</strong>: Ви не вказали тему для цього коментаря.\nНатиснувши кнопку «$1» ще раз, Ви збережете редагування без заголовка.",
"summary-preview": "Попередній перегляд опису редагування:",
"subject-preview": "Попередній перегляд теми:",
"recentchanges-legend": "Налаштування нових редагувань",
"recentchanges-summary": "Відстеження останніх змін на сторінках {{grammar:genitive|{{SITENAME}}}}.",
"recentchanges-noresult": "Немає змін за даний період, що відповідають цим критеріям.",
+ "recentchanges-timeout": "Час, відведений на цей пошук, вичерпано. Можливо, Ви захочете спробувати інші пошукові параметри.",
"recentchanges-feed-description": "Відстежувати останні зміни у вікі в цьому потоці.",
"recentchanges-label-newpage": "Цим редагуванням створена нова сторінка",
"recentchanges-label-minor": "Це незначна зміна",
"rcfilters-filter-user-experience-level-unregistered-label": "Незареєстровані",
"rcfilters-filter-user-experience-level-unregistered-description": "Користувачі, які не ввійшли в систему.",
"rcfilters-filter-user-experience-level-newcomer-label": "Новачки",
- "rcfilters-filter-user-experience-level-newcomer-description": "Зареєстровані редактори, які мають менш ніж 10 редагувань і 4 дні активності.",
+ "rcfilters-filter-user-experience-level-newcomer-description": "Зареєстровані редактори, які мають менш ніж 10 редагувань або менш ніж 4 дні активності.",
"rcfilters-filter-user-experience-level-learner-label": "Учні",
"rcfilters-filter-user-experience-level-learner-description": "Зареєстровані редактори, рівень досвіду яких перебуває між «новачками» та «досвідченими користувачами».",
"rcfilters-filter-user-experience-level-experienced-label": "Досвідчені користувачі",
"rcfilters-filter-newpages-label": "頁面建立",
"rcfilters-filter-newpages-description": "建立新頁面的編輯。",
"rcfilters-filter-categorization-label": "分類變更",
- "rcfilters-filter-categorization-description": "å·²å\8a å\85¥å\88°å\88\86é¡\9eæ\88\96å¾\9eå\88\86é¡\9eä¸ç§»é\99¤ç\9a\84é \81é\9d¢記錄。",
+ "rcfilters-filter-categorization-description": "å¾\9eå\88\86é¡\9eä¸æ·»å\8a æ\88\96移é\99¤é \81é\9d¢ç\9a\84記錄。",
"rcfilters-filter-logactions-label": "日誌動作",
"rcfilters-filter-logactions-description": "管理動作、帳號建立、頁面刪除、上傳…",
"rcfilters-hideminor-conflicts-typeofchange-global": "\"次要編輯\" 過濾條件與一個或多個變更類型過濾條件衝突,因為某些變更類型無法指定為 \"次要\"。衝突的過濾條件已在上方使用的過濾條件區域中標示。",
"rcfilters-view-tags": "標記的編輯",
"rcfilters-view-namespaces-tooltip": "按命名空間過濾結果",
"rcfilters-view-tags-tooltip": "按編輯標籤過濾結果",
+ "rcfilters-view-return-to-default-tooltip": "返回主過濾選單",
"rcfilters-view-tags-help-icon-tooltip": "了解更多關於標記編輯的資訊",
"rcfilters-liveupdates-button": "實時更新",
"rcfilters-liveupdates-button-title-on": "關閉實時更新",
// to $maintenance->mSelf. Keep that here for b/c
$self = $maintenance->getName();
-require_once "$IP/includes/PreConfigSetup.php";
-
-if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
- # Use a callback function to configure MediaWiki
- call_user_func( MW_CONFIG_CALLBACK );
-} else {
- // Require the configuration (probably LocalSettings.php)
- require $maintenance->loadSettings();
+// Define how settings are loaded (e.g. LocalSettings.php)
+if ( !defined( 'MW_CONFIG_CALLBACK' ) && !defined( 'MW_CONFIG_FILE' ) ) {
+ define( 'MW_CONFIG_FILE', $maintenance->loadSettings() );
}
-if ( $maintenance->getDbType() === Maintenance::DB_NONE ) {
- if ( $wgLocalisationCacheConf['storeClass'] === false
- && ( $wgLocalisationCacheConf['store'] == 'db'
- || ( $wgLocalisationCacheConf['store'] == 'detect' && !$wgCacheDirectory ) )
- ) {
- $wgLocalisationCacheConf['storeClass'] = 'LCStoreNull';
+// Custom setup for Maintenance entry point
+if ( !defined( 'MW_SETUP_CALLBACK' ) ) {
+ function wfMaintenanceSetup() {
+ // @codingStandardsIgnoreLine MediaWiki.NamingConventions.ValidGlobalName.wgPrefix
+ global $maintenance, $wgLocalisationCacheConf, $wgCacheDirectory;
+ if ( $maintenance->getDbType() === Maintenance::DB_NONE ) {
+ if ( $wgLocalisationCacheConf['storeClass'] === false
+ && ( $wgLocalisationCacheConf['store'] == 'db'
+ || ( $wgLocalisationCacheConf['store'] == 'detect' && !$wgCacheDirectory ) )
+ ) {
+ $wgLocalisationCacheConf['storeClass'] = 'LCStoreNull';
+ }
+ }
+
+ $maintenance->finalSetup();
}
+ define( 'MW_SETUP_CALLBACK', 'wfMaintenanceSetup' );
}
-$maintenance->finalSetup();
-// Some last includes
require_once "$IP/includes/Setup.php";
// Initialize main config instance
}
protected function clearCache( $page_id, $rev_id ) {
- $contentModelKey = $this->wanCache->makeKey( 'page', 'content-model', $rev_id );
+ $contentModelKey = $this->wanCache->makeKey( 'page-content-model', $rev_id );
$revisionKey =
$this->wanCache->makeGlobalKey( 'revision', $this->wikiId, $page_id, $rev_id );
$this->addOption( 'type', 'Type of job to run', false, true );
$this->addOption( 'procs', 'Number of processes to use', false, true );
$this->addOption( 'nothrottle', 'Ignore job throttling configuration', false, false );
- $this->addOption( 'result', 'Set to JSON to print only a JSON response', false, true );
+ $this->addOption( 'result', 'Set to "json" to print only a JSON response', false, true );
$this->addOption( 'wait', 'Wait for new jobs instead of exiting', false, false );
}
"karma-chrome-launcher": "2.0.0",
"karma-firefox-launcher": "1.0.1",
"karma-mocha-reporter": "2.2.3",
- "karma-qunit": "1.0.0",
+ "karma-qunit": "1.2.1",
"nodemw": "0.10.1",
- "qunitjs": "1.23.1",
+ "qunitjs": "2.4.0",
"stylelint": "7.8.0",
"stylelint-config-wikimedia": "0.4.1",
"wdio-junit-reporter": "0.2.0",
} else {
parameters[ key ] = '\x1f' + parameters[ key ].join( '\x1f' );
}
- }
- // Boolean values are only false when not given at all
- if ( parameters[ key ] === false || parameters[ key ] === undefined ) {
+ } else if ( parameters[ key ] === false || parameters[ key ] === undefined ) {
+ // Boolean values are only false when not given at all
delete parameters[ key ];
}
}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- version="1.1"
- width="30"
- height="30"
- id="svg2">
- <defs
- id="defs4" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- transform="matrix(0.41333074,0,0,0.41333074,-183.39876,-197.95599)"
- id="layer1">
- <g
- transform="translate(455.60433,484.94177)"
- id="g3163">
- <path
- d="M 0,0.03543307 0,60.519684 43.192915,30.259842 z"
- id="path3165"
- style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <path
- d="m 43.157481,0.03543307 5.633859,0 0,60.48425093 -5.633859,0 z"
- id="path3167"
- style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- </g>
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- version="1.1"
- width="30"
- height="30"
- id="svg2">
- <defs
- id="defs4" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- transform="matrix(0.4132798,0,0,0.4132798,-87.72955,-233.35372)"
- id="layer1">
- <path
- d="m 272.96237,570.69005 0,60.4894 -43.19393,-30.2447 z"
- id="path3023-7"
- style="fill:#cccccc;fill-opacity:1;stroke:none" />
- <rect
- width="5.6406202"
- height="60.489399"
- x="-229.82111"
- y="570.68774"
- transform="scale(-1,1)"
- id="rect3799-9"
- style="color:#000000;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:20;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- version="1.1"
- width="30"
- height="30"
- id="svg2">
- <defs
- id="defs4" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- transform="matrix(0.41329555,0,0,0.41329555,-111.35036,-135.3531)"
- id="layer1">
- <path
- d="m 284.11732,333.54605 0,60.4894 43.19395,-30.2447 z"
- id="path3023-7-2"
- style="fill:#cccccc;fill-opacity:1;stroke:none" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- version="1.1"
- width="30"
- height="30"
- id="svg2">
- <defs
- id="defs4" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- transform="matrix(0.41329555,0,0,0.41329555,-139.69062,-163.69336)"
- id="layer1">
- <path
- d="m 395.88269,402.11748 0,60.4894 -43.19395,-30.2447 z"
- id="path3023-7-2-8"
- style="fill:#cccccc;fill-opacity:1;stroke:none" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- version="1.1"
- width="30"
- height="30"
- id="svg2">
- <defs
- id="defs4" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- transform="matrix(0.41327999,0,0,0.41327999,-98.356798,-226.26904)"
- id="layer1">
- <path
- d="m 249.89477,553.5472 0,60.4894 43.19391,-30.2447 z"
- id="path3023"
- style="fill:#0000aa;fill-opacity:1;stroke:none" />
- <rect
- width="5.6406202"
- height="60.489399"
- x="293.03604"
- y="553.54492"
- id="rect3799"
- style="color:#000000;fill:#0000aa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:20;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- version="1.1"
- width="30"
- height="30"
- id="svg2"
- inkscape:version="0.48.4 r9939"
- sodipodi:docname="pager-arrow-fastforward-rtl.svg">
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1366"
- inkscape:window-height="692"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="17.4"
- inkscape:cx="7.0114943"
- inkscape:cy="15"
- inkscape:window-x="0"
- inkscape:window-y="24"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg2" />
- <defs
- id="defs4" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- transform="matrix(0.07055556,0,0,0.07055556,-9.1581596,-2.7587241)"
- id="layer1">
- <path
- d="m 485.26916,74.546776 0,354.317014 -253.00859,-177.15851 z"
- id="path3023-2"
- style="fill:#0000aa;fill-opacity:1;stroke:none"
- inkscape:connector-curvature="0" />
- <rect
- width="33.039963"
- height="354.31699"
- x="-232.56898"
- y="74.533081"
- transform="scale(-1,1)"
- id="rect3799-6"
- style="color:#000000;fill:#0000aa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:20;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- version="1.1"
- width="30"
- height="30"
- id="svg2">
- <defs
- id="defs4" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- transform="matrix(0.41329555,0,0,0.41329555,-162.12666,-110.55537)"
- id="layer1">
- <path
- d="m 406.97447,273.54605 0,60.4894 43.19391,-30.2447 z"
- id="path3023-3-9"
- style="fill:#0000aa;fill-opacity:1;stroke:none" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- version="1.1"
- width="30"
- height="30"
- id="svg2">
- <defs
- id="defs4" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- transform="matrix(0.41329555,0,0,0.41329555,-78.28671,-153.06577)"
- id="layer1">
- <path
- d="m 247.31124,376.4032 0,60.4894 -43.19391,-30.2447 z"
- id="path3023-3"
- style="fill:#0000aa;fill-opacity:1;stroke:none" />
- </g>
-</svg>
'not all and (min-resolution: 2dppx),' .
'</img/two-x.png>;rel=preload;as=image;media=(min-resolution: 2dppx)'
],
+ [
+ [
+ 'ResourceBasePath' => '/w',
+ 'Logo' => '/img/default.png',
+ 'LogoHD' => [
+ 'svg' => '/img/vector.svg',
+ ],
+ ],
+ 'Link: </img/vector.svg>;rel=preload;as=image'
+
+ ],
[
[
'ResourceBasePath' => '/w',
);
}
}
+
+ public function testSkinModules() {
+ $factory = new SkinFactory();
+ $factory->register( 'testing', 'Testing', function () {
+ $skin = $this->getMockBuilder( SkinFallback::class )
+ ->setMethods( [ 'getDefaultModules', 'setupSkinUserCss' ] )
+ ->getMock();
+ $skin->expects( $this->once() )->method( 'getDefaultModules' )
+ ->willReturn( [
+ 'core' => [ 'foo', 'bar' ],
+ 'content' => [ 'baz' ]
+ ] );
+ $skin->expects( $this->once() )->method( 'setupSkinUserCss' )
+ ->will( $this->returnCallback( function ( OutputPage $out ) {
+ $out->addModuleStyles( 'foo.styles' );
+ } ) );
+ return $skin;
+ } );
+ $this->setService( 'SkinFactory', $factory );
+
+ $res = $this->doApiRequest( [
+ 'action' => 'parse',
+ 'pageid' => self::$pageId,
+ 'useskin' => 'testing',
+ 'prop' => 'modules',
+ ] );
+ $this->assertSame(
+ [ 'foo', 'bar', 'baz' ],
+ $res[0]['parse']['modules'],
+ 'resp.parse.modules'
+ );
+ $this->assertSame(
+ [],
+ $res[0]['parse']['modulescripts'],
+ 'resp.parse.modulescripts'
+ );
+ $this->assertSame(
+ [ 'foo.styles' ],
+ $res[0]['parse']['modulestyles'],
+ 'resp.parse.modulestyles'
+ );
+ }
}
$this->assertEquals( 'somevalue', $extracted['globals']['egBar'] );
}
+ /**
+ * @covers ExtensionProcessor::addConfigGlobal()
+ * @expectedException RuntimeException
+ */
+ public function testDuplicateConfigKey1() {
+ $processor = new ExtensionProcessor;
+ $info = [
+ 'config' => [
+ 'Bar' => '',
+ ]
+ ] + self::$default;
+ $info2 = [
+ 'config' => [
+ 'Bar' => 'g',
+ ],
+ 'name' => 'FooBar2',
+ ];
+ $processor->extractInfo( $this->dir, $info, 1 );
+ $processor->extractInfo( $this->dir, $info2, 1 );
+ }
+
+ /**
+ * @covers ExtensionProcessor::addConfigGlobal()
+ * @expectedException RuntimeException
+ */
+ public function testDuplicateConfigKey2() {
+ $processor = new ExtensionProcessor;
+ $info = [
+ 'config' => [
+ 'Bar' => [ 'value' => 'somevalue' ],
+ ]
+ ] + self::$default;
+ $info2 = [
+ 'config' => [
+ 'Bar' => [ 'value' => 'somevalue' ],
+ ],
+ 'name' => 'FooBar2',
+ ];
+ $processor->extractInfo( $this->dir, $info, 2 );
+ $processor->extractInfo( $this->dir, $info2, 2 );
+ }
+
public static function provideExtractExtensionMessagesFiles() {
$dir = __DIR__ . '/FooBar/';
return [
<?php
/**
- * @group Database
* @group ResourceLoader
*/
class ResourceLoaderSkinModuleTest extends PHPUnit_Framework_TestCase {
+ // @codingStandardsIgnoreStart Ignore Generic.Files.LineLength.TooLong
public static function provideGetStyles() {
return [
[
'parent' => [],
+ 'logo' => '/logo.png',
'expected' => [
'all' => [ '.mw-wiki-logo { background-image: url(/logo.png); }' ],
],
'parent' => [
'screen' => '.example {}',
],
+ 'logo' => '/logo.png',
'expected' => [
'screen' => [ '.example {}' ],
'all' => [ '.mw-wiki-logo { background-image: url(/logo.png); }' ],
],
],
+ [
+ 'parent' => [],
+ 'logo' => [
+ '1x' => '/logo.png',
+ '1.5x' => '/logo@1.5x.png',
+ '2x' => '/logo@2x.png',
+ ],
+ 'expected' => [
+ 'all' => [ <<<CSS
+.mw-wiki-logo { background-image: url(/logo.png); }
+CSS
+ ],
+ '(-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (min-resolution: 1.5dppx), (min-resolution: 144dpi)' => [ <<<CSS
+.mw-wiki-logo { background-image: url(/logo@1.5x.png);background-size: 135px auto; }
+CSS
+ ],
+ '(-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 2dppx), (min-resolution: 192dpi)' => [ <<<CSS
+.mw-wiki-logo { background-image: url(/logo@2x.png);background-size: 135px auto; }
+CSS
+ ],
+ ],
+ ],
+ [
+ 'parent' => [],
+ 'logo' => [
+ '1x' => '/logo.png',
+ 'svg' => '/logo.svg',
+ ],
+ 'expected' => [
+ 'all' => [ <<<CSS
+.mw-wiki-logo { background-image: url(/logo.png); }
+CSS
+ , <<<CSS
+.mw-wiki-logo { background-image: -webkit-linear-gradient(transparent, transparent), url(/logo.svg); background-image: linear-gradient(transparent, transparent), url(/logo.svg);background-size: 135px auto; }
+CSS
+ ],
+ ],
+ ],
];
}
+ // @codingStandardsIgnoreEnd
/**
* @dataProvider provideGetStyles
* @covers ResourceLoaderSkinModule::normalizeStyles
* @covers ResourceLoaderSkinModule::getStyles
*/
- public function testGetStyles( $parent, $expected ) {
+ public function testGetStyles( $parent, $logo, $expected ) {
$module = $this->getMockBuilder( ResourceLoaderSkinModule::class )
->disableOriginalConstructor()
- ->setMethods( [ 'readStyleFiles' ] )
+ ->setMethods( [ 'readStyleFiles', 'getConfig', 'getLogoData' ] )
->getMock();
$module->expects( $this->once() )->method( 'readStyleFiles' )
->willReturn( $parent );
- $module->setConfig( new HashConfig( [
- 'ResourceBasePath' => '/w',
- 'Logo' => '/logo.png',
- 'LogoHD' => false,
- ] ) );
+ $module->expects( $this->once() )->method( 'getConfig' )
+ ->willReturn( new HashConfig() );
+ $module->expects( $this->once() )->method( 'getLogoData' )
+ ->willReturn( $logo );
$ctx = $this->getMockBuilder( ResourceLoaderContext::class )
->disableOriginalConstructor()->getMock();
$this->assertEquals(
- $module->getStyles( $ctx ),
- $expected
+ $expected,
+ $module->getStyles( $ctx )
);
}
$this->assertFalse( $module->isKnownEmpty( $ctx ) );
}
+
+ /**
+ * @dataProvider provideGetLogo
+ * @covers ResourceLoaderSkinModule::getLogo
+ */
+ public function testGetLogo( $config, $expected, $baseDir = null ) {
+ if ( $baseDir ) {
+ $oldIP = $GLOBALS['IP'];
+ $GLOBALS['IP'] = $baseDir;
+ $teardown = new Wikimedia\ScopedCallback( function () use ( $oldIP ) {
+ $GLOBALS['IP'] = $oldIP;
+ } );
+ }
+
+ $this->assertEquals(
+ $expected,
+ ResourceLoaderSkinModule::getLogo( new HashConfig( $config ) )
+ );
+ }
+
+ public function provideGetLogo() {
+ return [
+ 'simple' => [
+ 'config' => [
+ 'ResourceBasePath' => '/w',
+ 'Logo' => '/img/default.png',
+ 'LogoHD' => false,
+ ],
+ 'expected' => '/img/default.png',
+ ],
+ 'default and 2x' => [
+ 'config' => [
+ 'ResourceBasePath' => '/w',
+ 'Logo' => '/img/default.png',
+ 'LogoHD' => [
+ '2x' => '/img/two-x.png',
+ ],
+ ],
+ 'expected' => [
+ '1x' => '/img/default.png',
+ '2x' => '/img/two-x.png',
+ ],
+ ],
+ 'default and all HiDPIs' => [
+ 'config' => [
+ 'ResourceBasePath' => '/w',
+ 'Logo' => '/img/default.png',
+ 'LogoHD' => [
+ '1.5x' => '/img/one-point-five.png',
+ '2x' => '/img/two-x.png',
+ ],
+ ],
+ 'expected' => [
+ '1x' => '/img/default.png',
+ '1.5x' => '/img/one-point-five.png',
+ '2x' => '/img/two-x.png',
+ ],
+ ],
+ 'default and SVG' => [
+ 'config' => [
+ 'ResourceBasePath' => '/w',
+ 'Logo' => '/img/default.png',
+ 'LogoHD' => [
+ 'svg' => '/img/vector.svg',
+ ],
+ ],
+ 'expected' => [
+ '1x' => '/img/default.png',
+ 'svg' => '/img/vector.svg',
+ ],
+ ],
+ 'everything' => [
+ 'config' => [
+ 'ResourceBasePath' => '/w',
+ 'Logo' => '/img/default.png',
+ 'LogoHD' => [
+ '1.5x' => '/img/one-point-five.png',
+ '2x' => '/img/two-x.png',
+ 'svg' => '/img/vector.svg',
+ ],
+ ],
+ 'expected' => [
+ '1x' => '/img/default.png',
+ 'svg' => '/img/vector.svg',
+ ],
+ ],
+ 'versioned url' => [
+ 'config' => [
+ 'ResourceBasePath' => '/w',
+ 'Logo' => '/w/test.jpg',
+ 'LogoHD' => false,
+ 'UploadPath' => '/w/images',
+ ],
+ 'expected' => '/w/test.jpg?edcf2',
+ 'baseDir' => dirname( dirname( __DIR__ ) ) . '/data/media',
+ ],
+ ];
+ }
}
[ 'fr', true, 'Two letters, minor case' ],
[ 'EN', false, 'Two letters, upper case' ],
[ 'tyv', true, 'Three letters' ],
- [ 'tokipona', true, 'long language code' ],
[ 'be-tarask', true, 'With dash' ],
[ 'be-x-old', true, 'With extension (two dashes)' ],
[ 'be_tarask', false, 'Reject underscores' ],