* WikiRevision::$fileIsTemp was deprecated.
* WikiRevision::$importer was deprecated.
* WikiRevision::$user was deprecated.
+* Article::getLastPurgeTimestamp(), WikiPage::getLastPurgeTimestamp(), and the
+ WikiPage::PURGE_* constants are deprecated, and the functions will always
+ return false. They were a hack for an issue that has since been fixed.
+* Hook 'EditPageBeforeEditChecks' is now deprecated. Instead use the new hook
+ 'EditPageGetCheckboxesDefinition', or 'EditPage::showStandardInputs:options'
+ if you don't actually care about checkboxes and just want to add some HTML
+ to the page.
+* Selflinks are now rendered as href-less <a> tags with the class mw-selflink
+ rather than <strong> tags. The old class name, "selflink", was deprecated
+ and will be removed in a future release. (T160480)
== Compatibility ==
'Wikimedia\\Rdbms\\Blob' => __DIR__ . '/includes/libs/rdbms/encasing/Blob.php',
'Wikimedia\\Rdbms\\ChronologyProtector' => __DIR__ . '/includes/libs/rdbms/ChronologyProtector.php',
'Wikimedia\\Rdbms\\ConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/ConnectionManager.php',
+ 'Wikimedia\\Rdbms\\DBConnRef' => __DIR__ . '/includes/libs/rdbms/database/DBConnRef.php',
'Wikimedia\\Rdbms\\DBMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBMasterPos.php',
'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/DatabaseDomain.php',
'Wikimedia\\Rdbms\\FakeResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php',
'Wikimedia\\Rdbms\\Field' => __DIR__ . '/includes/libs/rdbms/field/Field.php',
'Wikimedia\\Rdbms\\IBlob' => __DIR__ . '/includes/libs/rdbms/encasing/IBlob.php',
+ 'Wikimedia\\Rdbms\\IDatabase' => __DIR__ . '/includes/libs/rdbms/database/IDatabase.php',
'Wikimedia\\Rdbms\\ILBFactory' => __DIR__ . '/includes/libs/rdbms/lbfactory/ILBFactory.php',
'Wikimedia\\Rdbms\\ILoadBalancer' => __DIR__ . '/includes/libs/rdbms/loadbalancer/ILoadBalancer.php',
'Wikimedia\\Rdbms\\ILoadMonitor' => __DIR__ . '/includes/libs/rdbms/loadmonitor/ILoadMonitor.php',
+ 'Wikimedia\\Rdbms\\IMaintainableDatabase' => __DIR__ . '/includes/libs/rdbms/database/IMaintainableDatabase.php',
'Wikimedia\\Rdbms\\IResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/IResultWrapper.php',
'Wikimedia\\Rdbms\\LBFactory' => __DIR__ . '/includes/libs/rdbms/lbfactory/LBFactory.php',
'Wikimedia\\Rdbms\\LBFactoryMulti' => __DIR__ . '/includes/libs/rdbms/lbfactory/LBFactoryMulti.php',
'Wikimedia\\Rdbms\\LoadMonitor' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitor.php',
'Wikimedia\\Rdbms\\LoadMonitorMySQL' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php',
'Wikimedia\\Rdbms\\LoadMonitorNull' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php',
+ 'Wikimedia\\Rdbms\\MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
'Wikimedia\\Rdbms\\MssqlBlob' => __DIR__ . '/includes/libs/rdbms/encasing/MssqlBlob.php',
'Wikimedia\\Rdbms\\MssqlField' => __DIR__ . '/includes/libs/rdbms/field/MssqlField.php',
'Wikimedia\\Rdbms\\MssqlResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php',
"ext-xml": "*",
"liuggio/statsd-php-client": "1.0.18",
"mediawiki/at-ease": "1.1.0",
- "oojs/oojs-ui": "0.20.0",
+ "oojs/oojs-ui": "0.20.2",
"oyejorge/less.php": "1.7.0.13",
"php": ">=5.5.9",
"psr/log": "1.0.2",
"monolog/monolog": "~1.18.2",
"nikic/php-parser": "2.1.0",
"nmred/kafka-php": "0.1.5",
- "phpunit/phpunit": "4.8.31",
+ "phpunit/phpunit": "4.8.35",
"wikimedia/avro": "1.7.7",
"hamcrest/hamcrest-php": "^2.0",
"wmde/hamcrest-html-matchers": "^0.1.0",
- "psy/psysh": "0.8.1"
+ "psy/psysh": "0.8.3"
},
"suggest": {
"ext-apc": "Local data and opcode cache",
&$buttons: Array of edit buttons "Save", "Preview", "Live", and "Diff"
&$tabindex: HTML tabindex of the last edit check/button
-'EditPageBeforeEditChecks': Allows modifying the edit checks below the textarea
-in the edit form.
+'EditPageBeforeEditChecks': DEPRECATED! Use 'EditPageGetCheckboxesDefinition' instead,
+or 'EditPage::showStandardInputs:options' if you don't actually care about checkboxes
+and just want to add some HTML to the page.
+Allows modifying the edit checks below the textarea in the edit form.
&$editpage: The current EditPage object
-&$checks: Array of edit checks like "watch this page"/"minor edit"
+&$checks: Array of the HTML for edit checks like "watch this page"/"minor edit"
&$tabindex: HTML tabindex of the last edit check/button
'EditPageBeforeEditToolbar': Allows modifying the edit toolbar above the
&$msg: localization message name, overridable. Default is either
'copyrightwarning' or 'copyrightwarning2'.
+'EditPageGetCheckboxesDefinition': Allows modifying the edit checkboxes
+below the textarea in the edit form.
+$editpage: The current EditPage object
+&$checkboxes: Array of checkbox definitions. See EditPage::getCheckboxesDefinition()
+for the format.
+
'EditPageGetDiffContent': Allow modifying the wikitext that will be used in
"Show changes". Note that it is preferable to implement diff handling for
different data types using the ContentHandler facility.
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\MediaWikiServices;
class Block {
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* The "CategoryFinder" class takes a list of articles, creates an internal
* representation of all their parent categories (as well as parents of
require_once __DIR__ . '/libs/rdbms/defines.php';
require_once __DIR__ . '/compat/normal/UtfNormalDefines.php';
+use Wikimedia\Rdbms\IDatabase;
+
/**
* @defgroup Constants MediaWiki constants
*/
# Show log extract when the user is currently blocked
if ( $namespace == NS_USER || $namespace == NS_USER_TALK ) {
$username = explode( '/', $this->mTitle->getText(), 2 )[0];
- $user = User::newFromName( $username, false /* allow IP users*/ );
+ $user = User::newFromName( $username, false /* allow IP users */ );
$ip = User::isIP( $username );
$block = Block::newFromTarget( $user, $user );
if ( !( $user && $user->isLoggedIn() ) && !$ip ) { # User does not exist
return $toolbar;
}
+ /**
+ * Return an array of checkbox definitions.
+ *
+ * Array keys correspond to the `<input>` 'name' attribute to use for each checkbox.
+ *
+ * Array values are associative arrays with the following keys:
+ * - 'label-message' (required): message for label text
+ * - 'id' (required): 'id' attribute for the `<input>`
+ * - 'default' (required): default checkedness (true or false)
+ * - 'title-message' (optional): used to generate 'title' attribute for the `<label>`
+ * - 'tooltip' (optional): used to generate 'title' and 'accesskey' attributes
+ * from messages like 'tooltip-foo', 'accesskey-foo'
+ * - 'label-id' (optional): 'id' attribute for the `<label>`
+ * - 'legacy-name' (optional): short name for backwards-compatibility
+ * @param array $checked Array of checkbox name (matching the 'legacy-name') => bool,
+ * where bool indicates the checked status of the checkbox
+ * @return array
+ */
+ protected function getCheckboxesDefinition( $checked ) {
+ global $wgUser;
+ $checkboxes = [];
+
+ // don't show the minor edit checkbox if it's a new page or section
+ if ( !$this->isNew && $wgUser->isAllowed( 'minoredit' ) ) {
+ $checkboxes['wpMinoredit'] = [
+ 'id' => 'wpMinoredit',
+ 'label-message' => 'minoredit',
+ // Uses messages: tooltip-minoredit, accesskey-minoredit
+ 'tooltip' => 'minoredit',
+ 'label-id' => 'mw-editpage-minoredit',
+ 'legacy-name' => 'minor',
+ 'default' => $checked['minor'],
+ ];
+ }
+
+ if ( $wgUser->isLoggedIn() ) {
+ $checkboxes['wpWatchthis'] = [
+ 'id' => 'wpWatchthis',
+ 'label-message' => 'watchthis',
+ // Uses messages: tooltip-watch, accesskey-watch
+ 'tooltip' => 'watch',
+ 'label-id' => 'mw-editpage-watch',
+ 'legacy-name' => 'watch',
+ 'default' => $checked['watch'],
+ ];
+ }
+
+ $editPage = $this;
+ Hooks::run( 'EditPageGetCheckboxesDefinition', [ $editPage, &$checkboxes ] );
+
+ return $checkboxes;
+ }
+
/**
* Returns an array of html code of the following checkboxes:
* minor and watch
*
* @param int $tabindex Current tabindex
- * @param array $checked Array of checkbox => bool, where bool indicates the checked
- * status of the checkbox
- *
+ * @param array $checked See getCheckboxesDefinition()
* @return array
*/
public function getCheckboxes( &$tabindex, $checked ) {
- global $wgUser, $wgUseMediaWikiUIEverywhere;
+ global $wgUseMediaWikiUIEverywhere;
$checkboxes = [];
+ $checkboxesDef = $this->getCheckboxesDefinition( $checked );
- // don't show the minor edit checkbox if it's a new page or section
+ // Backwards-compatibility for the EditPageBeforeEditChecks hook
if ( !$this->isNew ) {
$checkboxes['minor'] = '';
- $minorLabel = $this->context->msg( 'minoredit' )->parse();
- if ( $wgUser->isAllowed( 'minoredit' ) ) {
- $attribs = [
- 'tabindex' => ++$tabindex,
- 'accesskey' => $this->context->msg( 'accesskey-minoredit' )->text(),
- 'id' => 'wpMinoredit',
- ];
- $minorEditHtml =
- Xml::check( 'wpMinoredit', $checked['minor'], $attribs ) .
- " <label for='wpMinoredit' id='mw-editpage-minoredit'" .
- Xml::expandAttributes( [ 'title' => Linker::titleAttrib( 'minoredit', 'withaccess' ) ] ) .
- ">{$minorLabel}</label>";
-
- if ( $wgUseMediaWikiUIEverywhere ) {
- $checkboxes['minor'] =
- Html::rawElement( 'div', [ 'class' => 'mw-ui-checkbox' ], $minorEditHtml );
- } else {
- $checkboxes['minor'] = $minorEditHtml;
- }
- }
}
-
- $watchLabel = $this->context->msg( 'watchthis' )->parse();
$checkboxes['watch'] = '';
- if ( $wgUser->isLoggedIn() ) {
+
+ foreach ( $checkboxesDef as $name => $options ) {
+ $legacyName = isset( $options['legacy-name'] ) ? $options['legacy-name'] : $name;
+ $label = $this->context->msg( $options['label-message'] )->parse();
$attribs = [
'tabindex' => ++$tabindex,
- 'accesskey' => $this->context->msg( 'accesskey-watch' )->text(),
- 'id' => 'wpWatchthis',
+ 'id' => $options['id'],
+ ];
+ $labelAttribs = [
+ 'for' => $options['id'],
];
- $watchThisHtml =
- Xml::check( 'wpWatchthis', $checked['watch'], $attribs ) .
- " <label for='wpWatchthis' id='mw-editpage-watch'" .
- Xml::expandAttributes( [ 'title' => Linker::titleAttrib( 'watch', 'withaccess' ) ] ) .
- ">{$watchLabel}</label>";
+ if ( isset( $options['tooltip'] ) ) {
+ $attribs['accesskey'] = $this->context->msg( "accesskey-{$options['tooltip']}" )->text();
+ $labelAttribs['title'] = Linker::titleAttrib( $options['tooltip'], 'withaccess' );
+ }
+ if ( isset( $options['title-message'] ) ) {
+ $labelAttribs['title'] = $this->context->msg( $options['title-message'] )->text();
+ }
+ if ( isset( $options['label-id'] ) ) {
+ $labelAttribs['id'] = $options['label-id'];
+ }
+ $checkboxHtml =
+ Xml::check( $name, $options['default'], $attribs ) .
+ ' ' .
+ Xml::tags( 'label', $labelAttribs, $label );
+
if ( $wgUseMediaWikiUIEverywhere ) {
- $checkboxes['watch'] =
- Html::rawElement( 'div', [ 'class' => 'mw-ui-checkbox' ], $watchThisHtml );
- } else {
- $checkboxes['watch'] = $watchThisHtml;
+ $checkboxHtml = Html::rawElement( 'div', [ 'class' => 'mw-ui-checkbox' ], $checkboxHtml );
}
+
+ $checkboxes[ $legacyName ] = $checkboxHtml;
}
// Avoid PHP 7.1 warning of passing $this by reference
$editPage = $this;
- Hooks::run( 'EditPageBeforeEditChecks', [ &$editPage, &$checkboxes, &$tabindex ] );
+ Hooks::run( 'EditPageBeforeEditChecks', [ &$editPage, &$checkboxes, &$tabindex ], '1.29' );
return $checkboxes;
}
}
/**
- * Make appropriate markup for a link to the current article. This is
- * currently rendered as the bold link text. The calling sequence is the
- * same as the other make*LinkObj static functions, despite $query not
- * being used.
+ * Make appropriate markup for a link to the current article. This is since
+ * MediaWiki 1.29.0 rendered as an <a> tag without an href and with a class
+ * showing the link text. The calling sequence is the same as for the other
+ * make*LinkObj static functions, but $query is not used.
*
* @since 1.16.3
* @param Title $nt
* @return string
*/
public static function makeSelfLinkObj( $nt, $html = '', $query = '', $trail = '', $prefix = '' ) {
- $ret = "<strong class=\"selflink\">{$prefix}{$html}</strong>{$trail}";
+ $ret = "<a class=\"mw-selflink selflink\">{$prefix}{$html}</a>{$trail}";
if ( !Hooks::run( 'SelfLinkBegin', [ $nt, &$html, &$trail, &$prefix, &$ret ] ) ) {
return $ret;
}
$html = htmlspecialchars( $nt->getPrefixedText() );
}
list( $inside, $trail ) = self::splitTrail( $trail );
- return "<strong class=\"selflink\">{$prefix}{$html}{$inside}</strong>{$trail}";
+ return "<a class=\"mw-selflink selflink\">{$prefix}{$html}{$inside}</a>{$trail}";
}
/**
*/
use MediaWiki\Logger\LoggerFactory;
+use Psr\Log\LoggerInterface;
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ChronologyProtector;
use Wikimedia\Rdbms\LBFactory;
$n = intval( $jobRunRate );
}
- $runJobsLogger = LoggerFactory::getInstance( 'runJobs' );
+ $logger = LoggerFactory::getInstance( 'runJobs' );
- // Fall back to running the job(s) while the user waits if needed
- if ( !$this->config->get( 'RunJobsAsync' ) ) {
- $runner = new JobRunner( $runJobsLogger );
- $runner->run( [ 'maxJobs' => $n ] );
- return;
- }
-
- // Do not send request if there are probably no jobs
try {
- $group = JobQueueGroup::singleton();
- if ( !$group->queuesHaveJobs( JobQueueGroup::TYPE_DEFAULT ) ) {
- return;
+ if ( $this->config->get( 'RunJobsAsync' ) ) {
+ // Send an HTTP request to the job RPC entry point if possible
+ $invokedWithSuccess = $this->triggerAsyncJobs( $n, $logger );
+ if ( !$invokedWithSuccess ) {
+ // Fall back to blocking on running the job(s)
+ $logger->warning( "Jobs switched to blocking; Special:RunJobs disabled" );
+ $this->triggerSyncJobs( $n, $logger );
+ }
+ } else {
+ $this->triggerSyncJobs( $n, $logger );
}
} catch ( JobQueueError $e ) {
+ // Do not make the site unavailable (T88312)
MWExceptionHandler::logException( $e );
- return; // do not make the site unavailable
+ }
+ }
+
+ /**
+ * @param integer $n Number of jobs to try to run
+ * @param LoggerInterface $runJobsLogger
+ */
+ private function triggerSyncJobs( $n, LoggerInterface $runJobsLogger ) {
+ $runner = new JobRunner( $runJobsLogger );
+ $runner->run( [ 'maxJobs' => $n ] );
+ }
+
+ /**
+ * @param integer $n Number of jobs to try to run
+ * @param LoggerInterface $runJobsLogger
+ * @return bool Success
+ */
+ private function triggerAsyncJobs( $n, LoggerInterface $runJobsLogger ) {
+ // Do not send request if there are probably no jobs
+ $group = JobQueueGroup::singleton();
+ if ( !$group->queuesHaveJobs( JobQueueGroup::TYPE_DEFAULT ) ) {
+ return true;
}
$query = [ 'title' => 'Special:RunJobs',
$runJobsLogger->error( "Failed to start cron API (socket error $errno): $errstr" );
}
- // Fall back to running the job(s) while the user waits if needed
- if ( !$invokedWithSuccess ) {
- $runJobsLogger->warning( "Jobs switched to blocking; Special:RunJobs disabled" );
-
- $runner = new JobRunner( $runJobsLogger );
- $runner->run( [ 'maxJobs' => $n ] );
- }
+ return $invokedWithSuccess;
}
}
* @file
*/
use Wikimedia\Timestamp\TimestampException;
+use Wikimedia\Rdbms\IDatabase;
/**
* Handles the backend logic of merging the histories of two
*
* @file
*/
+
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ResultWrapper;
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* List for revision table items for a single page
/** @var ResultWrapper|bool */
protected $res;
- /** @var bool|object */
+ /** @var bool|Revision */
protected $current;
/**
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Static accessor class for site_stats and related things
*/
*
* @file
*/
+
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\Interwiki\InterwikiLookup;
use MediaWiki\MediaWikiServices;
$row = $db->selectRow( 'revision', Revision::selectFields(),
[ 'rev_page' => $pageId ],
__METHOD__,
- [ 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 ]
+ [
+ 'ORDER BY' => 'rev_timestamp ASC',
+ 'IGNORE INDEX' => 'rev_timestamp'
+ ]
);
if ( $row ) {
return new Revision( $row );
<?php
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\Linker\LinkTarget;
use Wikimedia\Assert\Assert;
use Wikimedia\Rdbms\LoadBalancer;
<?php
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Extension mechanism for WatchedItemQueryService
<?php
+use Wikimedia\Rdbms\IDatabase;
use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
}
public function onSubmit( $data ) {
- return $this->page->doPurge( WikiPage::PURGE_ALL );
+ return $this->page->doPurge();
}
public function show() {
$touched = null;
}
- // If a page was purged on HTTP GET, relect that timestamp to avoid sending 304s
- $touched = max( $touched, $this->page->getLastPurgeTimestamp() );
-
// Send HTTP 304 if the IMS matches or otherwise set expiry/last-modified headers
if ( $touched && $this->getOutput()->checkLastModified( $touched ) ) {
wfDebug( __METHOD__ . ": done 304\n" );
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* This abstract class implements many basic API functions, and is the base of
* all API classes.
*/
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* This class contains a list of pages that the client has requested.
$page = WikiPage::factory( $title );
if ( !$user->pingLimiter( 'purge' ) ) {
// Directly purge and skip the UI part of purge()
- $page->doPurge( WikiPage::PURGE_ALL );
+ $page->doPurge();
$r['purged'] = true;
} else {
$this->addWarning( 'apierror-ratelimited' );
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Query module to enumerate all available pages.
*
$db = $this->getDB();
$params = $this->extractRequestParams();
+ $userId = !is_null( $params['user'] ) ? User::idFromName( $params['user'] ) : null;
// Table and return fields
$this->addTables( 'image' );
// Image filters
if ( !is_null( $params['user'] ) ) {
- $this->addWhereFld( 'img_user_text', $params['user'] );
+ if ( $userId ) {
+ $this->addWhereFld( 'img_user', $userId );
+ } else {
+ $this->addWhereFld( 'img_user_text', $params['user'] );
+ }
}
if ( $params['filterbots'] != 'all' ) {
$this->addTables( 'user_groups' );
if ( $params['sort'] == 'timestamp' ) {
$this->addOption( 'ORDER BY', 'img_timestamp' . $sortFlag );
if ( !is_null( $params['user'] ) ) {
- $this->addOption( 'USE INDEX', [ 'image' => 'img_usertext_timestamp' ] );
+ if ( $userId ) {
+ $this->addOption( 'USE INDEX', [ 'image' => 'img_user_timestamp' ] );
+ } else {
+ $this->addOption( 'USE INDEX', [ 'image' => 'img_usertext_timestamp' ] );
+ }
} else {
$this->addOption( 'USE INDEX', [ 'image' => 'img_timestamp' ] );
}
"apihelp-query+recentchanges-paramvalue-prop-timestamp": "Ajoute l’horodatage de la modification.",
"apihelp-query+recentchanges-paramvalue-prop-title": "Ajoute le titre de la page modifiée.",
"apihelp-query+recentchanges-paramvalue-prop-ids": "Ajoute l’ID de la page, l’ID des modifications récentes et l’ID de l’ancienne et la nouvelle révisions.",
- "apihelp-query+recentchanges-paramvalue-prop-sizes": "Ajoute l’ancienne et la nouvelle tailles de la page en octets.",
+ "apihelp-query+recentchanges-paramvalue-prop-sizes": "Ajoute l’ancienne et la nouvelle taille de la page en octets.",
"apihelp-query+recentchanges-paramvalue-prop-redirect": "Marque la modification si la page est une redirection.",
"apihelp-query+recentchanges-paramvalue-prop-patrolled": "Marque les modifications patrouillables comme patrouillées ou non.",
"apihelp-query+recentchanges-paramvalue-prop-loginfo": "Ajoute les informations du journal (Id du journal, type de trace, etc.) aux entrées du journal.",
"apihelp-delete-param-watch": "문서를 현재 사용자의 주시문서 목록에 추가합니다.",
"apihelp-delete-param-unwatch": "문서를 현재 사용자의 주시문서 목록에서 제거합니다.",
"apihelp-delete-example-simple": "<kbd>Main Page</kbd>를 삭제합니다.",
+ "apihelp-delete-example-reason": "<kbd>Preparing for move</kbd> 라는 이유로 <kbd>Main Page</kbd>를 삭제하기.",
"apihelp-disabled-description": "이 모듈은 해제되었습니다.",
"apihelp-edit-description": "문서를 만들고 편집합니다.",
+ "apihelp-edit-param-title": "편집할 문서의 제목. <var>$1pageid</var>과 같이 사용할 수 없습니다.",
"apihelp-edit-param-section": "문단 번호입니다. <kbd>0</kbd>은 최상위 문단, <kbd>new</kbd>는 새 문단입니다.",
"apihelp-edit-param-sectiontitle": "새 문단을 위한 제목.",
"apihelp-edit-param-text": "문서 내용.",
"Caçador de Palavras",
"LucyDiniz",
"Eduardo Addad de Oliveira",
- "Warley Felipe C."
+ "Warley Felipe C.",
+ "TheEduGobi"
]
},
"apihelp-main-param-action": "Qual ação executar.",
"apihelp-main-param-requestid": "Qualquer valor dado aqui será incluído na resposta. Pode ser usado para distinguir requisições.",
"apihelp-main-param-servedby": "Inclua o nome de host que atendeu a solicitação nos resultados.",
"apihelp-main-param-curtimestamp": "Inclui a data atual no resultado.",
+ "apihelp-main-param-origin": "Ao acessar a API usando uma solicitação AJAX por domínio cruzado (CORS), defina isto como o domínio de origem. Isto deve estar incluso em toda solicitação ''pre-flight'', sendo portanto parte do URI da solicitação (ao invés do corpo do POST).\n\nPara solicitações autenticadas, isto deve corresponder a uma das origens no cabeçalho <code>Origin</code>, para que seja algo como <kbd>https://pt.wikipedia.org</kbd> ou <kbd>https://meta.wikimedia.org</kbd>. Se este parâmetro não corresponder ao cabeçalho <code>Origin</code>, uma resposta 403 será retornada. Se este parâmetro corresponder ao cabeçalho <code>Origin</code> e a origem for permitida (''whitelisted''), os cabeçalhos <code>Access-Control-Allow-Origin</code> e <code>Access-Control-Allow-Credentials</code> serão definidos.\n\nPara solicitações não autenticadas, especifique o valor <kbd>*</kbd>. Isto fará com que o cabeçalho <code>Access-Control-Allow-Origin</code> seja definido, porém o <code>Access-Control-Allow-Credentials</code> será <code>false</code> e todos os dados específicos para usuários tornar-se-ão restritos.",
"apihelp-block-description": "Bloquear um usuário",
"apihelp-block-param-user": "Nome de usuário, endereço IP ou faixa de IP para bloquear.",
"apihelp-block-param-reason": "Razão do bloqueio.",
"apihelp-feedcontributions-param-newonly": "Mostrar somente as edições que são criação de páginas.",
"apihelp-feedcontributions-param-hideminor": "Ocultar edições menores.",
"apihelp-feedcontributions-param-showsizediff": "Mostrar a diferença de tamanho entre as revisões.",
- "apihelp-feedrecentchanges-description": "Retorna um feed de alterações recentes.",
+ "apihelp-feedrecentchanges-description": "Retorna um ''feed'' de mudanças recentes.",
"apihelp-feedrecentchanges-param-feedformat": "O formato do feed.",
"apihelp-feedrecentchanges-param-namespace": "Espaço nominal a partir do qual limitar resultados.",
"apihelp-feedrecentchanges-param-invert": "Todos os espaços nominais, exceto o selecionado.",
"apihelp-feedrecentchanges-param-hidecategorization": "Alterações de membros pertencentes à uma categoria.",
"apihelp-feedrecentchanges-param-tagfilter": "Filtrar por tag.",
"apihelp-feedrecentchanges-example-simple": "Mostrar as mudanças recentes.",
- "apihelp-feedrecentchanges-example-30days": "Mostrar as alterações recentes por 30 dias.",
+ "apihelp-feedrecentchanges-example-30days": "Mostrar as mudanças recentes por 30 dias.",
"apihelp-feedwatchlist-description": "Retornar um feed da lista de vigiados.",
"apihelp-feedwatchlist-param-feedformat": "O formato do feed.",
"apihelp-feedwatchlist-param-hours": "Lista páginas modificadas dentro dessa quantia de horas a partir de agora.",
"apihelp-query+protectedtitles-example-simple": "Lista skyddade titlar.",
"apihelp-query+recentchanges-example-simple": "Lista de senaste ändringarna.",
"apihelp-query+revisions-example-first5-not-localhost": "Hämta första 5 revideringarna av \"huvudsidan\" och som inte gjorts av anonym användare \"127.0.0.1\"",
+ "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "Returnerar en lista över språkkoder som [[mw:LanguageConverter|LanguageConverter]] har aktiverat och de varianter som varje stöder.",
"apihelp-query+siteinfo-example-simple": "Hämta information om webbplatsen.",
"apihelp-query+stashimageinfo-description": "Returnerar filinformation för temporära filer.",
"apihelp-query+stashimageinfo-param-filekey": "Nyckel som identifierar en tidigare uppladdning som lagrats temporärt.",
use Wikimedia\Rdbms\ResultWrapper;
use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Class for fetching backlink lists, approximate backlink counts and
use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Class representing a list of titles
* @file
* @ingroup Cache
*/
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* LCStore implementation which uses the standard DB functions to store data.
* This will work on any MediaWiki installation.
* @author Matthew Flaschen
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* An individual filter in a boolean group
*
* @author Matthew Flaschen
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Represents a filter group with multiple string options. They are passed to the server as
* a single form parameter separated by a delimiter. The parameter name is the
$className = 'ChangeTagsLogList';
break;
default:
- throw new Exception( "Class $className requested, but does not exist" );
+ throw new Exception( "Class $typeName requested, but does not exist" );
}
+
return new $className( $context, $title, $ids );
}
* @ingroup Change tagging
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Stores a list of taggable log entries.
* @since 1.25
* @ingroup Change tagging
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Stores a list of taggable revisions.
* @since 1.25
* @ingroup Database
*/
use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IMaintainableDatabase;
class CloneDatabase {
/** @var string Table prefix for cloning */
<?php
+use Wikimedia\Rdbms\IDatabase;
+
/**
* The oci8 extension is fairly weak and doesn't support oci_num_rows, among
* other things. We use a wrapper class to handle that and other
<?php
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Deferrable Update for closure/callback updates via IDatabase::doAtomicSection()
* @since 1.27
<?php
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Deferrable Update for closure/callback updates that should use auto-commit mode
* @since 1.28
*
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\LBFactory;
use Wikimedia\Rdbms\LoadBalancer;
*/
use MediaWiki\MediaWikiServices;
use Wikimedia\ScopedCallback;
+use Wikimedia\Rdbms\IDatabase;
/**
* Update object handling the cleanup of links tables after a page was deleted.
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\MediaWikiServices;
use Wikimedia\ScopedCallback;
<?php
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Deferrable Update for closure/callback
*/
*/
use MediaWiki\MediaWikiServices;
use Wikimedia\Assert\Assert;
+use Wikimedia\Rdbms\IDatabase;
/**
* Class for handling updates to the site_stats table
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* @deprecated Since 1.28 Use DataUpdate directly, injecting the database
*/
<?php
use Psr\Log\LoggerInterface;
+use Wikimedia\Rdbms\IDatabase;
/**
* Class for fixing stale WANObjectCache keys using a purge event source
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* @ingroup SpecialPage Dump
*/
use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\DBConnRef;
+use Wikimedia\Rdbms\MaintainableDBConnRef;
/**
* DB accessable external objects.
*/
use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
/**
* Version of FileJournal that logs to a DB table
<?php
+
+use Wikimedia\Rdbms\IDatabase;
+
/**
* MySQL version of DBLockManager that supports shared locks.
*
* @author Aaron Schulz
*/
+use Wikimedia\Rdbms\DBConnRef;
+use Wikimedia\Rdbms\MaintainableDBConnRef;
+
/**
* @brief Proxy backend that manages file layout rewriting for FileRepo.
*
* @ingroup FileRepo
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* A foreign repository with an accessible MediaWiki database
*
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* A repository that stores files in the local filesystem and registers them
*/
use \MediaWiki\Logger\LoggerFactory;
+use Wikimedia\Rdbms\IDatabase;
/**
* Class to represent a local file in the wiki's own database
}
}
- if ( $foundRelativeURI ) {
- if ( $domain ) {
- return $domain . $locations[$countLocations - 1];
- } else {
- $url = parse_url( $this->url );
- if ( isset( $url['host'] ) ) {
- return $url['scheme'] . '://' . $url['host'] .
- $locations[$countLocations - 1];
- }
- }
- } else {
+ if ( !$foundRelativeURI ) {
return $locations[$countLocations - 1];
}
+ if ( $domain ) {
+ return $domain . $locations[$countLocations - 1];
+ }
+ $url = parse_url( $this->url );
+ if ( isset( $url['host'] ) ) {
+ return $url['scheme'] . '://' . $url['host'] .
+ $locations[$countLocations - 1];
+ }
}
return $this->url;
* @ingroup Deployment
*/
use Wikimedia\Rdbms\LBFactorySingle;
+use Wikimedia\Rdbms\IDatabase;
/**
* Base class for DBMS-specific installation helper classes.
* @file
* @ingroup Deployment
*/
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\MediaWikiServices;
require_once __DIR__ . '/../../maintenance/Maintenance.php';
"config-type-mssql": "Microsoft SQL Server",
"config-support-info": "Skoret eo ar reizhiadoù diaz titouroù da-heul gant MediaWiki :\n\n$1\n\nMa ne welit ket amañ dindan ar reizhiad diaz titouroù a fell deoc'h ober ganti, heuilhit an titouroù a-us (s.o. al liammoù) evit gweredekaat ar skorañ.",
"config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] eo an dibab kentañ evit MediaWiki hag an hini skoret ar gwellañ. Mont a ra MediaWiki en-dro gant [{{int:version-db-mariadb-url}} MariaDB] ha [{{int:version-db-percona-url}} Percona Server] ivez, kenglotus o-daou gant MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Penaos kempunañ PHP gant skor MySQL])",
- "config-dbsupport-postgres": "* Ur reizhiad diaz titouroù brudet ha digor eo $1. Gallout a ra ober evit MySQL ([http://www.php.net/manual/en/pgsql.installation.php Penaos kempunañ PHP gant skor PostgreSQL]). Gallout a ra bezañ un nebeud drein bihan enni ha n'eo ket erbedet he implijout en un endro produiñ.",
- "config-dbsupport-sqlite": "* $1 zo ur reizhiad diaz titouroù skañv skoret eus ar c'hentañ. ([http://www.php.net/manual/en/pdo.installation.php Penaos kempunañ PHP gant skor SQLite], implijout a ra PDO)",
+ "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] zo anezhi ur reizhiad diaz roadennoù frank a wirioù brudet-mat a c'haller ober gantañ e plas MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Penaos kempunañ PHP gant skor PostgreSQL])",
+ "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] zo anezhi ur reizhiad diaz roadennoù skañv skoret eus ar c'hentañ. ([http://www.php.net/manual/en/pdo.installation.php Penaos kempunañ PHP gant skor SQLite], implijout a ra PDO)",
"config-dbsupport-oracle": "* $1 zo un diaz titouroù kenwerzhel. ([http://www.php.net/manual/en/oci8.installation.php Penaos kempunañ PHP gant skor OCI8])",
"config-header-mysql": "Arventennoù MySQL",
"config-header-postgres": "Arventennoù PostgreSQL",
* @file
* @author Aaron Schulz
*/
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\MediaWikiServices;
use Wikimedia\ScopedCallback;
+use Wikimedia\Rdbms\DBConnRef;
/**
* Class to handle job queues stored in the DB
*
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\MediaWikiServices;
class PurgeJobUtils {
* @ingroup LockManager
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Version of LockManager based on using named/row DB locks.
*
namespace Wikimedia\Rdbms;
use Database;
-use DBConnRef;
-use IDatabase;
use InvalidArgumentException;
/**
namespace Wikimedia\Rdbms;
use Database;
-use DBConnRef;
/**
* Database connection manager.
<?php
-use Wikimedia\Rdbms\DatabaseDomain;
-use Wikimedia\Rdbms\ILoadBalancer;
-use Wikimedia\Rdbms\DBMasterPos;
+namespace Wikimedia\Rdbms;
+
+use Database;
+use InvalidArgumentException;
/**
* Helper class to handle automatically marking connections as reusable (via RAII pattern)
}
}
}
+
+class_alias( 'Wikimedia\Rdbms\DBConnRef', 'DBConnRef' );
use Wikimedia\Rdbms\DBMasterPos;
use Wikimedia\Rdbms\Blob;
use Wikimedia\Timestamp\ConvertibleTimestamp;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\IMaintainableDatabase;
/**
* Relational database abstraction object
}
$class = 'Database' . ucfirst( $driver );
- if ( class_exists( $class ) && is_subclass_of( $class, 'IDatabase' ) ) {
+ if ( class_exists( $class ) && is_subclass_of( $class, IDatabase::class ) ) {
// Resolve some defaults for b/c
$p['host'] = isset( $p['host'] ) ? $p['host'] : false;
$p['user'] = isset( $p['user'] ) ? $p['user'] : false;
* @return string
*/
protected function indexName( $index ) {
- return $index;
+ // Backwards-compatibility hack
+ $renamed = [
+ 'ar_usertext_timestamp' => 'usertext_timestamp',
+ 'un_user_id' => 'user_id',
+ 'un_user_ip' => 'user_ip',
+ ];
+
+ if ( isset( $renamed[$index] ) ) {
+ return $renamed[$index];
+ } else {
+ return $index;
+ }
}
public function addQuotes( $s ) {
return str_replace( '"', '', parent::tableName( $name, $format ) );
}
+ /**
+ * Index names have DB scope
+ *
+ * @param string $index
+ * @return string
+ */
+ protected function indexName( $index ) {
+ return $index;
+ }
+
/**
* This must be called after nextSequenceVal
*
* @file
* @ingroup Database
*/
+namespace Wikimedia\Rdbms;
+
use Wikimedia\ScopedCallback;
-use Wikimedia\Rdbms\Blob;
-use Wikimedia\Rdbms\LikeMatch;
-use Wikimedia\Rdbms\DBMasterPos;
-use Wikimedia\Rdbms\Field;
-use Wikimedia\Rdbms\IResultWrapper;
+use DBError;
+use DBConnectionError;
+use DBUnexpectedError;
+use DBQueryError;
+use Exception;
+use RuntimeException;
+use UnexpectedValueException;
+use stdClass;
/**
* Basic database interface for live and lazy-loaded relation database handles
*/
public function setTableAliases( array $aliases );
}
+
+class_alias( 'Wikimedia\Rdbms\IDatabase', 'IDatabase' );
* @file
* @ingroup Database
*/
+namespace Wikimedia\Rdbms;
+
+use Exception;
+use RuntimeException;
+use DBUnexpectedError;
/**
* Advanced database interface for IDatabase handles that include maintenance methods
$oldName, $newName, $temporary = false, $fname = __METHOD__
);
}
+
+class_alias( 'Wikimedia\Rdbms\IMaintainableDatabase', 'IMaintainableDatabase' );
<?php
+
+namespace Wikimedia\Rdbms;
+
/**
* Helper class to handle automatically marking connections as reusable (via RAII pattern)
* as well handling deferring the actual network connection until the handle is used
return $this->__call( __FUNCTION__, func_get_args() );
}
}
+
+class_alias( 'Wikimedia\Rdbms\MaintainableDBConnRef', 'MaintainableDBConnRef' );
namespace Wikimedia\Rdbms;
-use IDatabase;
use stdClass;
use RuntimeException;
<?php
use Wikimedia\Rdbms\ILoadBalancer;
+use Wikimedia\Rdbms\IDatabase;
/**@{
* Database related constants
* @file
* @ingroup Database
*/
+use Wikimedia\Rdbms\IDatabase;
/**
* @ingroup Database
* @file
* @ingroup Database
*/
+use Wikimedia\Rdbms\IDatabase;
/**
* Database error base class
* @file
* @ingroup Database
*/
+use Wikimedia\Rdbms\IDatabase;
/**
* Base class for the more common types of database errors. These are known to occur
* @file
* @ingroup Database
*/
+use Wikimedia\Rdbms\IDatabase;
/**
* @ingroup Database
use WANObjectCache;
use Exception;
use RuntimeException;
-use IDatabase;
use DBTransactionError;
use DBReplicationWaitError;
'errorLogger' => $this->errorLogger,
'hostname' => $this->hostname,
'cliMode' => $this->cliMode,
- 'agent' => $this->agent
+ 'agent' => $this->agent,
+ 'chronologyProtector' => $this->getChronologyProtector()
];
}
namespace Wikimedia\Rdbms;
-use IDatabase;
use InvalidArgumentException;
/**
public function getMainLB( $domain = false ) {
$section = $this->getSectionForDomain( $domain );
if ( !isset( $this->mainLBs[$section] ) ) {
- $lb = $this->newMainLB( $domain );
- $this->getChronologyProtector()->initLB( $lb );
- $this->mainLBs[$section] = $lb;
+ $this->mainLBs[$section] = $this->newMainLB( $domain );
}
return $this->mainLBs[$section];
public function getExternalLB( $cluster ) {
if ( !isset( $this->extLBs[$cluster] ) ) {
$this->extLBs[$cluster] = $this->newExternalLB( $cluster );
- $this->getChronologyProtector()->initLB( $this->extLBs[$cluster] );
}
return $this->extLBs[$cluster];
public function getMainLB( $domain = false ) {
if ( !isset( $this->mainLB ) ) {
$this->mainLB = $this->newMainLB( $domain );
- $this->getChronologyProtector()->initLB( $this->mainLB );
}
return $this->mainLB;
public function getExternalLB( $cluster ) {
if ( !isset( $this->extLBs[$cluster] ) ) {
$this->extLBs[$cluster] = $this->newExternalLB( $cluster );
- $this->getChronologyProtector()->initLB( $this->extLBs[$cluster] );
}
return $this->extLBs[$cluster];
namespace Wikimedia\Rdbms;
-use IDatabase;
use InvalidArgumentException;
use BadMethodCallException;
*/
namespace Wikimedia\Rdbms;
-use IDatabase;
use Database;
-use DBConnRef;
-use MaintainableDBConnRef;
use DBError;
use DBAccessError;
use DBTransactionError;
* - srvCache : BagOStuff object for server cache [optional]
* - memCache : BagOStuff object for cluster memory cache [optional]
* - wanCache : WANObjectCache object [optional]
+ * - chronologyProtector: ChronologyProtector object [optional]
* - hostname : The name of the current server [optional]
* - cliMode: Whether the execution context is a CLI script. [optional]
* - profiler : Class name or instance with profileIn()/profileOut() methods. [optional]
* If a DB_REPLICA connection has been opened already, then wait immediately.
* Otherwise sets a variable telling it to wait if such a connection is opened.
*
- * @param DBMasterPos $pos
+ * @param DBMasterPos|bool $pos Master position or false
*/
public function waitFor( $pos );
*
* This can be used a faster proxy for waitForAll()
*
- * @param DBMasterPos $pos
+ * @param DBMasterPos|bool $pos Master position or false
* @param int $timeout Max seconds to wait; default is mWaitTimeout
* @return bool Success (able to connect and no timeouts reached)
*/
/**
* Set the master wait position and wait for ALL replica DBs to catch up to it
*
- * @param DBMasterPos $pos
+ * @param DBMasterPos|bool $pos Master position or false
* @param int $timeout Max seconds to wait; default is mWaitTimeout
* @return bool Success (able to connect and no timeouts reached)
*/
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Wikimedia\ScopedCallback;
-use IDatabase;
use Database;
-use DBConnRef;
-use MaintainableDBConnRef;
use BagOStuff;
use EmptyBagOStuff;
use WANObjectCache;
/** @var ILoadMonitor */
private $loadMonitor;
+ /** @var ChronologyProtector|null */
+ private $chronProt;
/** @var BagOStuff */
private $srvCache;
/** @var BagOStuff */
/** @var boolean */
private $disabled = false;
+ /** @var boolean */
+ private $chronProtInitialized = false;
/** @var integer Warn when this many connection are held */
const CONN_HELD_WARN_THRESHOLD = 10;
: ( gethostname() ?: 'unknown' );
$this->cliMode = isset( $params['cliMode'] ) ? $params['cliMode'] : PHP_SAPI === 'cli';
$this->agent = isset( $params['agent'] ) ? $params['agent'] : '';
+
+ if ( isset( $params['chronologyProtector'] ) ) {
+ $this->chronProt = $params['chronologyProtector'];
+ }
}
/**
return $i;
}
- /**
- * @param DBMasterPos|false $pos
- */
public function waitFor( $pos ) {
+ $oldPos = $this->mWaitForPos;
$this->mWaitForPos = $pos;
- $i = $this->mReadIndex;
+ // If a generic reader connection was already established, then wait now
+ $i = $this->mReadIndex;
if ( $i > 0 ) {
if ( !$this->doWait( $i ) ) {
$this->laggedReplicaMode = true;
}
}
+
+ // Restore the older position if it was higher
+ $this->setWaitForPositionIfHigher( $oldPos );
}
public function waitForOne( $pos, $timeout = null ) {
+ $oldPos = $this->mWaitForPos;
$this->mWaitForPos = $pos;
$i = $this->mReadIndex;
$ok = true; // no applicable loads
}
+ // Restore the older position if it was higher
+ $this->setWaitForPositionIfHigher( $oldPos );
+
return $ok;
}
public function waitForAll( $pos, $timeout = null ) {
+ $oldPos = $this->mWaitForPos;
$this->mWaitForPos = $pos;
$serverCount = count( $this->mServers );
}
}
+ // Restore the older position if it was higher
+ $this->setWaitForPositionIfHigher( $oldPos );
+
return $ok;
}
+ /**
+ * @param DBMasterPos|bool $pos
+ */
+ private function setWaitForPositionIfHigher( $pos ) {
+ if ( !$pos ) {
+ return;
+ }
+
+ if ( !$this->mWaitForPos || $pos->hasReached( $this->mWaitForPos ) ) {
+ $this->mWaitForPos = $pos;
+ }
+ }
+
/**
* @param int $i
* @return IDatabase|bool
$domain = false; // local connection requested
}
+ if ( !$this->chronProtInitialized && $this->chronProt ) {
+ $this->connLogger->debug( __METHOD__ . ': calling initLB() before first connection.' );
+ // Load CP positions before connecting so that doWait() triggers later if needed
+ $this->chronProtInitialized = true;
+ $this->chronProt->initLB( $this );
+ }
+
if ( $domain !== false ) {
$conn = $this->openForeignConnection( $i, $domain );
} elseif ( isset( $this->mConns['local'][$i][0] ) ) {
namespace Wikimedia\Rdbms;
-use IDatabase;
use InvalidArgumentException;
/**
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Wikimedia\ScopedCallback;
-use IDatabase;
use BagOStuff;
/**
namespace Wikimedia\Rdbms;
-use IDatabase;
use BagOStuff;
/**
* @since 1.19
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Interface for log entries. Every log entry has these methods.
*
*/
use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
class LogEventsList extends ContextSource {
const NO_ACTION_LINK = 1;
case '2#025': /* keywords */
$data['Keywords'] = self::convIPTC( $val, $c );
break;
- case '2#101': /* Country (shown)*/
+ case '2#101': /* Country (shown) */
$data['CountryDest'] = self::convIPTC( $val, $c );
break;
case '2#095': /* state/province (shown) */
case '2#040': /* special instructions */
$data['SpecialInstructions'] = self::convIPTC( $val, $c );
break;
- case '2#105': /* headline*/
+ case '2#105': /* headline */
$data['Headline'] = self::convIPTC( $val, $c );
break;
case '2#110': /* credit */
* @ingroup Cache
*/
+use Wikimedia\Rdbms\IDatabase;
use \MediaWiki\MediaWikiServices;
use \Wikimedia\WaitConditionLoop;
use \Wikimedia\Rdbms\TransactionProfiler;
|| $title->getNamespace() == NS_USER_TALK
) {
$rootPart = explode( '/', $title->getText() )[0];
- $user = User::newFromName( $rootPart, false /* allow IP users*/ );
+ $user = User::newFromName( $rootPart, false /* allow IP users */ );
$ip = User::isIP( $rootPart );
$block = Block::newFromTarget( $user, $user );
/**
* Call to WikiPage function for backwards compatibility.
* @see WikiPage::doPurge
+ * @note In 1.28 (and only 1.28), this took a $flags parameter that
+ * controlled how much purging was done.
*/
- public function doPurge( $flags = WikiPage::PURGE_ALL ) {
- return $this->mPage->doPurge( $flags );
+ public function doPurge() {
+ 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();
}
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Used to show archived pages and eventually restore them.
return $this->mDupes;
}
- public function doPurge( $flags = self::PURGE_ALL ) {
+ /**
+ * Override handling of action=purge
+ * @return bool
+ */
+ public function doPurge() {
$this->loadFile();
-
if ( $this->mFile->exists() ) {
wfDebug( 'ImagePage::doPurge purging ' . $this->mFile->getName() . "\n" );
DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->mTitle, 'imagelinks' ) );
// Purge redirect cache
$this->mRepo->invalidateImageRedirect( $this->mTitle );
}
-
- return parent::doPurge( $flags );
+ return parent::doPurge();
}
/**
use \MediaWiki\Logger\LoggerFactory;
use \MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Class representing a MediaWiki article and history.
*/
protected $mLinksUpdated = '19700101000000';
- const PURGE_CDN_CACHE = 1; // purge CDN cache for page variant URLs
- const PURGE_CLUSTER_PCACHE = 2; // purge parser cache in the local datacenter
- const PURGE_GLOBAL_PCACHE = 4; // set page_touched to clear parser cache in all datacenters
+ /** @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;
/**
* @return Revision|null
*/
public function getOldestRevision() {
-
// Try using the replica DB first, then try the master
- $continue = 2;
- $db = wfGetDB( DB_REPLICA );
- $revSelectFields = Revision::selectFields();
-
- $row = null;
- while ( $continue ) {
- $row = $db->selectRow(
- [ 'revision' ],
- $revSelectFields,
- [
- 'rev_page' => $this->getId()
- ],
- __METHOD__,
- [
- 'ORDER BY' => 'rev_timestamp ASC'
- ]
- );
-
- if ( $row ) {
- $continue = 0;
- } else {
- $db = wfGetDB( DB_MASTER );
- $continue--;
- }
+ $rev = $this->mTitle->getFirstRevision();
+ if ( !$rev ) {
+ $rev = $this->mTitle->getFirstRevision( Title::GAID_FOR_UPDATE );
}
-
- return $row ? Revision::newFromRow( $row ) : null;
+ return $rev;
}
/**
/**
* Perform the actions of a page purging
- * @param integer $flags Bitfield of WikiPage::PURGE_* constants
* @return bool
+ * @note In 1.28 (and only 1.28), this took a $flags parameter that
+ * controlled how much purging was done.
*/
- public function doPurge( $flags = self::PURGE_ALL ) {
+ public function doPurge() {
// Avoid PHP 7.1 warning of passing $this by reference
$wikiPage = $this;
return false;
}
- if ( ( $flags & self::PURGE_GLOBAL_PCACHE ) == self::PURGE_GLOBAL_PCACHE ) {
- // Set page_touched in the database to invalidate all DC caches
- $this->mTitle->invalidateCache();
- } elseif ( ( $flags & self::PURGE_CLUSTER_PCACHE ) == self::PURGE_CLUSTER_PCACHE ) {
- // Delete the parser options key in the local cluster to invalidate the DC cache
- ParserCache::singleton()->deleteOptionsKey( $this );
- // Avoid sending HTTP 304s in ViewAction to the client who just issued the purge
- $cache = ObjectCache::getLocalClusterInstance();
- $cache->set(
- $cache->makeKey( 'page', 'last-dc-purge', $this->getId() ),
- wfTimestamp( TS_MW ),
- $cache::TTL_HOUR
- );
- }
+ $this->mTitle->invalidateCache();
- if ( ( $flags & self::PURGE_CDN_CACHE ) == self::PURGE_CDN_CACHE ) {
- // Clear any HTML file cache
- HTMLFileCache::clearFileCache( $this->getTitle() );
- // Send purge after any page_touched above update was committed
- DeferredUpdates::addUpdate(
- new CdnCacheUpdate( $this->mTitle->getCdnUrls() ),
- DeferredUpdates::PRESEND
- );
- }
+ // Clear file cache
+ HTMLFileCache::clearFileCache( $this->getTitle() );
+ // Send purge after above page_touched update was committed
+ DeferredUpdates::addUpdate(
+ new CdnCacheUpdate( $this->mTitle->getCdnUrls() ),
+ DeferredUpdates::PRESEND
+ );
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
$messageCache = MessageCache::singleton();
*
* @return string|bool TS_MW timestamp or false
* @since 1.28
+ * @deprecated since 1.29. It will always return false.
*/
public function getLastPurgeTimestamp() {
- $cache = ObjectCache::getLocalClusterInstance();
-
- return $cache->get( $cache->makeKey( 'page', 'last-dc-purge', $this->getId() ) );
+ wfDeprecated( __METHOD__, '1.29' );
+ return false;
}
/**
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* IndexPager is an efficient pager which uses a (roughly unique) index in the
}
}
}
+ // Remove 'deprecated' key
+ if ( is_array( $this->descriptor ) ) {
+ unset( $this->descriptor[ 'deprecated' ] );
+ }
// Ensure that all files have common extension.
$extensions = [];
- $descriptor = (array)$descriptor;
+ $descriptor = (array)$this->descriptor;
array_walk_recursive( $descriptor, function ( $path ) use ( &$extensions ) {
$extensions[] = pathinfo( $path, PATHINFO_EXTENSION );
} );
$extensions = array_unique( $extensions );
if ( count( $extensions ) !== 1 ) {
throw new InvalidArgumentException(
- "File type for different image files of '$name' not the same"
+ "File type for different image files of '$name' not the same in module '$module'"
);
}
$ext = $extensions[0];
if ( !isset( self::$fileTypes[$ext] ) ) {
throw new InvalidArgumentException(
- "Invalid file type for image files of '$name' (valid: svg, png, gif, jpg)"
+ "Invalid file type for image files of '$name' (valid: svg, png, gif, jpg) in module '$module'"
);
}
$this->extension = $ext;
class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
- /* Methods */
-
/**
* @param ResourceLoaderContext $context
* @return array
return false;
}
- /**
- * @param ResourceLoaderContext $context
- * @return string: Hash
- */
- public function getModifiedHash( ResourceLoaderContext $context ) {
- $logo = $this->getConfig()->get( 'Logo' );
- $logoHD = $this->getConfig()->get( 'LogoHD' );
- return md5( parent::getModifiedHash( $context ) . $logo . json_encode( $logoHD ) );
+ public function getDefinitionSummary( ResourceLoaderContext $context ) {
+ $summary = parent::getDefinitionSummary( $context );
+ $summary[] = [
+ 'logo' => $this->getConfig()->get( 'Logo' ),
+ 'logoHD' => $this->getConfig()->get( 'LogoHD' ),
+ ];
+ return $summary;
}
}
* @author Roan Kattouw
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Abstraction for ResourceLoader modules which pull from wiki pages
*
* @ingroup RevisionDelete
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* List for archive table items, i.e. revisions deleted via action=delete
*/
* @ingroup RevisionDelete
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* List for filearchive table items
*/
* @ingroup RevisionDelete
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Item class for an oldimage table row
*/
* @ingroup RevisionDelete
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* List for oldimage table items
*/
* @ingroup RevisionDelete
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* List for logging table items
*/
*/
use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* List for revision table items
* @ingroup RevisionDelete
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Backend functions for suppressing and unsuppressing all references to a given user,
* used when blocking with HideUser enabled. This was spun out of SpecialBlockip.php
* @ingroup Search
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Base search engine base class for database-backed searches
* @ingroup Search
<?php
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Factory class for SearchEngine.
* Allows to create engine of the specific type.
*/
use MediaWiki\Logger\LoggerFactory;
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Special page which uses a ChangesList to show query results.
if ( $rows === false ) {
if ( !$this->including() ) {
$this->doHeader( $opts, 0 );
+ $this->outputNoResults();
$this->getOutput()->setStatusCode( 404 );
}
}
}
$batch->execute();
-
$this->webOutput( $rows, $opts );
$rows->free();
}
}
+ /**
+ * Add the "no results" message to the output
+ */
+ protected function outputNoResults() {
+ $this->getOutput()->addHTML(
+ '<div class="mw-changeslist-empty">' .
+ $this->msg( 'recentchanges-noresult' )->parse() .
+ '</div>'
+ );
+ }
+
/**
* Get the database result for this special page instance. Used by ApiFeedRecentChanges.
*
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Variant of QueryPage which uses a gallery to output results, thus
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Variant of QueryPage which formats the result as a simple link to the page
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* This is a class for doing query pages; since they're almost all the same,
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Class definition for a wanted query page like
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* A special page listing redirects to non existent page. Those should be
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* A special page listing redirects to redirecting page.
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Special:LinkSearch to search the external-links table.
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Special:ListDuplicatedFiles Lists all files where the current version is
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Special:Listredirects - Lists all the redirects on the wiki.
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* @ingroup SpecialPage
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* A special page that list pages that have highest category count
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* A special page that listed pages that have highest interwiki count
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* A special page to show pages ordered by the number of pages linking to them.
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* A querypage to show categories ordered in descending order by the pages in them
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Special page lists templates with a large number of
$opts = new FormOptions();
$opts->add( 'like', '' );
+ $opts->add( 'user', '' );
$opts->add( 'showbots', false );
$opts->add( 'hidepatrolled', false );
$opts->add( 'limit', 50 );
'name' => 'like',
],
+ 'user' => [
+ 'type' => 'text',
+ 'label-message' => 'newimages-user',
+ 'name' => 'user',
+ ],
+
'showbots' => [
'type' => 'check',
'label-message' => 'newimages-showbots',
$rclistOutput .= $list->endRecentChangesList();
if ( $rows->numRows() === 0 ) {
- $this->getOutput()->addHTML(
- '<div class="mw-changeslist-empty">' .
- $this->msg( 'recentchanges-noresult' )->parse() .
- '</div>'
- );
+ $this->outputNoResults();
if ( !$this->including() ) {
$this->getOutput()->setStatusCode( 404 );
}
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* SpecialShortpages extends QueryPage. It is used to return the shortest
*/
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* A special page that displays a list of pages that are not on anyones watchlist.
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* A special page that lists last changes made to the wiki,
* @todo Use some variant of Pager or something; the pagination here is lousy.
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Implements Special:Whatlinkshere
*
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ResultWrapper;
use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
class ContribsPager extends ReverseChronologicalPager {
}
$sortable = [ 'img_timestamp', 'img_name', 'img_size' ];
/* For reference, the indicies we can use for sorting are:
- * On the image table: img_usertext_timestamp, img_size, img_timestamp
+ * On the image table: img_user_timestamp, img_usertext_timestamp,
+ * img_size, img_timestamp
* On oldimage: oi_usertext_timestamp, oi_name_timestamp
*
* In particular that means we cannot sort by timestamp when not filtering
$fields = [ 'img_name', 'img_user', 'img_timestamp' ];
$options = [];
+ $user = $opts->getValue( 'user' );
+ if ( $user !== '' ) {
+ $userId = User::idFromName( $user );
+ if ( $userId ) {
+ $conds['img_user'] = $userId;
+ } else {
+ $conds['img_user_text'] = $user;
+ }
+ }
+
if ( !$opts->getValue( 'showbots' ) ) {
$groupsWithBotPermission = User::getGroupsWithPermission( 'bot' );
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Represents a "user group membership" -- a specific instance of a user belonging
* to a group. For example, the fact that user Mary belongs to the sysop group is a
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Cut-down copy of User interface for local-interwiki-database
* user rights manipulation.
<?php
+
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Allows iterating a large number of rows in batches transparently.
* By default when iterated over returns the full query result as an
* @file
* @ingroup Maintenance
*/
+use Wikimedia\Rdbms\IDatabase;
use \MediaWiki\MediaWikiServices;
class BatchRowWriter {
: "";
if ( isset( $this->customCaptions[$iwPrefix] ) ) {
- /* customCaptions composed by loadCustomCaptions() with pre-escaped content.*/
+ /* customCaptions composed by loadCustomCaptions() with pre-escaped content. */
$caption = $this->customCaptions[$iwPrefix];
} else {
$interwiki = $this->iwLookup->fetch( $iwPrefix );
"post-expand-template-argument-warning": "'''تحذير:''' هذه الصفحة تحتوي على عامل قالب واحد على الأقل له حجم تمدد كبير جدا.\nهذه العوامل تم حذفها.",
"post-expand-template-argument-category": "تجاوزات معطيات القوالب",
"parser-template-loop-warning": "تم كشف حلقة قالب: [[$1]]",
+ "template-loop-category": "الصفحات بحلقات قالب",
+ "template-loop-category-desc": "الصفحة تحتوي على حلقة قالب، أي أن القالب يستدعي نفسه.",
"parser-template-recursion-depth-warning": "تم تجاوز حد عمق فرد القوالب ($1)",
"language-converter-depth-warning": "تم تخطي حد عمق محول اللغة ($1)",
"node-count-exceeded-category": "تجاوزات تعداد العقد",
"newimages-summary": "هذه الصفحة الخاصة تعرض آخر الملفات المرفوعة.",
"newimages-legend": "المرشح",
"newimages-label": "اسم الملف (أو جزء منه):",
+ "newimages-user": "عنوان الأيبي أو اسم المستخدم",
"newimages-showbots": "أظهر التحميلات بواسطة البوتات",
"newimages-hidepatrolled": "أخف المرفوعات المنظورة",
"noimages": "لا شيء للعرض.",
"Ramsis II",
"아라",
"Oldstoneage",
- "Macofe"
+ "Macofe",
+ "Abdelrhaman Eid"
]
},
"tog-underline": "حط خط تحت اللينكات:",
"externaldberror": "يا إما فى حاجة غلط فى الدخول على قاعدة البيانات الخارجية أو انت مش مسموح لك تعمل تحديث لحسابك الخارجي.",
"login": "دخول",
"nav-login-createaccount": "تسجيل دخول / فتح حساب",
- "userlogin": "دخول / فتح حساب",
- "userloginnocreate": "دخول",
"logout": "خروج",
"userlogout": "خروج",
"notloggedin": "انت مش مسجل دخولك",
"userlogin-noaccount": "معندكش حساب؟",
"userlogin-joinproject": "انضم ل {{SITENAME}}",
- "nologin": "معندكش حساب؟ '''$1'''.",
- "nologinlink": "افتح حساب",
"createaccount": "افتح حساب",
- "gotaccount": "عندك حساب؟ '''$1'''.",
- "gotaccountlink": "دخول",
- "userlogin-resetlink": "نسيت تفاصيل الدخول؟",
"userlogin-helplink2": "مساعده ف الدخول",
"createacct-email-ph": "أكتب عنوان الإيميل بتاعك",
"createaccountmail": "استخدم باسورد مؤقته و إبعتها ع الايميل المحدد ده",
- "createaccountreason": "السبب:",
"createacct-reason": "سبب:",
"createacct-submit": "افتح حسابك",
"createacct-benefit-body1": "$1 {{PLURAL:$1|تعديل|تعديلات}}",
"logentry-newusers-create": "تم فتح حساب {{GENDER:$2|اليوزر|اليوزره}} $1",
"logentry-upload-upload": " {{GENDER:$2|رفع|اترفعت}} $1 $3",
"rightsnone": "(فاضى)",
- "revdelete-summary": "ملخص التعديل",
"searchsuggest-search": "تدوير",
"searchsuggest-containing": "جوّاه...",
"expandtemplates": "تكبير القوالب",
"nstab-special": "Ka ici wectakaniok",
"nstab-project": "nohwe ma",
"nstab-image": "Masinhikan",
+ "nstab-template": "Tapapitcikan",
"nstab-category": "Ka ici arimotcikatek",
"mainpage-nstab": "Otitikowin",
"error": "Oniparin",
"databaseerror-error": "Oniparin: $1",
"badtitle": "nama mia icinikatew",
+ "badtitletext": "Nama takon nohwe e icinikatek paskickwemikan ,cikoctew,kekotc nama mia ki otci icinikatcikatew e itectamakaniwok nte arimwewinik kekotc nte otamirowinik.\nPotc osam nipira aitisinihikana actetikena nama tca ki actakaniwona tan e icinikatcikateki kekwan.",
"viewsource": "Nte ici nta kanawapata e otciparik",
"yourname": "Icinikasowin:",
"userlogin-yourname": "Icinikasowin",
"login": "Posi",
"logout": "Piskeapikenakan",
"userlogout": "Piskeapikenakan",
+ "userlogin-noaccount": " Nama takon ki mockinesinihikan?",
+ "userlogin-joinproject": "Pe natcipicta {{ohwe itipiwin}}",
"createaccount": "Masinahotiso",
"userlogin-resetpassword-link": "Ki onikan kipitakesinihikan?",
+ "userlogin-helplink2": "Witcihewin kata pitakeapikecinaniwok",
"createacct-emailrequired": "Pamikicikwepitcikan matcetcicihikan",
"createacct-emailoptional": "Pamikicikwepitcikan matcetcicihikan (kir kotc)",
"createacct-email-ph": "Pitakesinaha ki pamikicikwepitcikan matcetcicihikan",
"botpasswords-label-cancel": "Ponipita",
"botpasswords-label-delete": "Wepina",
"resetpass-submit-cancel": "Ponipita",
+ "passwordreset": "Ka ocehikaniin itewin koski masinaha",
"passwordreset-username": "Icinikasowin:",
"passwordreset-email": "Pamikicikwepitcikan matcetcicihikan:",
"bold_sample": "Atisokesinahikan e makatewasinatek",
"templatesused": "{{PLURAL:$1|tapapitcikan ka apatak |tapapitcikan ka apatak}} nta paskickwemakanik:",
"template-protected": "(nakatweritcikatew)",
"template-semiprotected": "(apita nakatoweritakon)",
+ "moveddeleted-notice": "Paskickwemakan ka ki wepinikatek.\nOhwe wapatcikan nitc ici nokon paskickwemakanik ka ki wepinikateki acit ka ki atcipitcikateki .",
"content-model-javascript": "JavaScript",
"viewpagelogs": "Kinawapta kekwan kaki isparik ota masinhikanik",
"revisionasof": "Kiwe wapata $1",
"enhancedrc-history": "isparik",
"recentchanges": "Ka ki meckotcitakanioki",
"recentchanges-legend": " Ka meckotcitain matcenikana",
+ "recentchanges-summary": "Paskickwemikan ke ici nosanetain ka ki ocki meckotcisinihikatekai wikik.",
"recentchanges-label-newpage": "Ocki paskickwemikan ki ocitamakan",
"recentchanges-label-minor": "Apicic meckotciparin",
"recentchanges-label-bot": "Icike ki meckotciparin",
"historyaction-submit": "Wapata",
"dellogpage": " Nesitc ka wepinikatek kanaweritcikan",
"rollbacklink": "e maninikatek",
+ "protectlogpage": "Nanakatisiwina wapatcikan",
"restriction-edit": "Meckotcita",
"undeleteviewlink": "tapwatcike",
"undelete-search-submit": "Nantokaskeritcikatek",
"tooltip-t-whatlinkshere": "Ka masinateti ite e ici itohikemakak",
"tooltip-t-recentchangeslinked": "Ka masinateki anihi kaki atcitakaniwok",
"tooltip-feed-atom": "Atom itapihikan ohwe otci paskickwemikan",
+ "tooltip-t-contributions": "Ka masinasotcik ka witcihiwetcik{{GENDER:$1|ka ntotcitatc}}",
"tooltip-t-upload": "Matceticiha masinhikan",
"tooltip-t-specialpages": "Kotahaki masinhikana",
"tooltip-t-print": "Matci keki orowipitaman kitci masinatekipan",
"tooltip-ca-nstab-special": "Ohowe kitcickwemakinikan,nama actew kitci meckotcitaparik.",
"tooltip-ca-nstab-project": "Kitci wapataman nehe masinihikan ocki otamirowinik otci",
"tooltip-ca-nstab-image": "Kitci wapitaman nehe masinhikan",
+ "tooltip-ca-nstab-template": "kanawapata orictawisinihikan",
"tooltip-ca-nstab-category": "Kitci wapitaman nehe mia ka ici arimotcikatek",
"tooltip-save": "Kinokepita ka meckotcisinihaman",
"tooltip-preview": "Mikwetc pitaman e kanawapataman kaki meckotcitain, e pwamici actain pamikicikwepitcikanik.",
"tooltip-diff": "Nokota nohwe ka ki meckotcisinihaham masinihikanik",
+ "tooltip-rollback": "\"Nakaha\" nikanikatew kotc peikwa e makohotc nohwe makonakan kaskina ka ki meckotcisinihikateki nta paskickwemakanik nohwe ka ki orisinihiketc mamitcit",
+ "tooltip-undo": "\"Nama ntowatc\"nihictamikan nictam meckotcisinihikan minawatc cepirihomikon taci e ici meckotcisinihikaniwok ke ici kanawapataman.Matci kaie ki ka acotcitan kekwan espirik nta nosem masinihikanik.",
"tooltip-summary": "Acta e arimotaman masinihikan apicic",
"simpleantispam-label": "Ntokiskeritcike piciriwe masinihikan \n\nNte nota <strong>nama kekwan</strong> masinaha ota!",
"pageinfo-toolboxlink": "Tipatcimo masinahikan",
"pageinfo-contentpage-yes": "Ehe",
"pageinfo-protect-cascading-yes": "Ehe",
"confirm-markpatrolled-button": "OK",
+ "nextdiff": "Tec meckotcisinihikan",
"show-big-image": "E otciparik masinahikaniwoc",
"show-big-image-preview": "E irikweckwemikisitc$1",
"show-big-image-size": "$1 x $2 pixels",
"saturday-at": "mari kicikaw $1",
"sunday-at": "manactakaniwon $1",
"metadata": "E ici tipatcitcikatek",
+ "metadata-fields": "Nohwe e aitotwakaniwitc masinasowin nta kata ici actew paskickwemakanik ka ici tipatcimonaniwok ickwa atciwonikateke nta kitci tipatcimoniwocik. Minawatc kotakahi kata katcictakaniwona.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
"exif-orientation": "Itactamictew",
"exif-datetime": "Apitc ka meckotcitakaniwok",
"exif-make": "Ka ki ocitatatc masinapiskihikaniw",
"exif-model": "E icinakok masinapiskohewin",
+ "exif-software": "Tipatcimocikimiwesinikan ka totcikatek",
+ "exif-colorspace": "Icipekihikanik",
"exif-datetimeoriginal": "E tato piponikak nictam ka masinohaniwok",
"exif-datetimedigitized": "e tato konekisit pisimw ka capwapiskipitcikatek",
"exif-source": "Ite wetciparik",
"userrights-nodatabase": "$1 базаһы юҡ йәки урындағы (локаль) база түгел.",
"userrights-changeable-col": "Һеҙ үҙгәртә алған төркөмдәр",
"userrights-unchangeable-col": "Һеҙ үҙгәртә алмаған төркөмдәр",
+ "userrights-expiry-options": "1 көн:1 day,1 аҙна:1 week,1 ай:1 mopnth, 3 ай:3 months,6 ай:6 months,1 йыл:1 year",
"userrights-conflict": "Ҡатнашыусының хоҡуҡтарын үҙгәртеү яраманы! Зинһар, үҙгәрештәрҙе тикшерегеҙ һәм яңынан индерегеҙ.",
"group": "Төркөм:",
"group-user": "Ҡулланыусылар",
"post-expand-template-argument-warning": "<strong>Увага</strong>: гэтая старонка ўтрымлівае прынамсі адзін парамэтар шаблёну, які мае занадта вялікі выгляд у разгорнутым выглядзе.\nГэтыя парамэтры былі прапушчаныя.",
"post-expand-template-argument-category": "Старонкі, у якіх прапушчаныя парамэтры шаблёнаў",
"parser-template-loop-warning": "Выяўлены цыкль у шаблёнах: [[$1]]",
+ "template-loop-category": "Старонкі з цыклямі шаблёнаў",
+ "template-loop-category-desc": "Старонка ўтрымлівае цыкль шаблёну, г. зн., шаблён уключае сам сябе рэкурсіўна.",
"parser-template-recursion-depth-warning": "Перавышаны ліміт глыбіні рэкурсіі шаблёну ($1)",
"language-converter-depth-warning": "Перавышанае абмежаваньне глыбіні канвэртару варыянтаў мовы ($1)",
"node-count-exceeded-category": "Старонкі зь перавышанай колькасьцю вузлоў",
"default-skin-not-found-no-skins": "Упс! Прадвызначаная вокладка для вашай вікі (<code>$wgDefaultSkin</code>), <code>$1</code>, недаступна.\n\nВы не ўстанавілі вокладкі.\n\n; Калі вы толькі што ўстанавілі ці абнавілі MediaWiki:\n: Магчыма, вы ўстанавілі з git, ці наўпрост з зыходнага коду, выкарыстаўшы іншы метад. Гэта нармальна. MediaWiki 1.24 і навейшыя не ўключаюць вокладкі ў асноўнае сховішча. Паспрабуйце ўстанавіць некалькі вокладак з [https://www.mediawiki.org/wiki/Category:All_skins каталога вокладак mediawiki.org], такім чынам:\n:* Узяўшы [https://www.mediawiki.org/wiki/Download tarball-інсталятар], які ўтрымлівае некалькі вокладак і прыставак. Вы можаце скапіяваць і ўставіць каталог <code>skins/</code> адтуль.\n:* Зрабіўшы клон аднаго з сховішчаў <code>mediawiki/skins/*</code> праз git у каталог <code>skins/</code> вашай інсталяцыі MediaWiki.\n: Калі вы распрацоўшчык MediaWiki, гэта не павінна адбіцца на вашым git-сховішчы. Гл. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя: Настройка вокладак] дзеля інфармацыі па ўключэнні вокладак і выбары прадвызначэння.",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (уключана)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>выключана</strong>)",
+ "mediastatistics-table-extensions": "Магчымыя прыстаўкі",
"mediastatistics-table-count": "Колькасць файлаў",
"mediastatistics-table-totalbytes": "Агульны памер",
"mediastatistics-header-unknown": "Невядомыя",
"jumptosearch": "অনুসন্ধান",
"view-pool-error": "দুঃখিত, সার্ভারে এ মূহুর্তে অতিরিক্ত চাপ রয়েছে।\nঅনেক বেশি সংখ্যক ব্যবহারকারী এই পাতাটি দেখার চেষ্টা করছেন।\nনতুন করে এ পাতাটি দেখার চেষ্টা করার আগে কিছুক্ষণ অপেক্ষা করুন।\n\n$1",
"generic-pool-error": "দুঃখিত, সার্ভারে এ মূহুর্তে অতিরিক্ত চাপ রয়েছে।\nঅনেক বেশি সংখ্যক ব্যবহারকারী এই পাতাটি দেখার চেষ্টা করছেন।\nনতুন করে এ পাতাটি দেখার চেষ্টা করার আগে কিছুক্ষণ অপেক্ষা করুন।",
- "pool-timeout": "সময় à¦\89তà§\8dতিরà§\8dণ লà¦\95-à¦\8fর à¦\9cনà§\8dয à¦\85পà§\87à¦\95à§\8dষারত",
+ "pool-timeout": "à¦\85বরà§\8bধà§\87র à¦\9cনà§\8dয à¦\85পà§\87à¦\95à§\8dষা à¦\95রতà§\87 à¦\97িয়à§\87 সময় à¦\89তà§\8dতà§\80রà§\8dণ",
"pool-queuefull": "পুলের লাইন পূর্ণ",
"pool-errorunknown": "অজানা ত্রুটি",
"pool-servererror": "পুল কাউন্টার সার্ভিস নিষ্ক্রিয় ($1)।",
"editsectionhint": "অনুচ্ছেদ সম্পাদনা: $1",
"toc": "পরিচ্ছেদসমূহ",
"showtoc": "দেখাও",
- "hidetoc": "লà§\81à¦\95িয়à§\87 রাà¦\96া হà§\8bà¦\95",
+ "hidetoc": "লà§\81à¦\95িয়à§\87 রাà¦\96à§\81ন",
"collapsible-collapse": "সংকোচন",
"collapsible-expand": "প্রসারণ",
"confirmable-confirm": "{{GENDER:$1|আপনি}} কি নিশ্চিত?",
"transaction-duration-limit-exceeded": "দীর্ঘ পুনঃসৃষ্টি বিলম্ব এড়ানোর জন্য এই ট্রানজাকশনটি বাতিল করা হল, কারণ লিখনের স্থায়িত্ব ($1) $2 সেকেন্ড সীমাটিকে অতিক্রম করে গিয়েছিল। \nযদি আপনি অনেকগুলি আইটেম একসাথে পরিবর্তন করতে চান, তাহলে একাধিক ক্ষুদ্রতর অপারেশন সম্পন্ন করার চেষ্টা করুন।",
"laggedslavemode": "<strong>সতর্ক বার্তা:</strong> পাতাটি সম্ভবত সম্প্রতি হালনাগাদ করা হয়নি।",
"readonly": "ডাটাবেজ অবরুদ্ধ",
- "enterlockreason": "তালাবদà§\8dধ à¦\95রার à¦\95ারণ à¦\95ি তা বলà§\81ন, সাথà§\87 à¦\95à¦\96ন তালা খুলবেন তার আনুমানিক সময় উল্লেখ করুন",
+ "enterlockreason": "à¦\85বরà§\81দà§\8dধ à¦\95রার à¦\95ারণ à¦\95à§\80 তা বলà§\81ন, সাথà§\87 à¦\95à¦\96ন à¦\85বরà§\8bধ খুলবেন তার আনুমানিক সময় উল্লেখ করুন",
"readonlytext": "নতুন ভুক্তি এবং অন্যান্য সম্পাদনার জন্য ডাটাবেজ বর্তমানে অবরুদ্ধ করা আছে। সম্ভবত ডাটাবেজ রক্ষণাবেক্ষণের নিয়মিত কাজ চলছে। কাজ শেষ হলে এটি স্বাভাবিক অবস্থায় ফিরে আসবে।\n\nযে সিস্টেম প্রশাসক এটি অবরুদ্ধ করেছেন, তিনি এই ব্যাখ্যা দিয়েছেন: $1",
"missing-article": "\"$1\" পাতাটির $2 লেখাটি ডাটাবেজ খুঁজে পায়নি, যদিও খুঁজে পাওয়ার কথা ছিল।\n\nসাধারণত কোন মেয়াদোত্তীর্ণ সংশোধন পার্থক্য অনুসরণ করলে অথবা \nমুছে ফেলা কোন পাতার ইতিহাসের সংযোগ অনুসরণ করলে এমনটি ঘটে।\n\nযদি এমনটি না হয়, তাহলে আপনি হয়ত সফটওয়্যারে কোন ত্রুটি খুঁজে পেয়েছেন।\n\nঅনুগ্রহ করে ইউআরএল-টি উল্লেখ করে এ ব্যাপারে কোন [[Special:ListUsers/sysop|প্রশাসককে]] অবহিত করুন।",
"missingarticle-rev": "(সংস্করণ#: $1)",
"resettokens-token-label": "$1 (বর্তমান: $2)",
"resettokens-watchlist-token": "[[Special:Watchlist|নজরতালিকায় থাকা পাতাগুলোতে পরিবর্তন]] সংক্রান্ত ওয়েব ফিডের (Atom বা RSS) টোকেন",
"resettokens-done": "টোকেনগুলি সফলভাবে পুনঃনির্ধারিত হয়েছে।",
- "resettokens-resetbutton": "নিরà§\8dবাà¦\9aিত à¦\9fà§\8bà¦\95à§\87নà¦\97à§\81লি পà§\81নà¦\83নিরà§\8dধারণ à¦\95রা হà§\8bà¦\95",
+ "resettokens-resetbutton": "নিরà§\8dবাà¦\9aিত à¦\9fà§\8bà¦\95à§\87নà¦\97à§\81লি পà§\81নà¦\83নিরà§\8dধারণ à¦\95রà§\81ন",
"bold_sample": "গাঢ় লেখা",
"bold_tip": "গাঢ় লেখা",
"italic_sample": "তির্যক লেখা",
"headline_sample": "শিরোনাম",
"headline_tip": "২য় স্তরের শিরোনাম",
"nowiki_sample": "অবিন্যাসকৃত পাঠ্য এখানে যোগ করুন",
- "nowiki_tip": "à¦\89à¦\87à¦\95ি ফরমà§\8dযাà¦\9fিà¦\82 উপেক্ষা করা হোক",
+ "nowiki_tip": "à¦\89à¦\87à¦\95ি বিনà§\8dযাসন উপেক্ষা করা হোক",
"image_sample": "উদাহরণ.jpg",
"image_tip": "গ্রথিত ফাইল",
"media_tip": "ফাইল সংযোগ",
"sectioneditnotsupported-text": "এই সম্পাদনা পাতায় অনুচ্ছেদ সম্পাদনা সমর্থন করে না",
"permissionserrors": "অনুমতি ত্রুটিসমূহ",
"permissionserrorstext": "নিন্মলিখিত {{PLURAL:$1|কারণটির|কারণগুলির}} জন্য আপনার এটা করার অনুমতি নেই:",
- "permissionserrorstext-withaction": "আপনার $2 অনুমতি নেই, যার {{PLURAL:$1|কারণ|কারণসমূহ}} হল:",
+ "permissionserrorstext-withaction": "আপনার $2 অনুমতি নেই, যার {{PLURAL:$1|কারণটি|কারণগুলি}} হল:",
"contentmodelediterror": "আপনি এই পুনর্বিবেচনা সম্পাদনা করতে পারবেন না কারণ এর বিষয়বস্তু মডেল <code>$1</code>, যা বর্তমান বিষয়বস্তু মডেল <code>$2</code>-এর থেকে ভিন্ন।",
"recreate-moveddeleted-warn": "'''সতর্কীকরণ: আপনি এমন একটি পাতা পুনরায় তৈরি করছেন যা পূর্বে অপসারণ করা হয়েছিল।'''\n\nআপনি পাতাটি সম্পাদনা চালিয়ে যাওয়া ঠিক হবে কিনা, তা বিবেচনা করুন।\nআপনার সুবিধার্থে পাতাটির অপলুপ্তি লগ এখানে দেয়া হলো:",
"moveddeleted-notice": "এই পাতাটি অপসারণ করা হয়েছে।\nসূত্র হিসেবে নিচে এ পাতার অবলুপ্তি লগ দেওয়া হলো।",
"mergehistory-list": "একীকরণযোগ্য সম্পাদনা ইতিহাস",
"mergehistory-merge": "[[:$1]]-এর নিচের সংশোধনগুলি [[:$2]]-এর সাথে একত্র করা যাবে। রেডিও বোতাম কলামটি ব্যবহার করে কেবলমাত্র নির্দেশিত সময় ও তার আগের সমস্ত সংশোধন একত্র করুন। লক্ষ্য করুন, পরিভ্রমণ সংযোগ ব্যবহার করলে কলামটি আদি অবস্থায় ফেরত যাবে।",
"mergehistory-go": "একত্রীকরণযোগ্য সম্পাদনাগুলি দেখানো হোক",
- "mergehistory-submit": "সংশোধনগুলি একত্র করা হোক",
+ "mergehistory-submit": "সংশোধনগুলি একত্রীত করুন",
"mergehistory-empty": "কোন সংশোধন একত্র করা যাবে না.",
"mergehistory-done": "$1-এর $3{{PLURAL:$3|টি সংশোধন}} [[:$2]]-এর সাথে একত্রিত করা হয়েছে।",
"mergehistory-fail": "ইতিহাস একত্র করা গেল না। অনুগ্রহ করে পাতাটি ও সময়ের প্যারামিটারগুলি আবার পরীক্ষা করে দেখুন।",
"action-autocreateaccount": "স্বয়ংক্রিয়ভাবে এই বাহ্যিক ব্যবহারকারী অ্যাকাউন্ট তৈরি করার",
"action-history": "এই পাতার ইতিহাস দেখার",
"action-minoredit": "এই সম্পাদনাটি অনুল্লেখ্য হিসেবে চিহ্নিত করার",
- "action-move": "পাতাà¦\9fি সরিয়à§\87 ফà§\87লà§\81ন",
- "action-move-subpages": "পাতাà¦\9fি à¦\8fবà¦\82 à¦\8fর à¦\89পপাতাà¦\97à§\81লà§\8b সরিয়à§\87 ফà§\87লà§\81ন",
+ "action-move": "à¦\8fà¦\87 পাতাà¦\9fি সà§\8dথানানà§\8dতর à¦\95রার",
+ "action-move-subpages": "à¦\8fà¦\87 পাতাà¦\9fি à¦\8fবà¦\82 à¦\8fর à¦\89পপাতাà¦\97à§\81লি সà§\8dথানানà§\8dতর à¦\95রার",
"action-move-rootuserpages": "root ব্যবহারকারীর পাতাগুলো সরিয়ে ফেলুন",
- "action-move-categorypages": "বিষয়শ্রেণী পাতা স্থানান্তর করা",
+ "action-move-categorypages": "বিষয়শ্রেণীর পাতা স্থানান্তর করার",
"action-movefile": "এই ফাইল স্থানান্তর করার",
"action-upload": "এই ফাইল আপলোড করার",
- "action-reupload": "বিদà§\8dযমান ফাà¦\87ল পà§\8dরতিসà§\8dথাপন à¦\95রà§\8b",
+ "action-reupload": "à¦\8fà¦\87 বিদà§\8dযমান ফাà¦\87ল পà§\8dরতিসà§\8dথাপন à¦\95রার",
"action-reupload-shared": "শেয়ার্ড রিপোজিটরীতে এই ফাইলটি হালনাগাদ করার",
- "action-upload_by_url": "à¦\95à§\8bন à¦\87à¦\89à¦\86রà¦\8fল থà§\87à¦\95à§\87 ফাà¦\87লà¦\9fি à¦\86পলà§\8bড à¦\95রà§\8b",
- "action-writeapi": "রাà¦\87à¦\9f à¦\8fপিà¦\86à¦\87 বà§\8dযবহার à¦\95রà§\81ন",
- "action-delete": "পাতাà¦\9fি মà§\81à¦\9bà§\87 ফà§\87লà§\8b",
+ "action-upload_by_url": "à¦\8fà¦\95à¦\9fি à¦\87à¦\89à¦\86রà¦\8fল থà§\87à¦\95à§\87 à¦\8fà¦\87 ফাà¦\87লà¦\9fি à¦\86পলà§\8bড à¦\95রার",
+ "action-writeapi": "à¦\8fপিà¦\86à¦\87 লà§\87à¦\96া বà§\8dযবহার à¦\95রার",
+ "action-delete": "à¦\8fà¦\87 পাতাà¦\9fি à¦\85পসারণ à¦\95রার",
"action-deleterevision": "সংশোধনটি মুছে ফেলার",
"action-deletelogentry": "লগের ভুক্তি অপসারণ করার",
"action-deletedhistory": "পাতার অপসারিত ইতিহাস দেখার",
"action-deletedtext": "অপসারিত সংশোধনের লেখা দেখার",
- "action-browsearchive": "অপসারিত পাতায় অনুসন্ধান করুন",
+ "action-browsearchive": "অপসারিত পাতা অনুসন্ধান করার",
"action-undelete": "পাতাটি পুনরুদ্ধার করার",
"action-suppressrevision": "লুকানো সংস্করণগুলো পর্যালোচনা এবং পুনঃস্থাপন করার",
"action-suppressionlog": "এই ব্যক্তিগত লগ দেখার",
"action-protect": "এই পাতার সুরক্ষার মাত্রা পরিবর্তন করার",
"action-rollback": "একটি নির্দিষ্ট পাতার সর্বশেষ ব্যবহারকারীর সম্পদনা পূর্বাবস্থায় ফিরিয়ে আনুন",
"action-import": "অন্য উইকি থেকে পাতা আমদানি করার",
- "action-importupload": "ফাà¦\87ল à¦\86পলà§\8bড থà§\87à¦\95à§\87 পাতা à¦\86মদানà§\80 à¦\95রà§\8b",
- "action-patrol": "à¦\85নà§\8dযদà§\87র সমà§\8dপাদনা পরà§\80à¦\95à§\8dষিত বলà§\87 à¦\9aিহà§\8dনিত à¦\95রà§\8b",
+ "action-importupload": "ফাà¦\87ল à¦\86পলà§\8bড থà§\87à¦\95à§\87 পাতা à¦\86মদানি à¦\95রার",
+ "action-patrol": "à¦\85নà§\8dযদà§\87র সমà§\8dপাদনা পরà§\80à¦\95à§\8dষিত বলà§\87 à¦\9aিহà§\8dনিত à¦\95রার",
"action-autopatrol": "পরীক্ষিত বলে চিহ্নিত কি আপনি সম্পাদনা করেছেন",
- "action-unwatchedpages": "নà¦\9cরতালিà¦\95া বহিরà§\8dà¦à§\82ত পাতাà¦\97à§\81লির তালিà¦\95া দà§\87à¦\96াà¦\93",
+ "action-unwatchedpages": "নà¦\9cরতালিà¦\95া বহিরà§\8dà¦à§\82ত পাতাà¦\97à§\81লির তালিà¦\95া দà§\87à¦\96ার",
"action-mergehistory": "এই পাতার ইতিহাস একত্রিত করার",
- "action-userrights": "সà¦\95ল বà§\8dযবহারà¦\95ারà§\80র à¦\85ধিà¦\95ার সমà§\8dপাদনা à¦\95রà§\81ন",
- "action-userrights-interwiki": "অন্যান্য উইকির ব্যবহারকারীদের অধিকারসমূহ সম্পাদনা করুন",
- "action-siteadmin": "ডাটাবেজ অবরুদ্ধ করা অথবা খোলা",
+ "action-userrights": "সà¦\95ল বà§\8dযবহারà¦\95ারà§\80র à¦\85ধিà¦\95ার সমà§\8dপাদনা à¦\95রার",
+ "action-userrights-interwiki": "অন্য উইকিতে ব্যবহারকারীদের অধিকার সম্পাদনা করার",
+ "action-siteadmin": "ডাটাবেজ অবরুদ্ধ করার অথবা খোলার",
"action-sendemail": "ই-মেইল পাঠাও",
"action-editmyoptions": "নিজের পছন্দসমূহ সম্পাদনা করার",
"action-editmywatchlist": "আপনার নজরতালিকা পরিবর্তন করুন",
"recentchanges-submit": "দেখাও",
"rcfilters-activefilters": "সক্রিয় ফিল্টার",
"rcfilters-restore-default-filters": "পূর্বনির্ধারিত ছাঁকনি পুনরুদ্ধার করুন",
- "rcfilters-clear-all-filters": "সমসà§\8dত ফিলà§\8dà¦\9fার à¦\85পসারণ",
+ "rcfilters-clear-all-filters": "সব à¦\9bাà¦\81à¦\95নি পরিষà§\8dà¦\95ার à¦\95রà§\81ন",
"rcfilters-search-placeholder": "সাম্প্রতিক পরিবর্তনসমূহ ছাঁকুন (ব্রাউজ বা টাইপ করা শুরু করুন)",
- "rcfilters-invalid-filter": "à¦\85à¦\95ারà§\8dযà¦\95র ফিলà§\8dà¦\9fার",
+ "rcfilters-invalid-filter": "à¦\85à¦\95ারà§\8dযà¦\95র à¦\9bাà¦\81à¦\95নি",
"rcfilters-empty-filter": "কোনো সক্রিয় ফিল্টার নেই। সমস্ত অবদান দেখানো হয়েছে।",
"rcfilters-filterlist-title": "ছাঁকনি",
"rcfilters-filterlist-whatsthis": "এটি কী?",
"rcfilters-filterlist-feedbacklink": "নতুন (বিটা) ছাঁকনির উপর মতামত প্রদান করুন",
- "rcfilters-highlightbutton-title": "ফলাফল আলোকপাত করুন",
+ "rcfilters-highlightbutton-title": "ফলাফলে আলোকপাত করুন",
"rcfilters-highlightmenu-title": "একটি রং নির্বাচন করুন",
- "rcfilters-highlightmenu-help": "এই বৈশিষ্ট্য আলোকপাত করতে একটি রঙ নির্বাচন করুন",
- "rcfilters-filterlist-noresults": "à¦\95à§\8bনà¦\93 ফিলà§\8dà¦\9fার পাওয়া যায়নি",
+ "rcfilters-highlightmenu-help": "এই বৈশিষ্ট্যটিতে আলোকপাত করতে একটি রঙ নির্বাচন করুন",
+ "rcfilters-filterlist-noresults": "à¦\95à§\8bনà¦\93 à¦\9bাà¦\81à¦\95নি পাওয়া যায়নি",
"rcfilters-noresults-conflict": "কোনও ফলাফল পাওয়া যায়নি কারণ অনুসন্ধানের মাপকাঠিগুলির মধ্যে সংঘর্ষ আছে",
- "rcfilters-state-message-subset": "এই ছাঁকনিটির কোন প্রভাব নেই কারণ এর ফলাফলগুলি নিম্নোক্ত বৃহত্তর পরিধির {{PLURAL:$2|ছাঁকনির|ছাঁকনিগুলির}} মধ্যে অন্তর্ভুক্ত আছে (আলোকপাত করে এটিকে আলাদা করে দেখার চেষ্টা করুন): $1",
+ "rcfilters-state-message-subset": "à¦\8fà¦\87 à¦\9bাà¦\81à¦\95নিà¦\9fির à¦\95à§\8bন পà§\8dরà¦à¦¾à¦¬ নà§\87à¦\87 à¦\95ারণ à¦\8fর ফলাফলà¦\97à§\81লি নিমà§\8dনà§\8bà¦\95à§\8dত বà§\83হতà§\8dতর পরিধির {{PLURAL:$2|à¦\9bাà¦\81à¦\95নিà¦\9fির|à¦\9bাà¦\81à¦\95নিà¦\97à§\81লির}} মধà§\8dযà§\87 à¦\85নà§\8dতরà§\8dà¦à§\81à¦\95à§\8dত à¦\86à¦\9bà§\87 (à¦\86লà§\8bà¦\95পাত à¦\95রà§\87 à¦\8fà¦\9fিà¦\95à§\87 à¦\86লাদা à¦\95রà§\87 দà§\87à¦\96ার à¦\9aà§\87ষà§\8dà¦\9fা à¦\95রà§\81ন): $1",
"rcfilters-state-message-fullcoverage": "কোন দলের সমস্ত ছাঁকনি নির্বাচন করা এবং কোন ছাঁকনিই নির্বাচন না করা একই কথা, তাই এই ছাঁকনিটির কোন প্রভাব নেই। এই দলে অন্তর্ভুক্ত ছাঁকনিগুলি হল: $1",
"rcfilters-filtergroup-registration": "ব্যবহারকারী নিবন্ধন",
"rcfilters-filter-registered-label": "নিবন্ধিত",
"rcfilters-filter-registered-description": "প্রবেশকৃত সম্পাদকবৃন্দ।",
"rcfilters-filter-unregistered-label": "অনিবন্ধিত",
- "rcfilters-filter-unregistered-description": "সমà§\8dপাদà¦\95 যারা পà§\8dরবà§\87শ à¦\95রà§\87ন নি।",
- "rcfilters-filter-unregistered-conflicts-user-experience-level": "এই ছাঁকনিটির সাথে নিম্নোক্ত ব্যবহারকারী অভিজ্ঞতা{{PLURAL:$2|ছাঁকনির|ছাঁকনিগুলির}} সংঘর্ষ আছে; যা কেবলমাত্র নিবন্ধিত ব্যবহারকারীদের খুঁজে বের করে: $1",
- "rcfilters-filtergroup-authorship": "à¦\95à§\83তি সমà§\8dপাদনা",
+ "rcfilters-filter-unregistered-description": "যà§\87সব সমà§\8dপাদà¦\95 à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9fà§\87 পà§\8dরবà§\87শ à¦\95রà§\87ননি।",
+ "rcfilters-filter-unregistered-conflicts-user-experience-level": "এই ছাঁকনিটির সাথে নিম্নোক্ত ব্যবহারকারী অভিজ্ঞতা {{PLURAL:$2|ছাঁকনিটির|ছাঁকনিগুলির}} সংঘর্ষ আছে; যা কেবলমাত্র নিবন্ধিত ব্যবহারকারীদের খুঁজে বের করে: $1",
+ "rcfilters-filtergroup-authorship": "à¦\95ার দà§\8dবারা সমà§\8dপাদিত",
"rcfilters-filter-editsbyself-label": "আপনার নিজস্ব সম্পাদনা",
- "rcfilters-filter-editsbyself-description": "à¦\86পনার দà§\8dবারা সমà§\8dপাদনা।",
- "rcfilters-filter-editsbyother-label": "à¦\85নà§\8dযদà§\87র দà§\8dবারা সমà§\8dপাদনা",
- "rcfilters-filter-editsbyother-description": "à¦\85নà§\8dয বà§\8dযবহারà¦\95ারà§\80দà§\87র দà§\8dবারা à¦\95রা সমà§\8dপাদনা (à¦\86পনার না)।",
+ "rcfilters-filter-editsbyself-description": "à¦\86পনার সমà§\8dপাদনাà¦\97à§\81লি।",
+ "rcfilters-filter-editsbyother-label": "à¦\85নà§\8dযদà§\87র সমà§\8dপাদনাà¦\97à§\81লি",
+ "rcfilters-filter-editsbyother-description": "à¦\85নà§\8dয বà§\8dযবহারà¦\95ারà§\80দà§\87র à¦\95রা সমà§\8dপাদনাà¦\97à§\81লি (à¦\86পনার à¦\95রা নয়)।",
"rcfilters-filtergroup-userExpLevel": "অভিজ্ঞতার স্তর (শুধু মাত্র নিবন্ধিত ব্যবহারকারীর জন্য)",
"rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "অভিজ্ঞতা ছাঁকনিগুলি কেবলমাত্র নিবন্ধিত ব্যবহারকারীদের খুঁজে বের করে, তাই এই ছাঁকনিটি \"অনিবন্ধিত\" ছাঁকনিটির সাথে সংঘর্ষে আছে।",
"rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "\"অনিবন্ধিত\" ছাঁকনিটি এক বা তার অধিক অভিজ্ঞতা ছাঁকনির সাথে সংঘর্ষে আছে, যে ছাঁকনিগুলি কেবলমাত্র নিবন্ধিত ব্যবহারকারীদের খুঁজে বের করে। সংঘর্ষরত ছাঁকনিগুলিকে উপরের \"সক্রিয় ছাঁকনিসমূহ\" এলাকাতে চিহ্নিত করা হয়েছে।",
"rcfilters-filter-user-experience-level-newcomer-label": "নতুন আগত",
- "rcfilters-filter-user-experience-level-newcomer-description": "১০টি সম্পাদনার কম ও ৪ দিনের কার্যকলাপ।",
+ "rcfilters-filter-user-experience-level-newcomer-description": "১০টির কমসংখ্যক সম্পাদনা করেছেন ও ৪ দিনের কম সময় ধরে সক্রিয় আছেন।",
"rcfilters-filter-user-experience-level-learner-label": "শিক্ষার্থী",
"rcfilters-filter-user-experience-level-learner-description": "যারা \"নবাগত\" ব্যবহারকারীদের চেয়ে বেশিসংখ্যক দিন ও বেশিবার সম্পাদনা করেছেন, কিন্তু \"অভিজ্ঞ ব্যবহারকারীদের\" চেয়ে কম করেছেন।",
"rcfilters-filter-user-experience-level-experienced-label": "অভিজ্ঞ ব্যবহারকারী",
- "rcfilters-filter-user-experience-level-experienced-description": "৩০ দিনà§\87র বà§\87শà§\80 à¦\95ারà§\8dযà¦\95লাপ à¦\93 ৫০০à¦\9fি সমà§\8dপাদনা।",
+ "rcfilters-filter-user-experience-level-experienced-description": "৩০ দিনà§\87র বà§\87শি সà¦\95à§\8dরিয় à¦\86à¦\9bà§\87ন à¦\93 ৫০০à¦\9fির বà§\87শি সমà§\8dপাদনা à¦\95রà§\87à¦\9bà§\87ন।",
"rcfilters-filtergroup-automated": "স্বয়ংক্রিয় অবদান",
"rcfilters-filter-bots-label": "বট",
"rcfilters-filter-bots-description": "স্বয়ংক্রিয় সরঞ্জাম দিয়ে করা সম্পাদনা।",
"rcfilters-filter-humans-label": "মানুষ (বট নয়)",
- "rcfilters-filter-humans-description": "মানব সমà§\8dপাদà¦\95 দà§\8dবারা করা সম্পাদনা।",
+ "rcfilters-filter-humans-description": "মানà§\81ষà§\87র করা সম্পাদনা।",
"rcfilters-filtergroup-reviewstatus": "পর্যালোচনার অবস্থা",
"rcfilters-filter-patrolled-label": "পরীক্ষিত",
"rcfilters-filter-patrolled-description": "সম্পাদনা পরীক্ষিত হিসেবে চিহ্নিত করা হয়েছে।",
"rcfilters-filtergroup-significance": "তাৎপর্য",
"rcfilters-filter-minor-label": "অনুল্লেখ্য সম্পাদনা",
"rcfilters-filter-minor-description": "যেসব সম্পাদনাকে লেখক অনুল্লেখ্য হিসেবে চিহ্নিত করেছেন।",
- "rcfilters-filter-major-label": "অ-অনুল্লেখ্য সম্পাদনা",
+ "rcfilters-filter-major-label": "অনুল্লেখ্য নয়, এমন সম্পাদনা",
"rcfilters-filter-major-description": "যেসব সম্পাদনাকে অনুল্লেখ্য হিসেবে চিহ্নিত করা হয়নি।",
"rcfilters-filtergroup-changetype": "পরিবর্তনের ধরন",
"rcfilters-filter-pageedits-label": "পাতার সম্পাদনা",
"rcfilters-filter-pageedits-description": "উইকি বিষয়বস্তু, আলোচনা, বিষয়শ্রেণীর বিবরণ.... ইত্যাদিতে সম্পাদনা",
- "rcfilters-filter-newpages-label": "পাতার সৃষ্টিকরণ",
+ "rcfilters-filter-newpages-label": "পাতা তৈরিকরণ",
"rcfilters-filter-newpages-description": "সম্পাদনা যা নতুন পাতা তৈরি করেছে।",
"rcfilters-filter-categorization-label": "বিষয়শ্রেণীর পরিবর্তন",
"rcfilters-filter-categorization-description": "বিষয়শ্রেণী পাতা সংযোজন বা অপসারণের তালিকা",
"lockmanager-fail-releaselock": "\"$1\" লক করা ফাইলটি ছাড়া যাচ্ছে না।",
"lockmanager-fail-db-bucket": "$1 বাকেটটিতে যথেষ্ট সংখ্যক অবরোধ ডাটাবেজের সাথে যোগাযোগ করা যাচ্ছে না।",
"lockmanager-fail-db-release": "$1 ডাটাবেজের লক খোলা যাচ্ছে না।",
- "lockmanager-fail-svr-acquire": "$1 সারà§\8dà¦à¦¾à¦°à§\87 তালা পাওয়া যায়নি।",
+ "lockmanager-fail-svr-acquire": "$1 সারà§\8dà¦à¦¾à¦°à§\87 à¦\85বরà§\8bধà¦\97à§\81লি পাওয়া যায়নি।",
"lockmanager-fail-svr-release": "$1 ডাটাবেজের লক খোলা যাচ্ছে না।",
"zip-file-open-error": "ফাইলটির জিপ পরীক্ষা করার সময় একটি ত্রুটি দেখা দিয়েছে।",
"zip-wrong-format": "চিহ্নিত ফাইলটি কোনো জিপ ফাইল নয়।",
"shared-repo-from": "$1 থেকে",
"shared-repo": "শেয়ার্ড রিপোজিটরী",
"shared-repo-name-wikimediacommons": "উইকিমিডিয়া কমন্স",
+ "filepage.css": "/* এখানে সন্নিবেশিত সিএসএস ফাইলের বিবরণ পৃষ্ঠায় অন্তর্ভুক্ত হবে, এছাড়া বিদেশী ক্লায়েন্ট উইকিতেও অন্তর্ভুক্ত হবে */",
"upload-disallowed-here": "আপনি এই ফাইলটি প্রতিস্থাপন করতে পারবেন না।",
"filerevert": "$1 পূর্বাবস্থায় ফেরত নিন",
"filerevert-legend": "ফাইল পূর্বাবস্থায় ফেরত নিন",
"filerevert-success": "'''[[Media:$1|$1]]''' ফাইলটি [$3, $2-এর $4 সংস্করণে] ফেরত নেওয়া হয়েছে।",
"filerevert-badversion": "প্রদত্ত তারিখ ও সময়ের জন্য এই ফাইলটির কোন স্থানীয় সংস্করণ নেই।",
"filerevert-identical": "ফাইলটির বর্তমান সংস্করণের সাথে নির্বাচিত সংস্করণটির হুবহু মিল রয়েছে।",
- "filedelete": "$1 মà§\81à¦\9bà§\87 ফà§\87লা হà§\8bà¦\95",
- "filedelete-legend": "ফাà¦\87ল মà§\81à¦\9bà§\87 ফà§\87লা হà§\8bà¦\95",
+ "filedelete": "$1 à¦\85পসারণ à¦\95রà§\81ন",
+ "filedelete-legend": "ফাà¦\87ল à¦\85পসারণ à¦\95রà§\81ন",
"filedelete-intro": "আপনি '''[[Media:$1|$1]]''' ফাইলটি এর সমস্ত ইতিহাসহ অপসারণ করছেন।",
"filedelete-intro-old": "আপনি '''[[Media:$1|$1]]''' ফাইলটির [$4 $3, $2] সংস্করণটি মুছে ফেলছেন।",
"filedelete-comment": "কারণ:",
"apisandbox-multivalue-all-namespaces": "$1 (সব নামস্থান)",
"apisandbox-multivalue-all-values": "$1 (সব মান)",
"booksources": "বইয়ের উৎস",
- "booksources-search-legend": "বà¦\87য়à§\87র à¦\89à§\8eসà§\87র à¦\9cনà§\8dয à¦\85নà§\81সনà§\8dধান à¦\95রা হà§\8bà¦\95",
+ "booksources-search-legend": "বà¦\87য়à§\87র à¦\89à§\8eসà§\87র à¦\9cনà§\8dয à¦\85নà§\81সনà§\8dধান à¦\95রà§\81ন",
"booksources-isbn": "আইএসবিএন:",
"booksources-search": "অনুসন্ধান",
"booksources-text": "নতুন ও পুরাতন ব্যবহৃত বই বিক্রি করে, এমন কতগুলি সাইটের সংযোগের তালিকা নিচে দেওয়া হল, যে সাইটগুলিতে আপনার অনুসন্ধানকৃত বইগুলির উপর আরও তথ্য থাকতে পারে:",
"block": "ব্যবহারকারীকে বাধা দাও",
"unblock": "ব্যবহারকারীর উপর থেকে বাধা অপসারণ",
"blockip": "{{GENDER:$1|ব্যবহারকারীকে}} বাধা দাও",
- "blockip-legend": "বà§\8dযবহারà¦\95ারà§\80à¦\95à§\87 বাধা দà§\87à¦\93য়া হà§\8bà¦\95",
+ "blockip-legend": "বà§\8dযবহারà¦\95ারà§\80à¦\95à§\87 বাধা দিন",
"blockiptext": "কোন নির্দিষ্ট আইপি ঠিকানা বা ব্যবহারকারীর লেখার অধিকারে বাধা দিতে নিচের ফর্মটি ব্যবহার করুন।\nএটি কেবলমাত্র ধ্বংসপ্রবণতা প্রতিরোধে ও [[{{MediaWiki:Policy-url}}|নীতিমালা]] মেনে সম্পাদন করা উচিত।\nনিচে একটি নির্দিষ্ট কারণ দিন (উদাহরণস্বরূপ, যেসব পাতার ধ্বংসসাধন করা হয়েছে, সেগুলি উল্লেখ করতে পারেন)।\nআপনি একটি নির্দিষ্ট সীমার অন্তর্গত একাধিক আইপি ঠিকানাকে বাধা দিতে পারেন; এজন্য [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] সিনট্যাক্স বা পদবিন্যাসবিধি ব্যবহার করুন; এরকম বৃহত্তম অনুমোদিত সীমা হচ্ছে IPv4-এর ক্ষেত্রে /$1 এবং IPv6-এর ক্ষেত্রে /$2।",
"ipaddressorusername": "আইপি ঠিকানা বা ব্যবহারকারীর নাম:",
"ipbexpiry": "যখন মেয়াদোত্তীর্ণ হবে:",
"ipb-hardblock": "এই আইপি ঠিকানা থেকে লগ-ইনকৃত ব্যবহারকারীদেরকে সম্পাদনায় বাধা দাও",
"ipbcreateaccount": "অ্যাকাউন্ট সৃষ্টিতে বাধা দেওয়া হোক",
"ipbemailban": "ব্যবহারকারীকে ই-মেইল পাঠাতে বাধা দেওয়া হোক",
- "ipbenableautoblock": "এই ব্যবহারকারীর ব্যবহার করা সর্বশেষ আইপি ঠিকানা, এবং পরবর্তী যেসব আইপি ঠিকানা থেকে সম্পাদনার চেষ্টা করা হবে, সেগুলিকেও স্বয়ংক্রিয়ভাবে বাধা দেয়া হোক।",
+ "ipbenableautoblock": "এই ব্যবহারকারীর ব্যবহার করা সর্বশেষ আইপি ঠিকানা, এবং পরবর্তী যেসব আইপি ঠিকানা থেকে সম্পাদনার চেষ্টা করা হবে, সেগুলিকেও স্বয়ংক্রিয়ভাবে বাধা দেয়া হোক",
"ipbsubmit": "এই ব্যবহারকারীকে বাধা দেয়া হোক",
"ipbother": "অন্য সময়:",
"ipboptions": "২ ঘণ্টা:2 hours,১ দিন:1 day,৩ দিন:3 days,১ সপ্তাহ:1 week,২ সপ্তাহ:2 weeks,১ মাস:1 month,৩ মাস:3 months,৬ মাস:6 months,১ বছর:1 year,অসীম:infinite",
"ipb-confirmhideuser": "\"hide user\" ক্ষমতার মাধ্যমে আপনি একজন ব্যবহারকারীকে বাধা দিতে যাচ্ছেন। এর মাধ্যমে এই ব্যবহারকারীর নাম সকল লিস্ট এবং লগএন্ট্রি থেকে সরিয়ে ফেলা হবে। আপনি কি নিশ্চিতভাবে এটি করতে চান?",
"ipb-confirmaction": "আপনি যদি নিশ্চিত হন আপনি এটি সত্যিকার অর্থেই করতে চান তাহলে অনুগ্রহ করে উপরের \"{{int:ipb-confirm}}\" ঘরটি দেখুন।",
"ipb-edit-dropdown": "বাধাদানের কারণ সম্পাদনা করুন",
- "ipb-unblock-addr": "$1-à¦\8fর à¦\89পর থà§\87à¦\95à§\87 বাধা তà§\81লà§\87 নà§\87à¦\93য়া হà§\8bà¦\95",
+ "ipb-unblock-addr": "$1-à¦\8fর বাধা তà§\81লà§\87 নিন",
"ipb-unblock": "ব্যবহারকারী বা আইপি ঠিকানার উপর থেকে বাধা তুলে নেওয়া হোক",
"ipb-blocklist": "বিদ্যমান বাধাগুলি দেখুন",
"ipb-blocklist-contribs": "{{GENDER:$1|$1}}-এর অবদানসমূহ",
"ipb-blocklist-duration-left": "$1 বাকি",
"unblockip": "ব্যবহারকারীর উপর থেকে বাধা তুলে নেওয়া হোক",
"unblockiptext": "নিচের ফর্মটি ব্যবহার করে পূর্বে বাধা দেওয়া কোন আইপি ঠিকানা বা ব্যবহারকারীর সাইটে লেখার অধিকার পুনঃপ্রতিষ্ঠা করুন।",
- "ipusubmit": "বাধা তà§\81লà§\87 নà§\87à¦\93য়া হà§\8bà¦\95",
+ "ipusubmit": "à¦\8fà¦\87 বাধা তà§\81লà§\87 নিন",
"unblocked": "[[User:$1|$1]]-এর উপর বাধা তুলে নেওয়া হয়েছে",
"unblocked-range": "$1 -এর থেকে বাধা সরিয়ে নেওয়া হয়েছে",
"unblocked-id": "$1 বাধাটি তুলে নেওয়া হয়েছে",
"ipblocklist-empty": "বাধাতালিকা খালি।",
"ipblocklist-no-results": "অনুরুদ্ধ আইপি ঠিকানা বা ব্যবহারকারী নামটির উপর কোন বাধা নেই।",
"blocklink": "বাধা দাও",
- "unblocklink": "বাধা তà§\81লà§\87 নà§\87à¦\93য়া হà§\8bà¦\95",
+ "unblocklink": "বাধা তà§\81লà§\81ন",
"change-blocklink": "বাধা পরিবর্তন করুন",
"contribslink": "অবদান",
"emaillink": "ই-মেইল পাঠাও",
"cant-see-hidden-user": "আপনি যে ব্যবহারকারীকে ব্লক বা লুকিয়ে রাখতে চাচ্ছেন তাকে আগে থেকেই ব্লক বা লুকিয়ে রাখা হয়েছে। এছাড়া আপনার Hideuser অধিকার নেই, তাই আপনি ব্যবহারকারীর অবস্থা পরিবর্তন করতে পারবেন না।",
"ipbblocked": "আপনি অন্য কোন ব্যবহারকরীকে ব্লক বা আনব্লক করতে পারবেন না, কারণ আপনি নিজেই ব্লক রয়েছেন",
"ipbnounblockself": "আপনি নিজেকে আনব্লক করতে পারবেন না",
- "lockdb": "ডাà¦\9fাবà§\87à¦\9c à¦\85বরà§\81দà§\8dধ à¦\95রà§\87 দà§\87à¦\93য়া হà§\8bà¦\95",
+ "lockdb": "ডাটাবেজ অবরুদ্ধ করা হোক",
"unlockdb": "ডাটাবেজ খুলে দেওয়া হোক",
"lockdbtext": "ডাটাবেজ অবরুদ্ধ করে দিলে কোনো ব্যবহারকারীই পাতা সম্পাদনা করতে, তাদের পছন্দ পরিবর্তন করতে, তাদের নজরতালিকা সম্পাদনা করতে এবং ডাটাবেজে পরিবর্তন আনে এমন কোন কিছু করতে পারবেন না।\nঅনুগ্রহ করে নিশ্চিত করুন যে আপনি এটাই করতে চান, এবং আপনার রক্ষণাবেক্ষণ শেষ হবার পর ডাটাবেজ আবার খুলে দেবেন।",
"unlockdbtext": "ডাটাবেজ খুলে দিলে সব ব্যবহারকারী পাতা সম্পাদনা করতে, তাদের পছন্দ পরিবর্তন করতে, তাদের নজরতালিকা সম্পাদনা করতে, এবং ডাটাবেজে পরিবর্তন সাধন করে, এমন অন্যান্য কাজ করতে পারবেন।\nঅনুগ্রহ করে নিশ্চিত করুন যে আপনি এটাই করতে চান।",
"locknoconfirm": "আপনি নিশ্চিতকরণ বাক্সে টিক দেননি।",
"lockdbsuccesssub": "ডাটাবেজ সফলভাবে অবরুদ্ধ করে দেওয়া হয়েছে",
"unlockdbsuccesssub": "ডাটাবেজ খুলে দেওয়া হয়েছে",
- "lockdbsuccesstext": "ডাটাবেজ অবরুদ্ধ করা হয়েছে\n<br />আপনার রক্ষণাবেক্ষণ সম্পন্ন হবার পর [[Special:UnlockDB|ডাটাবেজ খুলে দিতে]] ভুলবেন না।",
+ "lockdbsuccesstext": "ডাটাবেজ অবরুদ্ধ করা হয়েছে।<br />\nআপনার রক্ষণাবেক্ষণ সম্পন্ন হবার পর [[Special:UnlockDB|ডাটাবেজ খুলে দিতে]] ভুলবেন না।",
"unlockdbsuccesstext": "ডাটাবেজ খুলে দেওয়া হয়েছে।",
"lockfilenotwritable": "ডাটাবেজ অবরোধনির্দেশক ফাইলটি লিখনযোগ্য নয়। ডাটাবেজ অবরুদ্ধ করতে বা খুলতে চাইলে ফাইলটিকে ওয়েব সার্ভার কর্তৃক লিখনযোগ্য হতে হবে।",
"databaselocked": "ডাটাবেজটি ইতিমধ্যেই অবরুদ্ধ।",
"import-interwiki-sourcewiki": "উত্স উইকি:",
"import-interwiki-sourcepage": "উৎস পাতা:",
"import-interwiki-history": "এই পাতার ইতিহাসের সমস্ত সংস্করণের প্রতিলিপি করা হোক",
- "import-interwiki-templates": "সà¦\95ল à¦\9fà§\87মà§\8dপলà§\87à¦\9f à¦\85নà§\8dতরà§\8dà¦à§\81à¦\95à§\8dত",
+ "import-interwiki-templates": "সà¦\95ল à¦\9fà§\87মপà§\8dলà§\87à¦\9f à¦\85নà§\8dতরà§\8dà¦à§\81à¦\95à§\8dত à¦\95রà§\81ন",
"import-interwiki-submit": "আমদানি",
"import-mapping-default": "পূর্বনির্ধারিত অবস্থানে আমদানি করুন",
"import-mapping-namespace": "একটি নামস্থানে আমদানি করুন:",
"tooltip-ca-protect": "এই পাতাকে সুরক্ষিত করো",
"tooltip-ca-unprotect": "এই পাতার সুরক্ষা পরিবর্তন করো",
"tooltip-ca-delete": "পাতাটি মুছে ফেলো",
- "tooltip-ca-undelete": "পাতাà¦\9fি মà§\81à¦\9bà§\87 ফà§\87লার à¦\86à¦\97à§\87 যà§\87 সমà§\8dপাদনাà¦\97à§\81লি à¦\95রা হয়à§\87à¦\9bিল, সà§\87à¦\97à§\81লি à¦\89দà§\8dধার à¦\95রা হà§\8bà¦\95।",
+ "tooltip-ca-undelete": "পাতাà¦\9fি à¦\85পসারণà§\87র à¦\86à¦\97à§\87 যà§\87 সমà§\8dপাদনাà¦\97à§\81লি à¦\95রা হয়à§\87à¦\9bিল সà§\87à¦\97à§\81লি à¦\89দà§\8dধার à¦\95রা হà§\8bà¦\95",
"tooltip-ca-move": "পাতাটি স্থানান্তর করুন",
"tooltip-ca-watch": "এই পাতাটি আপনার নজরতালিকায় যোগ করুন",
"tooltip-ca-unwatch": "এই পাতাটি আপনার নজরতালিকা থেকে সরিয়ে ফেলুন",
"tooltip-search": "{{SITENAME}} অনুসন্ধান",
"tooltip-search-go": "যদি থাকে, তবে ঠিক এই নামের পাতায় চলো",
- "tooltip-search-fulltext": "à¦\8fà¦\87 à¦\9fà§\87à¦\95à§\8dসà¦\9fà§\87র à¦\9cনà§\8dয পাতাà¦\97à§\81লিতà§\87 à¦\85নà§\81সনà§\8dধান à¦\95রা হà§\8bà¦\95",
+ "tooltip-search-fulltext": "à¦\8fà¦\87 লà§\87à¦\96ার à¦\9cনà§\8dয পাতাà¦\97à§\81লিতà§\87 à¦\85নà§\81সনà§\8dধান à¦\95রà§\81ন",
"tooltip-p-logo": "প্রধান পাতা পরিদর্শন করুন",
"tooltip-n-mainpage": "প্রধান পাতায় যান",
"tooltip-n-mainpage-description": "প্রধান পাতা পরিদর্শন করুন",
"tooltip-preferences-save": "পছন্দ সংরক্ষণ",
"tooltip-summary": "একটি সংক্ষিপ্ত সারাংশ দিন",
"interlanguage-link-title": "$1 - $2",
- "common.css": "/* এখানে সিএসএস নিবেশিত করা হলে তা সব স্কিনে প্রয়োগ করা হবে */",
+ "common.css": "/* এখানে সন্নিবেশিত সিএসএস সব আবরণে প্রয়োগ করা হবে */",
+ "print.css": "/* এখানে সন্নিবেশিত সিএসএস মুদ্রণের আউটপুটকে প্রভাবিত করবে */",
+ "noscript.css": "/* এখানে সন্নিবেশিত সিএসএস জাভাস্ক্রিপ্ট নিষ্ক্রিয় করা ব্যবহারকারীদের প্রভাবিত করবে */",
+ "group-autoconfirmed.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু স্বয়ংনিশ্চিতকৃত ব্যবহারকারীদের প্রভাবিত করবে */",
+ "group-user.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু নিবন্ধিত ব্যবহারকারীদের প্রভাবিত করবে */",
+ "group-bot.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু বটকে প্রভাবিত করবে */",
+ "group-sysop.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু প্রশাসকদের প্রভাবিত করবে */",
+ "group-bureaucrat.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু ব্যুরোক্র্যাটদের প্রভাবিত করবে */",
+ "common.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট সকল ব্যবহারকারীর জন্য সকল পাতায় লোড হবে। */",
+ "group-autoconfirmed.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু স্বয়ংনিশ্চিতকৃত ব্যবহারকারীদের জন্য লোড হবে */",
+ "group-user.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু নিবন্ধিত ব্যবহারকারীদের জন্য লোড হবে */",
+ "group-bot.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু বটের জন্য লোড হবে */",
+ "group-sysop.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু প্রশাসকদের জন্য লোড হবে */",
+ "group-bureaucrat.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু ব্যুরোক্র্যাটদের জন্য লোড হবে */",
"anonymous": "{{SITENAME}} এর বেনামী {{PLURAL:$1|ব্যবহারকারী|ব্যবহারকারীবৃন্দ}}",
"siteuser": "{{SITENAME}} ব্যবহারকারী $1",
"anonuser": "{{SITENAME}} বেনামী ব্যবহারকারী $1",
"newimages-summary": "এই বিশেষ পাতা সর্বশেষ আপলোডকৃত ফাইল দেখাবে।",
"newimages-legend": "ছাঁকনি",
"newimages-label": "ফাইলের নাম (অথবা এর কোন অংশ):",
+ "newimages-user": "আইপি ঠিকানা বা ব্যবহারকারী নাম",
"newimages-showbots": "বটের আপলোড গুলো দেখাও।",
"newimages-hidepatrolled": "টহলকৃত আপলোড লুকানো হোক",
"noimages": "দেখার মত কিছু নেই।",
"exif-copyrighted-false": "কপিরাইট সংক্রান্ত তথ্য নেই",
"exif-photometricinterpretation-0": "কালো এবং সাদা (সাদা হল 0)",
"exif-photometricinterpretation-1": "কালো এবং সাদা (কালো হল 0)",
+ "exif-photometricinterpretation-3": "প্যালেট",
+ "exif-photometricinterpretation-4": "স্বচ্ছতা মাস্ক",
+ "exif-photometricinterpretation-5": "পৃথকীকৃত (সম্ভবত CMYK)",
"exif-unknowndate": "অজানা তারিখ",
"exif-orientation-1": "সাধারণ",
"exif-orientation-2": "অনুভূমিকভাবে উল্টানো",
"watchlistedit-normal-title": "নজরতালিকা সম্পাদনা করো",
"watchlistedit-normal-legend": "নজর তালিকা থেকে শিরোনামসমূহ মুছে ফেলো",
"watchlistedit-normal-explain": "আপনার নজরতালিকায় রাখা পাতার শিরোনামগুলি নিচে দেখানো হয়েছে।\nকোন শিরোনাম সরিয়ে নিতে চাইলে পাশের বাক্সে টিক দিন এবং \"{{int:Watchlistedit-normal-submit}}\"-এ ক্লিক করুন।\nআপনি [[Special:EditWatchlist/raw|মূল তালিকাটিও]] সম্পাদনা করতে পারেন।",
- "watchlistedit-normal-submit": "শিরà§\8bনামà¦\97à§\81লি সরিয়à§\87 ফà§\87লা হà§\8bà¦\95",
+ "watchlistedit-normal-submit": "শিরà§\8bনামà¦\97à§\81লি সরান",
"watchlistedit-normal-done": "{{PLURAL:$1|1 শিরোনাম|$1 শিরোনামসমূহ}} আপনার নজর তালিকা থেকে মুছে ফেলা হয়েছে:",
"watchlistedit-raw-title": "অশোধিত নজর তালিকা সম্পাদনা করুন",
"watchlistedit-raw-legend": "অশোধিত নজরতালিকা সম্পাদনা করুন",
"watchlistedit-raw-explain": "আপনার নজরতালিকায় রাখা পাতার শিরোনামগুলি নিচে দেখানো হয়েছে, এই তালিকাতে নতুন শিরোনাম যোগ করা যাবে বা শিরোনাম সরিয়ে নেওয়া যাবে;\nপ্রতিটি লাইনে একটি করে শিরনাম দেখানো হচ্ছে।\nশেষ হলে \"{{int:Watchlistedit-raw-submit}}\"-এ ক্লিক করুন।\nআপনি [[Special:EditWatchlist|আদর্শ সম্পাদনা সরঞ্জাম]]-ও ব্যবহার করতে পারেন।",
"watchlistedit-raw-titles": "শিরোনাম:",
- "watchlistedit-raw-submit": "নà¦\9cরতালিà¦\95া হালনাà¦\97াদ à¦\95রা হà§\8bà¦\95",
+ "watchlistedit-raw-submit": "নà¦\9cরতালিà¦\95া হালনাà¦\97াদ à¦\95রà§\81ন",
"watchlistedit-raw-done": "আপনার নজর তালিকা হালনাগাদ করা হয়েছে।",
"watchlistedit-raw-added": "{{PLURAL:$1|1 শিরোনাম|$1 শিরোনামসমূহ}} যোগ করা হয়েছে:",
"watchlistedit-raw-removed": "{{PLURAL:$1|1 শিরোনাম|$1 শিরোনামসমূহ}} মুছে ফেলা হয়েছে:",
"newimages-summary": "Diskouez a ra ar bajenn dibar-mañ roll ar restroù diwezhañ bet enporzhiet.",
"newimages-legend": "Sil",
"newimages-label": "Anv ar restr (pe darn anezhi) :",
+ "newimages-user": "Chomlec'h IP pe anv implijer",
"newimages-showbots": "Diskouez an ezporzhiadennoù graet gant robotoù",
"newimages-hidepatrolled": "Kuzhat ar enporzhiadennoù gwiriet",
"noimages": "Netra da welet.",
"post-expand-template-argument-warning": "Varování: Tato stránka obsahuje alespoň jeden argument šablony, který je po rozbalení příliš velký.\nTyto argumenty byly vynechány.",
"post-expand-template-argument-category": "Stránky obsahující vynechané argumenty šablon",
"parser-template-loop-warning": "Nalezena smyčka šablon: [[$1]]",
+ "template-loop-category": "Stránky se smyčkami šablon",
+ "template-loop-category-desc": "Stránka obsahuje smyčku šablon, tj. šablonu, která je vložená sama do sebe.",
"parser-template-recursion-depth-warning": "Překročen limit hloubky rekurzivního vkládání šablon ($1)",
"language-converter-depth-warning": "Překročen limit vnoření u jazykové konverze ($1)",
"node-count-exceeded-category": "Stránky překračující počet uzlů",
"newimages-summary": "Diese Spezialseite zeigt die zuletzt hochgeladenen Dateien an.",
"newimages-legend": "Filter",
"newimages-label": "Dateiname (oder ein Teil davon):",
+ "newimages-user": "IP-Adresse oder Benutzername",
"newimages-showbots": "Von Bots hochgeladene Dateien anzeigen",
"newimages-hidepatrolled": "Kontrollierte Dateien ausblenden",
"noimages": "Keine Dateien gefunden.",
"watchthis": "Şıma bewnê ena perre",
"savearticle": "Perre qeyd ke",
"savechanges": "Vırnayışan qeyd kerê",
- "publishpage": "Perer bıhesırne",
- "publishchanges": "Vurnayışa vıla ke",
+ "publishpage": "Riperri bare ke",
+ "publishchanges": "Vırnayışan aşkera ke",
"preview": "Verqayt",
"showpreview": "Verasayışi bımocne",
"showdiff": "Vurnayışan bımotne",
"tooltip-ca-nstab-category": "Pela kategoriye bıvêne",
"tooltip-minoredit": "Ney vırnayışo werdi nışan bıkerê",
"tooltip-save": "Vurnayışanê xo qeyd ke",
- "tooltip-publish": "Vurnayışê xo vıla kı",
+ "tooltip-publish": "Vırnayışê xo aşkera ke",
"tooltip-preview": "Vurnayışanê xo çım ra bıviyarnê. Qeydkerdış ra ver bıgurê cı!",
"tooltip-diff": "Kamci vırnayışê ke şıma nuştey sero kerdê, inan bıvênê.",
"tooltip-compareselectedversions": "Ena per de ferqê rewziyonan de dı weçinaya bıvinê",
"newimages-summary": "This special page shows the last uploaded files.",
"newimages-legend": "Filter",
"newimages-label": "Filename (or a part of it):",
+ "newimages-user": "IP address or username",
"newimages-showbots": "Show uploads by bots",
"newimages-hidepatrolled": "Hide patrolled uploads",
"noimages": "Nothing to see.",
"logentry-newusers-autocreate": "Se ha {{GENDER:$2|creado}} automáticamente la cuenta de {{GENDER:$4|usuario|usuaria}} $1",
"logentry-protect-move_prot": "$1 {{GENDER:$2|trasladó}} las preferencias de protección de $4 a $3",
"logentry-protect-unprotect": "$1 {{GENDER:$2|eliminó}} la protección de $3",
- "logentry-protect-protect": "$1 {{GENDER:$2|protegió}} $3 $4",
- "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protegió}} a $3 $4 [en cascada]",
+ "logentry-protect-protect": "$1 {{GENDER:$2|protegió}} la página $3 $4",
+ "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protegió}} la página $3 $4 [en cascada]",
"logentry-protect-modify": "$1 {{GENDER:$2|cambió}} el nivel de protección de $3 $4",
"logentry-protect-modify-cascade": "$1 {{GENDER:$2|cambió}} el nivel de protección de $3 $4 [en cascada]",
"logentry-rights-rights": "$1 {{GENDER:$2|modificó}} los grupos a los que pertenece {{GENDER:$6|$3}}: de $4 a $5",
"right-createpage": "Luua lehekülgi (mis pole aruteluleheküljed)",
"right-createtalk": "Luua arutelulehekülgi",
"right-createaccount": "Luua uusi kasutajakontosid",
+ "right-autocreateaccount": "Automaatselt välise kasutajakontoga sisse logida",
"right-minoredit": "Märkida muudatusi pisimuudatusteks",
"right-move": "Teisaldada lehekülgi",
"right-move-subpages": "Teisaldada lehekülgi koos nende alamlehtedega",
"action-createpage": "seda lehekülge luua",
"action-createtalk": "seda arutelulehekülge luua",
"action-createaccount": "seda kasutajakontot luua",
+ "action-autocreateaccount": "välise kasutajakontoga automaatselt sisse logida",
"action-history": "vaadata selle lehekülje ajalugu",
"action-minoredit": "seda muudatust pisimuudatuseks märkida",
"action-move": "seda lehekülge teisaldada",
"newimages-summary": "Sellel erilehel on viimati üles laaditud failid.",
"newimages-legend": "Filter",
"newimages-label": "Failinimi (või selle osa):",
+ "newimages-user": "IP-aadress või kasutajanimi",
"newimages-showbots": "Näita robotite üles laaditud faile",
"newimages-hidepatrolled": "Peida kontrollitud failid",
"noimages": "Uusi pilte ei ole.",
"authform-wrongtoken": "Vale luba",
"specialpage-securitylevel-not-allowed-title": "Pole lubatud",
"specialpage-securitylevel-not-allowed": "Kahjuks ei lubata sul seda lehekülge kasutada, kuna sinu identiteeti ei õnnestunud tõestada.",
+ "authpage-cannot-login": "Sisselogimisega ei õnnestu alustada.",
+ "authpage-cannot-login-continue": "Sisselogimisega ei õnnestu jätkata. Suure tõenäosusega on sinu seansi ajalõpp möödunud.",
+ "authpage-cannot-create": "Konto loomisega ei õnnestu alustada.",
+ "authpage-cannot-create-continue": "Konto loomisega ei õnnestu jätkata. Suure tõenäosusega on sinu seansi ajalõpp möödunud.",
+ "authpage-cannot-link": "Konto linkimisega ei õnnestu alustada.",
+ "authpage-cannot-link-continue": "Konto linkimisega ei õnnestu jätkata. Suure tõenäosusega on sinu seansi ajalõpp möödunud.",
"changecredentials": "Autentimisandmete muutmine",
"changecredentials-submit": "Muuda autentimisandmed",
"changecredentials-success": "Sinu autentimisandmed on muudetud.",
"removecredentials-success": "Sinu autentimisandmed on eemaldatud.",
"credentialsform-provider": "Andmete tüüp:",
"credentialsform-account": "Konto nimi:",
+ "authenticationdatachange-ignored": "Autentimisandmete muutmine jäi rahuldamata. Võimalik, et ühtegi pakkujat polnud häälestatud.",
"userjsispublic": "Pea silmas, et JavaScripti alamleheküljed ei tohiks sisaldada konfidentsiaalseid andmeid, kuna neid näevad teised kasutajad.",
"usercssispublic": "Palun pane tähele: CSS-alamleheküljel ei peaks olema konfidentsiaalseid andmeid, kuna teised kasutajad näevad seda.",
"restrictionsfield-badip": "Vigane IP-aadress või -aadressivahemik: $1",
"mediastatistics-table-count": "Tiedostojen lukumäärä",
"mediastatistics-table-totalbytes": "Yhteenlaskettu koko",
"mediastatistics-header-unknown": "Tuntematon",
- "mediastatistics-header-bitmap": "Bitmap-kuvat",
+ "mediastatistics-header-bitmap": "Bittikarttakuvat",
"mediastatistics-header-drawing": "Piirrokset (vektorikuvat)",
"mediastatistics-header-audio": "Audio",
"mediastatistics-header-video": "Videot",
"post-expand-template-argument-category": "Pages contenant des paramètres de modèle non évalués",
"parser-template-loop-warning": "Modèle en boucle détecté : [[$1]]",
"template-loop-category": "Pages avec des boucles de modèle",
- "template-loop-category-desc": "La page contient une boucle de modèle, c.à.d. un modèle qui s’appelle lui-même récursivement.",
+ "template-loop-category-desc": "La page contient une boucle dans le modèle, c.à.d. un modèle qui s’appelle lui-même récursivement.",
"parser-template-recursion-depth-warning": "Limite de profondeur des appels récursifs de modèles dépassée ($1)",
"language-converter-depth-warning": "Limite de profondeur du convertisseur de langue dépassée ($1)",
"node-count-exceeded-category": "Pages dépassant le nombre de nœuds maximal",
"newimages-summary": "Cette page spéciale affiche les derniers fichiers importés.",
"newimages-legend": "Filtre",
"newimages-label": "Nom du fichier (ou une partie de celui-ci) :",
+ "newimages-user": "Adresse IP ou nom d'utilisateur",
"newimages-showbots": "Afficher les imports faits par des robots",
"newimages-hidepatrolled": "Masquer les téléchargements patrouillés",
"noimages": "Aucune image à afficher.",
"confirmemail_sendfailed": "{{SITENAME}} n’a pas pu vous envoyer le courriel de confirmation.\nVeuillez vérifiez que votre adresse de courriel ne comprend aucun caractère incorrect.\n\nLe programme d’envoi de courriel a retourné l’indication suivante : $1",
"confirmemail_invalid": "Code de confirmation incorrect.\nCelui-ci a peut-être expiré.",
"confirmemail_needlogin": "Vous devez vous $1 pour confirmer votre adresse de courriel.",
- "confirmemail_success": "Votre adresse de courriel a été confirmée.\nVous pouvez maintenant vous [[Special:UserLogin|{{MediaWiki:Loginreqlink}}]] et profiter du wiki.",
+ "confirmemail_success": "Votre adresse de courriel a été confirmée.\nVous pouvez maintenant vous [[Special:UserLogin|{{MediaWiki:Loginreqlink/fr}}]] et profiter du wiki.",
"confirmemail_loggedin": "Votre adresse de courriel est maintenant confirmée.",
"confirmemail_subject": "Confirmation d’adresse de courriel pour {{SITENAME}}",
"confirmemail_body": "Quelqu’un, probablement vous, à partir de l’adresse IP $1,\na créé un compte « $2 » avec cette adresse de courriel sur le site {{SITENAME}}.\n\nPour confirmer que ce compte vous appartient vraiment et afin\nd’activer les fonctions de messagerie sur {{SITENAME}},\nveuillez suivre ce lien dans votre navigateur :\n\n$3\n\nSi vous n’avez *pas* créé ce compte, suivez le lien ci-dessous \npour annuler la confirmation de votre adresse courriel :\n\n$5\n\nCe code de confirmation expirera le $4.",
"externaldberror": "Soit y avait une erreur avec la base d'information de certification extérieur, soit vous avez pas la permission de renouveler votre compte extérieur.",
"login": "Connecter",
"nav-login-createaccount": "Connecter / créer un compte",
- "userlogin": "Connecter / créer un compte",
"logout": "Déconnecter",
"userlogout": "Déconnecter",
"notloggedin": "Pas connecté",
- "nologin": "Vous avez pas de compte? '''$1'''.",
- "nologinlink": "Créez un compte",
"createaccount": "Créer un compte",
- "gotaccount": "Vous avez un compte déjà? '''$1'''.",
- "gotaccountlink": "Connectez",
- "userlogin-resetlink": "Oublié vôtre détailes de log in?",
"createacct-emailrequired": "Adresse d'email",
"createacct-emailoptional": "Adresse d'email (optional)",
"createacct-email-ph": "Entres t'adresse d'email",
"createacct-another-email-ph": "Entres adresse d'email",
"createaccountmail": "par e-mail",
- "createaccountreason": "Raison:",
"createacct-reason": "Raison",
"createacct-reason-ph": "Pourquoi crées-tu un autre compte",
"badretype": "Les mots de passe que vous avez mis sont pas pareils.",
"resetpass-temp-password": "Mot de passe temporaire:",
"passwordreset-username": "Nom d'useur:",
"passwordreset-domain": "Domaine:",
- "passwordreset-capture": "Regarder l'email résultant?",
"passwordreset-email": "Adresse d'email:",
"changeemail-none": "(aucun)",
"changeemail-password": "Ton mot de passe sur {{SITENAME}}:",
"userjsyoucanpreview": "'''Tip:''' Brük di „{{int:showpreview}}“-knoop, am din nei JavaScript föör det seekrin tu testin.",
"usercsspreview": "'''Seenk diaram, dat det bluas en föörskau faan din CSS as.'''\n'''Det as noch ei seekert wurden!'''",
"userjspreview": "'''Seenk diaram, dat det bluas en föörskau faan din JavaScript as.'''\n'''Det as noch ei seekert wurden!'''",
- "sitecsspreview": "'''Påås aw dåt dü jüdeer CSS bloot forbekiikest.'''\n'''Dåt as nuch ai spiikerd!'''",
- "sitejspreview": "'''Påås aw dåt dü jüdeer JavaScript code bloot forbekiikest.'''\n'''Dåt as nuch ai spiikerd!'''",
+ "sitecsspreview": "<strong>Paase üüb! Det as bluas en föörskau faan't CSS. Det as noch ei seekert wurden!</strong>",
+ "sitejspreview": "<strong>Paase üüb! Det as bluas en föörskau faan di JavaScript code. Det as noch ei seekert wurden!</strong>",
"userinvalidcssjstitle": "''Paase üüb:''' Skak \"$1\" jaft at ei.\nSeenk diaram, dat faan en brüker iinracht .css- an .js-sidjen mä en letjen buksteew began skel. Bispal:\n''{{ns:user}}:Münsterkjarl/vector.css'' uunsteed faan ''{{ns:user}}:Münsterkjarl/Vector.css''.",
"updated": "(Feranert)",
"note": "'''Paase üüb:'''",
"post-expand-template-argument-warning": "'''Aviso:''' Esta páxina contén, polo menos, un argumento de modelo que ten un tamaño e expansión moi grande.\nEstes argumentos foron omitidos.",
"post-expand-template-argument-category": "Páxinas que conteñen argumentos de modelo omitidos",
"parser-template-loop-warning": "Detectouse un modelo en bucle: [[$1]]",
+ "template-loop-category": "Páxinas con bucles de modelo",
+ "template-loop-category-desc": "A páxina contén un bucle de modelo, por exemplo, un modelo que se chama a si mesmo recursivamente.",
"parser-template-recursion-depth-warning": "Excedeuse o límite de profundidade de recursión do modelo ($1)",
"language-converter-depth-warning": "Excedeuse o límite de profundidade do convertedor de lingua ($1)",
"node-count-exceeded-category": "Páxinas nas que se supera o número de nodos",
"newimages-summary": "Esta páxina especial mostra os últimos ficheiros cargados.",
"newimages-legend": "Filtro",
"newimages-label": "Nome do ficheiro (ou parte del):",
+ "newimages-user": "Enderezo IP ou nome de usuario",
"newimages-showbots": "Mostrar as cargas feitas por bots",
"newimages-hidepatrolled": "Agochar as subidas patrulladas",
"noimages": "Non hai imaxes que mostrar.",
"newimages-summary": "דף מיוחד זה מציג את הקבצים האחרונים שהועלו.",
"newimages-legend": "מסנן",
"newimages-label": "שם הקובץ (או חלק ממנו):",
+ "newimages-user": "כתובת IP או שם משתמש",
"newimages-showbots": "הצגת העלאות שבוצעו על־ידי בוטים",
"newimages-hidepatrolled": "הסתרת העלאות בדוקות",
"noimages": "אין קבצים.",
"post-expand-template-argument-warning": "'''चेतावनी:''' इस पृष्ठ पर किसी साँचे में कम-से-कम एक ऐसा प्राचल है जो बढ़ाने पर बहुत बड़ा हो जायेगा।\nऐसे प्राचलों को छोड़ दिया गया है।",
"post-expand-template-argument-category": "ऐसे पृष्ठ जिनमें प्राचल छोड़े गये हैं",
"parser-template-loop-warning": "साँचा चक्र मिला: [[$1]]",
+ "template-loop-category": "टेम्पलेट लूप वाले पेज",
+ "template-loop-category-desc": "पृष्ठ में एक टेम्पलेट लूप है, अर्थात। एक टेम्पलेट जो स्वयं को पुनरावर्ती रूप से कॉल करता है",
"parser-template-recursion-depth-warning": "साँचा पुनरावर्ती गहराई सीमा पार ($1)",
"language-converter-depth-warning": "भाषा कन्वर्टर गहराई सीमा से बाहर गया ( $1 )",
"node-count-exceeded-category": "पृष्ठ जिनमें नोड-संख्या सीमा पार की गई है",
"prefs-help-recentchangescount": "इसमें हाल के बदलाव, पृष्ठ इतिहास व लॉग शामिल हैं।",
"prefs-help-watchlist-token2": "यह आपकी ध्यानसूची की वेब फ़ीड की गोपनीय चाबी है।\nयह जिसके भी पास होगी वह आपकी ध्यानसूची पढ़ सकेगा, इसिलए इसे किसी के साथ बांटियेगा नहीं।\n[[Special:ResetTokens|इसे रीसेट करने के लिए यहाँ क्लिक करें]]।",
"savedprefs": "आपकी वरीयताएँ संजोई गई हैं।",
- "savedrights": "पà¥\8dरयà¥\8bà¤\95à¥\8dता {{GENDER:$1|$1}} का सदस्य अधिकार सहेजा गया।",
+ "savedrights": "सदसà¥\8dय {{GENDER:$1|$1}} का सदस्य अधिकार सहेजा गया।",
"timezonelegend": "समयमंडल:",
"localtime": "स्थानीय समय:",
"timezoneuseserverdefault": "विकि मूल का उपयोग करें ($1)",
"userrights-user-editname": "सदस्यनाम दें:",
"editusergroup": "सदस्य समूह दिखायें",
"editinguser": "सदस्य '''[[User:$1|$1]]''' $2 के अधिकार बदलें\n{{GENDER:$1|सदस्य}} के सदस्य अधिकार बदले जा रहे हैं <strong>[[User:$1|$1]]</strong> $2",
+ "viewinguserrights": "{{GENDER:$1|user}} के उपयोगकर्ता अधिकारों को देखना <strong>[[User:$1|$1]]</strong> $2",
"userrights-editusergroup": "सदस्य समूहों का संपादन करें",
- "userrights-viewusergroup": "सदस्य समूह देखें",
+ "userrights-viewusergroup": "{{GENDER:$1|सदस्य}} समूह देखें",
"saveusergroups": "{{GENDER:$1|सदस्य}} समूह सहेजें",
"userrights-groupsmember": "निम्न {{PLURAL:$1|समूह|समूहों}} का सदस्य:",
"userrights-groupsmember-auto": "निम्न {{PLURAL:$1|समूह|समूहों}} का अंतर्निहित सदस्य:",
- "userrights-groups-help": "आप इस सदस्य की समूह-सदस्यता बदल सकते हैं:\n* बक्से पर सही का निशान लगे होने का अर्थ है कि सदस्य उस समूह में है।\n* बक्से पर सही का निशान न लगे होने का अर्थ है कि सदस्य उस समूह में नहीं है।\n* एक * का अर्थ है कि एक बार जोड़ने के बाद वह समूह हटा नहीं सकते हैं, और हटाने के बाद जोड़ नहीं सकते हैं।",
+ "userrights-groups-help": "आप इस सदस्य की समूह-सदस्यता बदल सकते हैं:\n* बक्से पर सही का निशान लगे होने का अर्थ है कि सदस्य उस समूह में है।\n* बक्से पर सही का निशान न लगे होने का अर्थ है कि सदस्य उस समूह में नहीं है।\n* एक * का अर्थ है कि एक बार जोड़ने के बाद वह समूह हटा नहीं सकते हैं, और हटाने के बाद जोड़ नहीं सकते हैं।\n* एक # सूचित करता है कि आप केवल इस समूह के समाप्ति समय को वापस रख सकते हैं; आप इसे आगे नहीं बढ़ा सकते हैं",
"userrights-reason": "कारण:",
"userrights-no-interwiki": "आपको अन्य विकियों पर सदस्य अधिकार बदलने की अनुमति नहीं हैं।",
"userrights-nodatabase": "डाटाबेस $1 या तो मौजूद नहीं है या फिर स्थानीय नहीं है।",
"userrights-expiry-options": "एक दिन:1 day,एक सप्ताह:1 week,एक महीना:1 month,तीन महीने:3 months,छः महीने:6 months,एक वर्ष:1 year",
"userrights-invalid-expiry": "\"$1\" समूह के लिए समाप्ती तिथि अमान्य है।",
"userrights-expiry-in-past": "\"$1\" समूह हेतु समाप्ती का समय पहले ही बीत चुका है।",
+ "userrights-cannot-shorten-expiry": "आप \"$1\" समूह की समाप्ति को आगे नहीं बढ़ा सकते हैं। केवल इस समूह को जोड़ने और निकालने की अनुमति वाले उपयोगकर्ता आगे समाप्ति समय ला सकते हैं।",
"userrights-conflict": "सदस्य अधिकार बदलावों में अंतर्विरोध! कृपया अपने बदलाव जाँचें और पुनः सुनिश्चित करें।",
"group": "समूह:",
"group-user": "सदस्य",
"action-delete": "इस पृष्ठ को हटाने",
"action-deleterevision": "अवतरण हटायें",
"action-deletelogentry": "लॉग प्रविष्टियाँ को हटाए",
- "action-deletedhistory": "à¤\87स पà¥\83षà¥\8dठà¤\95à¥\87 मिà¤\9fà¥\87 à¤\87तिहास à¤\95à¥\8b दà¥\87à¤\96नà¥\87",
+ "action-deletedhistory": "पà¥\83षà¥\8dठà¤\95à¥\87 मिà¤\9fà¥\87 à¤\87तिहास à¤\95à¥\8b दà¥\87à¤\96ना",
"action-deletedtext": "हटाये गए अवतरण का पाठ देखें",
"action-browsearchive": "हटाएँ गए पृष्ठों में खोजने",
- "action-undelete": "à¤\87स पà¥\83षà¥\8dठà¤\95à¥\8b पà¥\81नरà¥\8dसà¥\8dथापित à¤\95रनà¥\87",
- "action-suppressrevision": "à¤\87स à¤\9bिपà¥\87 à¤\85वतरण को देखने और पुनर्स्थापित करने",
+ "action-undelete": "पृष्ठ को पुनर्स्थापित करने",
+ "action-suppressrevision": "à¤\9bिपà¥\87 à¤\85वतरणà¥\8bà¤\82 को देखने और पुनर्स्थापित करने",
"action-suppressionlog": "इस निजी लॉग को देखने",
"action-block": "इस सदस्य को संपादन करने से ब्लॉक करने",
"action-protect": "इस पृष्ठ के सुरक्षा स्तर बदलने",
"rcfilters-empty-filter": "कोई सक्रिय फिल्टर नहीं। सभी योगदान दिखाए गए है।",
"rcfilters-filterlist-title": "फिल्टर",
"rcfilters-filterlist-whatsthis": "यह क्या है?",
+ "rcfilters-filterlist-feedbacklink": "नए (बीटा) फिल्टर पर प्रतिक्रिया दें",
"rcfilters-highlightbutton-title": "Highlight results",
"rcfilters-highlightmenu-title": "रंग चुनें",
+ "rcfilters-highlightmenu-help": "इस गुण को हाइलाइट करने के लिए एक रंग चुनें",
"rcfilters-filterlist-noresults": "कोई फिल्टर नहीं पाया",
+ "rcfilters-noresults-conflict": "कोई भी परिणाम नहीं मिला क्योंकि खोज मापदंड संघर्ष में है",
+ "rcfilters-state-message-subset": "इस फिल्टर का कोई प्रभाव नहीं है क्योंकि इसका परिणाम निम्न, व्यापक {{PLURAL: $2 |फ़िल्टर|फिल्टर}} के साथ शामिल है (इसे भेद करने के लिए हाइलाइट करने की कोशिश करें): $1",
+ "rcfilters-state-message-fullcoverage": "किसी समूह में सभी फ़िल्टर चुनना कोई भी नहीं चुनने के समान है इसलिए इस फ़िल्टर का कोई प्रभाव नहीं है समूह में शामिल हैं: $1",
"rcfilters-filtergroup-registration": "उपयोगकर्ता पंजीकरण",
"rcfilters-filter-registered-label": "पंजीकृत:",
"rcfilters-filter-registered-description": "लॉग-इन संपादक।",
"rcfilters-filter-unregistered-label": "अपंजीकृत",
"rcfilters-filter-unregistered-description": "संपादक जो लॉग इन नहीं हैं।",
+ "rcfilters-filtergroup-authorship": "लेखकों को संपादित करें",
"rcfilters-filter-editsbyself-label": "आपके अपने संपादन",
"rcfilters-filter-editsbyself-description": "आपके द्वारा संपादित",
"rcfilters-filter-editsbyother-label": "दूसरों के द्वारा संपादित",
+ "rcfilters-filter-editsbyother-description": "अन्य उपयोगकर्ताओं द्वारा बनाई गए संपादन (आपके द्वारा नहीं)",
+ "rcfilters-filtergroup-userExpLevel": "अनुभवी स्तर (केवल पंजीकृत सदस्यों के लिए)",
+ "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "अनुभव फ़िल्टर केवल पंजीकृत उपयोगकर्ता पाते हैं इसलिए यह फ़िल्टर \"अपंजीकृत\" फ़िल्टर के साथ संघर्ष करता है।",
"rcfilters-filter-user-experience-level-newcomer-label": "अपरिचित",
"rcfilters-filter-user-experience-level-newcomer-description": "4 दिनों की गतिविधि और 10 सम्पादन से कम।",
"rcfilters-filter-user-experience-level-learner-label": "शिक्षार्थियों",
"rcfilters-filter-unpatrolled-description": "परीक्षित चिन्हित न किए सम्पादन।",
"rcfilters-filtergroup-significance": "महत्व",
"rcfilters-filter-minor-label": "छोटा संपादन",
+ "rcfilters-filter-minor-description": "लेखक का संपादन छोटा संपादन के रूप में लेबल किया गया है।",
"rcfilters-filter-major-label": "गैर-मामूली संपादन",
"rcfilters-filtergroup-changetype": "बदलाव के प्रकार:",
"rcfilters-filter-pageedits-label": "पृष्ठ संपादन",
+ "rcfilters-filter-pageedits-description": "विकि सामग्री, चर्चा, श्रेणी विवरणों के संपादन ....",
"rcfilters-filter-newpages-label": "पृष्ठ कृतियों",
"rcfilters-filter-newpages-description": "संपादन जिससे नया पृष्ट बना",
"rcfilters-filter-categorization-label": "श्रेणी परिवर्तन",
+ "rcfilters-filter-categorization-description": "श्रेणियों से पृष्ठों के रिकॉर्ड्स को जोड़ा या निकाला जा सकता है",
+ "rcfilters-filter-logactions-label": "लॉग की गई कार्रवाई",
+ "rcfilters-filter-logactions-description": "प्रशासनिक कार्रवाई, खाता निर्माण, पृष्ठ विलोपन, अपलोड ....",
"rcnotefrom": "नीचे <strong>$2</strong> के बाद से (<strong>$1</strong> तक) {{PLURAL:$5|हुआ बदलाव दर्शाया गया है|हुए बदलाव दर्शाए गये हैं}}।",
"rclistfrom": "$3 $2 से नये बदलाव दिखाएँ",
"rcshowhideminor": "छोटे बदलाव $1",
"feedback-thanks": "धन्यवाद! आपकी प्रतिक्रिया पृष्ठ में नियुक्त किया गया है \"[ $2 $1 ]\"।",
"feedback-thanks-title": "धन्यवाद!",
"feedback-useragent": "सदस्य कर्ता:",
- "searchsuggest-search": "खोजें {{SITENAME}}",
+ "searchsuggest-search": "{{SITENAME}} में खोजें",
"searchsuggest-containing": "...से युक्त",
"api-error-badtoken": "आंतरिक त्रुटि: बुरी टोकन।",
"api-error-emptypage": "नए खाली पृष्ठ बनाने की अनुमति नहीं है।",
"htmlform-time-invalid": "Unesena vrijednost nije prepoznati format vremena. Pokušajte koristiti format HH:MM:SS.",
"htmlform-datetime-toohigh": "Uneseni datum i vrijeme su veći od $1",
"logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
- "logentry-delete-delete_redir": "$1 je premještanjem {{GENDER:$2|pobrisao|pobrisala}} preusmjeravanje $3",
+ "logentry-delete-delete_redir": "$1 premještanjem je {{GENDER:$2|pobrisao|pobrisala}} preusmjeravanje $3",
"logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
"logentry-delete-event": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|zapisa u evidenciji|$5 zapisa u evidenciji}} na $3: $4",
"logentry-delete-revision": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|uređivanja|$5 uređivanja}} na stranici $3: $4",
"newimages-summary": "Questa pagina speciale mostra i file caricati più di recente.",
"newimages-legend": "Filtra",
"newimages-label": "Nome file (o una parte di esso):",
+ "newimages-user": "Indirizzo IP o nome utente",
"newimages-showbots": "Mostra caricamenti di bot",
"newimages-hidepatrolled": "Nascondi caricamenti verificati",
"noimages": "Non c'è nulla da vedere.",
"yourrealname": "실명:",
"yourlanguage": "언어:",
"yourvariant": "언어 변종:",
- "prefs-help-variant": "이 위키 내용을 볼 때 사용할 언어 변종이나 철자 체계를 선택하세요.",
+ "prefs-help-variant": "이 위키 내용을 표시하기 위해 사용할 언어 변종이나 철자 체계를 선택하세요.",
"yournick": "새 서명:",
"prefs-help-signature": "토론 문서에 글을 쓴 후에는 마지막에 서명을 해야 합니다. “<nowiki>~~~~</nowiki>” 기호를 추가하면 서명과 글 작성 시각이 자동으로 입력됩니다.",
"badsig": "서명이 잘못되었습니다.\nHTML 태그를 확인하세요.",
"upload_directory_read_only": "파일 저장 디렉터리($1)에 쓰기 권한이 없습니다.",
"uploaderror": "올리기 오류",
"upload-recreate-warning": "<strong>경고: 해당 이름으로 된 파일이 삭제되었거나 이동되었습니다.</strong>\n\n편의를 위해 이 문서에 대한 삭제와 이동 기록을 다음과 같이 제공합니다:",
- "uploadtext": "파일을 올리기 위해서는 아래의 양식을 채워주세요.\n[[Special:FileList|파일 목록]]에서 이전에 올라온 파일을 검색할 수 있습니다. [[Special:Log/upload|올리기 기록]]에는 파일이 올라온 기록이 남습니다. 삭제 기록은 [[Special:Log/delete|삭제 기록]]에서 볼 수 있습니다.\n\n문서에 파일을 넣으려면 아래 방법 중 하나를 사용하세요.\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' 파일의 온전한 모양을 사용하고자 할 때\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code>''' 파일의 너비를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' 파일을 직접 보여주지 않고 파일로 바로 링크할 때",
+ "uploadtext": "파일을 올리기 위해서는 아래의 양식을 채워주세요.\n[[Special:FileList|파일 목록]]에서 이전에 올라온 파일을 검색할 수 있습니다. [[Special:Log/upload|올리기 기록]]에는 파일이 올라온 기록이 남습니다. 삭제 기록은 [[Special:Log/delete|삭제 기록]]에서 볼 수 있습니다.\n\n문서에 파일을 넣으려면 아래 방법 중 하나를 사용하세요.\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code></strong> 파일의 온전한 모양을 사용하고자 할 때\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code></strong> 파일의 너비를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code></strong> 파일을 직접 표시하지 않고 파일로 바로 링크할 때",
"upload-permitted": "허용된 파일 {{PLURAL:$2|형식}}: $1",
"upload-preferred": "권장 파일 {{PLURAL:$2|형식}}: $1",
"upload-prohibited": "금지된 파일 {{PLURAL:$2|형식}}: $1",
"log": "기록 목록",
"logeventslist-submit": "보기",
"all-logs-page": "모든 공개 기록",
- "alllogstext": "{{SITENAME}}ì\97\90ì\84\9cì\9d\98 기ë¡\9dì\9d´ 모ë\91\90 ë\82\98ì\99\80 ì\9e\88ì\8aµë\8b\88ë\8b¤.\n기ë¡\9d ì¢\85ë¥\98, ì\82¬ì\9a©ì\9e\90 ì\9d´ë¦\84, 문ì\84\9c ì\9d´ë¦\84ì\9d\84 ì\84 í\83\9dí\95´서 볼 수 있습니다. (대소문자를 구별합니다.)",
+ "alllogstext": "{{SITENAME}}ì\9d\98 ì\82¬ì\9a©í\95 ì\88\98 ì\9e\88ë\8a\94 기ë¡\9dì\9d´ 모ë\91\90 í\91\9cì\8b\9cë\90\98ì\96´ ì\9e\88ì\8aµë\8b\88ë\8b¤.\n기ë¡\9d ì¢\85ë¥\98, ì\82¬ì\9a©ì\9e\90 ì\9d´ë¦\84, ì\98\81í\96¥ì\9d\84 ë°\9bë\8a\94 문ì\84\9cì\9d\84 ì\84 í\83\9dí\95´ì\84\9c ë²\94ì\9c\84를 ì¢\81í\98\80서 볼 수 있습니다. (대소문자를 구별합니다.)",
"logempty": "일치하는 항목이 없습니다.",
"log-title-wildcard": "다음 글로 시작하는 제목 검색",
"showhideselectedlogentries": "선택한 기록 항목 보이기/숨기기",
"newimages-summary": "이 특수 문서는 최근에 올라온 파일을 나열하고 있습니다.",
"newimages-legend": "필터",
"newimages-label": "파일 이름 (또는 그 일부분):",
+ "newimages-user": "IP 주소 또는 사용자 이름",
"newimages-showbots": "봇이 올린 것 보기",
"newimages-hidepatrolled": "점검한 업로드 숨기기",
"noimages": "그림이 없습니다.",
"metadata-help": "이 파일은 카메라나 스캐너가 파일을 만들거나 디지털화하는 데 사용하기위해 기록한 부가 정보를 포함하고 있습니다.\n프로그램에서 파일을 편집한 경우, 새로 저장한 파일에 일부 부가 정보가 빠질 수 있습니다.",
"metadata-expand": "자세한 정보 보이기",
"metadata-collapse": "자세한 정보 숨기기",
- "metadata-fields": "파일 메타데이터 표가 접혀 있을 때, 이 메시지에 올라와 있는 다음 속성값만이 기본적으로 보이게 됩니다.\n나머지 값은 자동적으로 숨겨집니다.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+ "metadata-fields": "그림 메타데이터 표가 접혀 있을 때, 이 메시지에 나열되어 있는 다음 메타데이터 필드가 그림 문서 표시에 포함됩니다.\n나머지는 기본적으로 숨겨집니다.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
"exif-imagewidth": "너비",
"exif-imagelength": "높이",
"exif-bitspersample": "픽셀당 비트 수",
"authprovider-confirmlink-request-label": "연결할 계정",
"authprovider-confirmlink-success-line": "$1: 연결을 성공했습니다.",
"authprovider-confirmlink-failed": "계정 연결을 완전히 성공하지 못했습니다: $1",
- "authprovider-confirmlink-ok-help": "연결 실패 메시지를 보여준 뒤에도 계속합니다.",
+ "authprovider-confirmlink-ok-help": "연결 실패 메시지를 표시한 뒤에도 계속합니다.",
"authprovider-resetpass-skip-label": "건너뛰기",
"authprovider-resetpass-skip-help": "비밀번호 재설정을 건너뜁니다.",
"authform-nosession-login": "인증은 성공했으나 사용자의 브라우저가 로그인 상태를 저장하지 못했습니다.\n\n$1",
"newimages-summary": "Dës Spezialsäit weist eng Lëscht mat de Fichieren déi als lescht eropgeluede goufen.",
"newimages-legend": "Filter",
"newimages-label": "Numm vum Fichier (oder en Deel dovun):",
+ "newimages-user": "IP-Adress oder Benotzernumm",
"newimages-showbots": "Vu Botten eropgeluede Fichiere weisen",
"newimages-hidepatrolled": "Nogekuckt Fichiere verstoppen",
"noimages": "Keng Biller fonnt.",
"watchthis": "Stebėti šį puslapį",
"savearticle": "Išsaugoti puslapį",
"savechanges": "Išsaugoti pakeitimus",
- "publishpage": "Skelbti puslapį",
- "publishchanges": "Skelbti pakeitimus",
+ "publishpage": "Išsaugoti puslapį",
+ "publishchanges": "Išsaugoti pakeitimus",
"preview": "Peržiūra",
"showpreview": "Rodyti peržiūrą",
"showdiff": "Rodyti skirtumus",
"editlink": "kohendele",
"viewsourcelink": "Kačo algukoodu",
"editsectionhint": "Kohendele tädä kohtua: $1",
- "toc": "Sizäldö",
+ "toc": "Syväindö",
"showtoc": "ozuttua",
- "hidetoc": "peittiä",
+ "hidetoc": "peitä",
"collapsible-collapse": "Peitä",
"collapsible-expand": "Levitä",
"confirmable-confirm": "{{GENDER:$1|Oletgo}} varmu?",
"password-change-forbidden": "Et voi vaihtua peittosanoi täs wikis.",
"login": "Kirjuttai",
"nav-login-createaccount": "Kirjuttai libo registriiruiččei",
- "userlogin": "Kirjuttai libo registriiruiččei",
- "userloginnocreate": "Kirjuttai",
"logout": "Kirjuttai ullos",
"userlogout": "Kirjuttai ullos",
"notloggedin": "Ei kirjutannuhes",
"userlogin-noaccount": "Ei ole tilii?",
"userlogin-joinproject": "Yhty {{SITENAME}}",
- "nologin": "Ei ole tilii? $1",
- "nologinlink": "Luaji tili",
"createaccount": "Registriiruiččei",
- "gotaccount": "Ollou sinul jo tunnus? $1",
- "gotaccountlink": "Kirjuttai",
- "userlogin-resetlink": "Unohtitgo sinun käyttäinimen/peittosanan?",
"userlogin-resetpassword-link": "Unohtitgo sinun peittosanan?",
"userlogin-helplink2": "Abuu kirjuttamizeh",
"userlogin-loggedin": "Olet jo kirjutannuhes nimel {{GENDER:$1|$1}}.\nKäytä al olijua ankiettua ku kirjuttuakseh eri käyttäjänny.",
"createacct-email-ph": "Kirjuta sinun sähköpoštuadressu",
"createacct-another-email-ph": "Kirjuta sinun sähköpoštuadressu",
"createacct-realname": "Tovelline nimi (omatahtoine tiedo)",
- "createaccountreason": "Syy:",
"createacct-reason": "Syy",
"createacct-reason-ph": "Mindäh olet luadimas tostu käyttäitilii",
"createacct-submit": "Luaji tili",
"prefs-changeemail": "Vaihta libo ota iäre sähköpoštuadressu",
"prefs-setemail": "Kirjuta sähköpoštuadressu",
"saveprefs": "Tallenda",
- "rows": "Riädyy:",
"searchresultshead": "Eččie",
"timezoneregion-africa": "Afriekku",
"timezoneregion-america": "Ameriekku",
"rcshowhideanons-show": "Ozuta",
"rcshowhideanons-hide": "Peitä",
"rcshowhidepatr-show": "Ozuttua",
- "rcshowhidepatr-hide": "Peittiä",
+ "rcshowhidepatr-hide": "Peitä",
"rcshowhidemine": "$1 minun kohendukset",
"rcshowhidemine-show": "Ozuta",
"rcshowhidemine-hide": "Peitä",
"newimages-summary": "Na tej stronie specjalnej prezentowane są ostatnio przesłane pliki.",
"newimages-legend": "Filtruj",
"newimages-label": "Nazwa pliku (lub jej fragment):",
+ "newimages-user": "Adres IP lub nazwa użytkownika",
"newimages-showbots": "Pokaż pliki przesłane przez boty",
"newimages-hidepatrolled": "Ukryj sprawdzone pliki",
"noimages": "Brak plików do pokazania.",
"!Silent",
"Joao Xavier",
"Nahime2015",
- "Alex Great"
+ "Alex Great",
+ "EVinente"
]
},
"tog-underline": "Sublinhar links:",
"login": "Autenticar-se",
"login-security": "Verificar sua identidade",
"nav-login-createaccount": "Entrar / criar conta",
- "userlogin": "Entrar / criar conta",
- "userloginnocreate": "Entrar",
"logout": "Sair",
"userlogout": "Sair",
"notloggedin": "Não autenticado(a)",
"userlogin-noaccount": "Não possui uma conta?",
"userlogin-joinproject": "Junte-se ao projeto {{SITENAME}}",
- "nologin": "Não possui uma conta? $1.",
- "nologinlink": "Criar uma conta",
"createaccount": "Criar conta",
- "gotaccount": "Já possui uma conta? '''$1'''.",
- "gotaccountlink": "Autenticar-se",
- "userlogin-resetlink": "Esqueceu-se do seu nome de usuário ou da senha?",
"userlogin-resetpassword-link": "Esqueceu sua senha?",
"userlogin-helplink2": "Ajuda com o login",
"userlogin-loggedin": "Você já está conectado como {{GENDER:$1|$1}}.\nUse o formulário abaixo para iniciar sessão como outro usuário.",
"createaccountmail": "Usar uma senha aleatória e temporária que será enviada ao endereço de e-mail especificado a seguir",
"createaccountmail-help": "Pode ser utilizado para criar uma conta para outra pessoa sem saber a senha.",
"createacct-realname": "Nome real (opcional)",
- "createaccountreason": "Motivo:",
"createacct-reason": "Motivo",
"createacct-reason-ph": "Por que você está criando outra conta",
"createacct-reason-help": "Mensagem mostrada no registro de criação de conta",
"rcfilters-activefilters": "Filtros ativos",
"rcfilters-restore-default-filters": "Restaurar filtros padrão",
"rcfilters-clear-all-filters": "Limpar todos os filtros",
- "rcfilters-search-placeholder": "Filtrar alterações recentes (procurar ou começar a digitar)",
+ "rcfilters-search-placeholder": "Filtrar mudanças recentes (procurar ou começar a digitar)",
"rcfilters-invalid-filter": "Filtro inválido",
"rcfilters-empty-filter": "Nenhum filtro ativo. Todas as contribuições são mostradas.",
"rcfilters-filterlist-title": "Filtros",
"rcfilters-filter-editsbyother-label": "Edições de outros",
"rcfilters-filter-editsbyother-description": "Edições criadas por outros usuários (não você.)",
"rcfilters-filtergroup-userExpLevel": "Nível de experiência (apenas para usuário registados)",
- "rcfilters-filter-userExpLevel-newcomer-label": "Recém-chegados",
- "rcfilters-filter-userExpLevel-newcomer-description": "Menos de 10 edições e 4 dias de atividade.",
- "rcfilters-filter-userExpLevel-learner-label": "Aprendizes",
- "rcfilters-filter-userExpLevel-learner-description": "Mais dias de atividade e edições do que \"Novatos\", mas menos do que \"Usuários experientes\".",
- "rcfilters-filter-userExpLevel-experienced-label": "Usuários experientes",
- "rcfilters-filter-userExpLevel-experienced-description": "Mais de 30 dias de atividade e 500 edições.",
+ "rcfilters-filter-user-experience-level-newcomer-label": "Recém-chegados",
+ "rcfilters-filter-user-experience-level-newcomer-description": "Menos de 10 edições e 4 dias de atividade.",
+ "rcfilters-filter-user-experience-level-learner-label": "Aprendizes",
+ "rcfilters-filter-user-experience-level-learner-description": "Mais dias de atividade e edições do que \"Novatos\", mas menos do que \"Usuários experientes\".",
+ "rcfilters-filter-user-experience-level-experienced-label": "Usuários experientes",
+ "rcfilters-filter-user-experience-level-experienced-description": "Mais de 30 dias de atividade e 500 edições.",
"rcfilters-filtergroup-automated": "Contribuições automatizadas",
"rcfilters-filter-bots-label": "Robô",
"rcfilters-filter-bots-description": "Edições feitas por ferramentas automatizadas.",
"rcshowhidecategorization": "$1 categorização de páginas",
"rcshowhidecategorization-show": "Exibir",
"rcshowhidecategorization-hide": "Esconder",
- "rclinks": "Exibir as $1 alterações recentes feitas nos últimos $2 dias<br />$3",
+ "rclinks": "Exibir as $1 mudanças recentes feitas nos últimos $2 dias<br />$3",
"diff": "dif",
"hist": "his",
"hide": "Ocultar",
"newimages-summary": "Esta página especial mostra os arquivos mais recentemente enviados",
"newimages-legend": "Filtrar",
"newimages-label": "Nome de arquivo (ou parte dele):",
+ "newimages-user": "Endereço IP ou nome do usuário:",
"newimages-showbots": "Mostrar uploads realizados por robôs",
"newimages-hidepatrolled": "Ocultar os carregamentos patrulhados.",
"noimages": "Nada para ver.",
"autosumm-newblank": "Criar página em branco",
"size-kilobytes": "$1 kB",
"bitrate-kilobits": "$1 kb/s",
- "lag-warn-normal": "É possível que as alterações que sejam mais recentes do que $1 {{PLURAL:$1|segundo|segundos}} não sejam exibidas nesta lista.",
- "lag-warn-high": "Devido a sérios problemas de latência no servidor do banco de dados, as alterações mais recentes que $1 {{PLURAL:$1|segundo|segundos}} poderão não ser exibidas nesta lista.",
+ "lag-warn-normal": "É possível que as mudanças que sejam mais recentes do que $1 {{PLURAL:$1|segundo|segundos}} não sejam exibidas nesta lista.",
+ "lag-warn-high": "Devido a sérios problemas de latência no servidor do banco de dados, as mudanças mais recentes que $1 {{PLURAL:$1|segundo|segundos}} poderão não ser exibidas nesta lista.",
"watchlistedit-normal-title": "Editar lista de páginas vigiadas",
"watchlistedit-normal-legend": "Remover títulos da lista de páginas vigiadas",
"watchlistedit-normal-explain": "Os títulos das páginas de sua lista de vigiadas são exibidos abaixo.\nPara remover um título, marque a caixa ao lado do mesmo e clique \"{{int:Watchlistedit-normal-submit}}\".\nVocê pode também [[Special:EditWatchlist/raw|editar a lista de páginas vigiadas em forma de texto]].",
"logentry-tag-update-revision": "$1 {{GENDER:$2|atualizou}} etiquetas em revisão $4 da página $3 ({{PLURAL:$7|adicionou}} $6; {{PLURAL:$9|removeu}} $8)",
"logentry-tag-update-logentry": "$1 {{GENDER:$2|atualizou}} etiquetas na entrada de registro $5 da página $3 ({{PLURAL:$7|adicionou}} $6; {{PLURAL:$9|removeu}} $8)",
"rightsnone": "(nenhum)",
- "revdelete-summary": "resumo da edição",
"rightslogentry-temporary-group": "$1 (temporário, até $2)",
"feedback-adding": "Adicionando os comentários na página...",
"feedback-back": "Voltar",
"page_first": "primeira",
"page_last": "última",
"histlegend": "Seleção de diferenças: use os botões de opção para marcar as versões que deseja comparar.\nPressione 'Enter' ou clique o botão \"{{int:compareselectedversions}}\".<br />\nLegenda: '''({{int:cur}})''' = diferenças para a versão atual,\n'''({{int:last}})''' = diferenças para a versão anterior,\n'''{{int:minoreditletter}}''' = edição menor",
- "history-fieldset-title": "Navegar pelo histórico",
- "history-show-deleted": "Somente eliminadas",
+ "history-fieldset-title": "Pesquisar revisões",
+ "history-show-deleted": "Somente revisões eliminadas",
"histfirst": "Mais antigas",
"histlast": "Mais novas",
"historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
"prefs-help-prefershttps": "Esta preferência terá efeito no seu próximo início de sessão.",
"prefswarning-warning": "Fez alterações às suas preferências que não foram gravadas ainda.\nSe abandonar esta página sem clicar em \"$1\", as suas preferências não serão atualizadas.",
"prefs-tabs-navigation-hint": "Dica: Pode usar as setas direita e esquerda do teclado para navegar entre os separadores.",
- "userrights": "Gestão de privilégios {{GENDER:{{BASEPAGENAME}}|do utilizador|da utilizadora|de utilizador(a)}}",
+ "userrights": "Privilégios de utilizador",
"userrights-lookup-user": "Selecionar um utilizador",
"userrights-user-editname": "Introduza um nome de utilizador(a):",
"editusergroup": "Carregar grupos do utilizador",
"rcfilters-invalid-filter": "Filtro inválido",
"rcfilters-empty-filter": "Não há filtros ativos. São mostradas todas as contribuições.",
"rcfilters-filterlist-title": "Filtros",
+ "rcfilters-filterlist-whatsthis": "O que é isto?",
"rcfilters-filterlist-feedbacklink": "Dê-nos a sua opinião sobre os novos filtros (beta)",
"rcfilters-highlightbutton-title": "Realçar resultados",
"rcfilters-highlightmenu-title": "Selecionar uma cor",
+ "rcfilters-highlightmenu-help": "Selecione uma cor para realçar esta propriedade",
"rcfilters-filterlist-noresults": "Não foram encontrados filtros",
+ "rcfilters-noresults-conflict": "Não foram encontrados resultados porque os critérios de pesquisa estão em conflito",
"rcfilters-filtergroup-registration": "Registo de utilizador",
"rcfilters-filter-registered-label": "Registado",
"rcfilters-filter-registered-description": "Editores autenticados.",
"rcfilters-filter-bots-description": "Edições efectuadas por ferramentas automatizadas.",
"rcfilters-filter-humans-label": "Ser humano (não robô)",
"rcfilters-filter-humans-description": "Edições efectuadas por editores humanos.",
+ "rcfilters-filtergroup-reviewstatus": "Estado da revisão",
+ "rcfilters-filter-patrolled-label": "Patrulhadas",
+ "rcfilters-filter-patrolled-description": "Edições marcadas como patrulhadas.",
+ "rcfilters-filter-unpatrolled-label": "Não patrulhadas",
+ "rcfilters-filter-unpatrolled-description": "Edições não marcadas como patrulhadas.",
"rcfilters-filtergroup-significance": "Significado",
"rcfilters-filter-minor-label": "Edições menores",
"rcfilters-filter-minor-description": "Edições marcadas pelo autor como menores.",
"newimages-summary": "Esta página especial mostra os ficheiros mais recentemente enviados.",
"newimages-legend": "Filtrar",
"newimages-label": "Nome de ficheiro (ou parte dele):",
+ "newimages-user": "Endereço IP ou nome do utilizador",
"newimages-showbots": "Mostrar carregamentos feitos por robôs",
"newimages-hidepatrolled": "Ocultar carregamentos patrulhados",
"noimages": "Nada para ver.",
"newimages-summary": "This message is displayed at the top of [[Special:NewImages]] to explain what is shown on that special page.",
"newimages-legend": "Caption of the fieldset for the filter on [[Special:NewImages]]\n\n{{Identical|Filter}}",
"newimages-label": "Caption of the filter editbox on [[Special:NewImages]]",
+ "newimages-user": "Caption of the username/IP address editbox on [[Special:NewImages]]",
"newimages-showbots": "Used as label for a checkbox. When checked, [[Special:NewImages]] will also display uploads by users in the bots group.",
"newimages-hidepatrolled": "Used as label for a checkbox. When checked, [[Special:NewImages]] will not display patrolled uploads.\n\nCf. {{msg-mw|tog-hidepatrolled}} and {{msg-mw|apihelp-feedrecentchanges-param-hidepatrolled}}.",
"noimages": "This is shown on the special page [[Special:NewImages]], when there aren't any recently uploaded files.",
"newimages-summary": "На этой служебной странице показаны недавно загруженные файлы.",
"newimages-legend": "Фильтр",
"newimages-label": "Имя файла (или его часть):",
+ "newimages-user": "IP-адрес или имя участника",
"newimages-showbots": "Показать загрузки ботов",
"newimages-hidepatrolled": "Скрыть отпатрулированные загрузки",
"noimages": "Изображения отсутствуют.",
"newimages-summary": "Ta posebna stran prikazuje najnovejše naložene datoteke.",
"newimages-legend": "Filter",
"newimages-label": "Ime datoteke (ali njen del):",
+ "newimages-user": "IP-naslov ali uporabniško ime",
"newimages-showbots": "Prikaži nalaganja botov",
"newimages-hidepatrolled": "Skrij nadzorovana nalaganja",
"noimages": "Nič ni videti.",
"post-expand-template-argument-warning": "Varning: Sidan innehåller en eller flera mallparametrar som blir för långa när de expanderas.\nDessa parametrar har uteslutits.",
"post-expand-template-argument-category": "Sidor med uteslutna mallparametrar",
"parser-template-loop-warning": "Mall-loop upptäckt: [[$1]]",
+ "template-loop-category": "Sidor med loopade mallar",
+ "template-loop-category-desc": "Sidan innehåller en loopad mall, d.v.s. en mall som anropar sig själv rekursivt.",
"parser-template-recursion-depth-warning": "Gräns för mallrekursionsdjup överskriden ($1)",
"language-converter-depth-warning": "Gräns för språkkonverteringsdjup överskriden ($1)",
"node-count-exceeded-category": "Sidor där antalet noder har överskridits",
"newimages-summary": "Den här specialsidan visar de senast uppladdade filerna.",
"newimages-legend": "Filter",
"newimages-label": "Filnamn (eller en del av det):",
+ "newimages-user": "IP-adress eller användarnamn",
"newimages-showbots": "Visa uppladdningar av botar",
"newimages-hidepatrolled": "Dölj patrullerade uppladdningar",
"noimages": "Ingenting att se.",
"externaldberror": "Maaaring may kamalian sa pagpapatotoo ng database o kaya hindi ka pinahintulutang isapanahon ng iyong panlabas na account.",
"login": "Lumagda",
"nav-login-createaccount": "Lumagda / lumikha ng account",
- "userlogin": "Lumagda / lumikha ng account",
- "userloginnocreate": "Lumagda",
"logout": "Umalis sa pagkaka-login",
"userlogout": "Umalis sa pagkaka-login",
"notloggedin": "Hindi naka-login",
"userlogin-noaccount": "Wala ka pa bang account?",
"userlogin-joinproject": "Sumali sa {{SITENAME}}",
- "nologin": "Wala ka pang account? $1.",
- "nologinlink": "Lumikha ng account",
"createaccount": "Lumikha ng account",
- "gotaccount": "May account ka na ba? $1.",
- "gotaccountlink": "Lumagda",
- "userlogin-resetlink": "Nakalimutan mo ang iyong mga detalyeng pang-login?",
"userlogin-resetpassword-link": "Nakalimutan ba ang iyong password?",
"userlogin-helplink2": "Tulong sa pag-login",
"userlogin-loggedin": "Naka-login ka na bilang {{GENDER:$1|$1}}. Gamitin ang form sa ibaba upang maka-login bilang ibang tagagamit o user.",
"createacct-another-email-ph": "Ipasok ang email address",
"createaccountmail": "Gumamit ng pansamantalang random na password at ipadala ito sa email na nakasaad sa ibaba",
"createacct-realname": "Tunay na pangalan (maaaring wala)",
- "createaccountreason": "Dahilan:",
"createacct-reason": "Dahilan",
"createacct-reason-ph": "Bakit ka gagawa ng isa pang account?",
"createacct-submit": "Likhain ang iyong account",
"post-expand-template-argument-warning": "Babala: Naglalamang ang pahinang ito ng kahit isang pagaalitan ng padron na napakalaki ng sukat ng paglawak. Tinanggal ang mga alitang ito.",
"post-expand-template-argument-category": "Mga pahinang naglalaman ng mga tinanggal na mga alitan ng padron",
"parser-template-loop-warning": "Nadiskubreng silo ng suleras: [[$1]]",
+ "template-loop-category-desc": "Ang pahina ay naglalaman ng kodigong-makapanguulit, halimbawa. Isang kodigo na magpapahiwatig sa sarili ng paguulit.",
"parser-template-recursion-depth-warning": "Lumabis na sa nakatakdang lalim ng rekursyon (pormula) ng suleras ($1)",
"language-converter-depth-warning": "Lumampas sa ($1) ang hangganan ng lalim ng pampalit ng wika",
"node-count-exceeded-category": "Mga pahina kung saan nalampasan ang bilang ng buko",
"logentry-newusers-autocreate": "Automatikong {{GENDER:$2|inilikha}} ang account ng tagagamit na $1",
"logentry-upload-upload": "{{GENDER:$2|Ikinarga}} ni $1 ang $3",
"rightsnone": "(wala)",
- "revdelete-summary": "buod ng pagbabago",
"feedback-adding": "Idinaragdag ang pakaing-tugon sa pahina...",
"feedback-back": "Magbalik",
"feedback-bugcheck": "Mahusay! Suriin lang na hindi pa ito isa sa [$1 nalalamang mga depekto].",
"newimages-summary": "本特殊页面展示最后上传的文件。",
"newimages-legend": "过滤",
"newimages-label": "文件名(或它的一部份):",
+ "newimages-user": "IP地址或用户名",
"newimages-showbots": "显示机器人上传",
"newimages-hidepatrolled": "隐藏已巡查的上传",
"noimages": "无可查看文件。",
"newimages-summary": "此特殊頁面中顯示最新上傳的檔案。",
"newimages-legend": "搜尋",
"newimages-label": "檔案名稱 (或部份檔名):",
+ "newimages-user": "IP 位址或使用者名稱",
"newimages-showbots": "顯示由機器人上傳的檔案",
"newimages-hidepatrolled": "隱藏己巡查上傳",
"noimages": "無任何圖片。",
$maintClass = false;
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\LBFactory;
require_once __DIR__ . '/../includes/export/DumpFilter.php';
use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\IDatabase;
/**
* @ingroup Dump Maintenance
*/
use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
require_once __DIR__ . '/Maintenance.php';
* @author Timo Tijhof
*/
-use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
require_once __DIR__ . '/Maintenance.php';
* @ingroup Maintenance
*/
+use Wikimedia\Rdbms\IDatabase;
+
require_once __DIR__ . '/Maintenance.php';
/**
require_once __DIR__ . '/Maintenance.php';
+use Wikimedia\Rdbms\IDatabase;
+
/**
* Maintenance script to run a database query in batches and wait for replica DBs.
*
require_once __DIR__ . '/Maintenance.php';
use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
/**
* Maintenance script that sends SQL queries from the specified file to the database.
"eslint": "3.12.2",
"eslint-config-wikimedia": "0.3.0",
"grunt": "1.0.1",
- "grunt-banana-checker": "0.5.0",
+ "grunt-banana-checker": "0.6.0",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-watch": "1.0.0",
"grunt-eslint": "19.0.0",
'dependencies' => [
'mediawiki.ForeignStructuredUpload',
'mediawiki.Upload.BookletLayout',
- 'mediawiki.widgets.CategorySelector',
+ 'mediawiki.widgets.CategoryMultiselectWidget',
'mediawiki.widgets.DateInputWidget',
'mediawiki.jqueryMsg',
'mediawiki.api.messages',
'targets' => [ 'desktop', 'mobile' ],
],
'mediawiki.widgets.CategorySelector' => [
+ 'deprecated' => 'Use "mw.widgets.CategoryMultiselectWidget" instead. See T161285.',
+ 'dependencies' => [
+ 'mediawiki.widgets.CategoryMultiselectWidget',
+ ],
+ ],
+ 'mediawiki.widgets.CategoryMultiselectWidget' => [
'scripts' => [
'resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js',
- 'resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js',
+ 'resources/src/mediawiki.widgets/mw.widgets.CategoryMultiselectWidget.js',
],
'dependencies' => [
'oojs-ui-widgets',
],
'messages' => [
'red-link-title',
- 'mw-widgets-categoryselector-add-category-placeholder'
+ 'mw-widgets-categoryselector-add-category-placeholder',
],
'targets' => [ 'desktop', 'mobile' ],
],
"Mogoeilor"
]
},
+ "ooui-outline-control-move-down": "ڤا دڤۈن بوردن آیتم",
+ "ooui-outline-control-move-up": "ڤارو بردن آیتم",
+ "ooui-outline-control-remove": "ڤورداشتن آیتم",
"ooui-toolbar-more": "بیشتر",
"ooui-toolgroup-expand": "بیشتر",
"ooui-toolgroup-collapse": "کمتر",
"ooui-dialog-message-accept": "خۈڤإ",
"ooui-dialog-message-reject": "أنجومشيڤ کردن",
+ "ooui-dialog-process-error": "یأ چي ايچو إشتوا إ",
"ooui-dialog-process-retry": "ز نۉ تلاش کونين",
"ooui-dialog-process-continue": "ديندا گرهڌن",
"ooui-selectfile-button-select": "گولإڤورچين کردن جانیا",
+ "ooui-selectfile-not-supported": "گول ڤورچی کردن جانیا کونشتکاری نڤابیڌ",
"ooui-selectfile-placeholder": "هيژ جانيایي گولإ ڤورچين نڤابيڌإ",
"ooui-selectfile-dragdrop-placeholder": "جانيانأ ڤأنين ايچو"
}
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
*/
( function ( OO ) {
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
*/
.oo-ui-element-hidden {
display: none !important;
-ms-user-select: none;
user-select: none;
}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button::-moz-focus-inner {
+ border-color: transparent;
+ padding: 0;
+}
.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
display: none;
.oo-ui-menuSelectWidget-invisible {
display: none;
}
-.oo-ui-menuOptionWidget {
- position: relative;
-}
.oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
display: none;
}
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
*/
.oo-ui-element-hidden {
display: none !important;
-ms-user-select: none;
user-select: none;
}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button::-moz-focus-inner {
+ border-color: transparent;
+ padding: 0;
+}
.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
display: none;
border-radius: 2px;
outline: 0;
}
-.oo-ui-buttonElement > .oo-ui-buttonElement-button:focus::-moz-focus-inner {
- border-color: transparent;
-}
.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
margin-right: 0.25em;
margin-left: 0.46875em;
.oo-ui-optionWidget {
position: relative;
display: block;
- border: 0;
}
.oo-ui-optionWidget.oo-ui-widget-enabled {
cursor: pointer;
display: none;
}
.oo-ui-menuOptionWidget {
- position: relative;
padding: 0.5em 1em;
-webkit-transition: background-color 100ms, color 100ms;
-moz-transition: background-color 100ms, color 100ms;
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
*/
( function ( OO ) {
// Check if the element is visible
if ( !(
// This is quicker than calling $element.is( ':visible' )
- $.expr.filters.visible( element ) &&
+ $.expr.pseudos.visible( element ) &&
// Check that all parents are visible
!$element.parents().addBack().filter( function () {
return $.css( this, 'visibility' ) === 'hidden';
// Window
obj.document ||
// HTMLDocument
- ( obj.nodeType === 9 && obj ) ||
+ ( obj.nodeType === Node.DOCUMENT_NODE && obj ) ||
null;
};
if ( obj instanceof jQuery ) {
obj = obj[ 0 ];
}
- isDoc = obj.nodeType === 9;
+ isDoc = obj.nodeType === Node.DOCUMENT_NODE;
isWin = obj.document !== undefined;
if ( isDoc || isWin ) {
if ( isWin ) {
}() );
/**
- * Get scrollable object parent
+ * Get the root scrollable element of given element's document.
*
- * documentElement can't be used to get or set the scrollTop
- * property on Blink. Changing and testing its value lets us
- * use 'body' or 'documentElement' based on what is working.
+ * On Blink-based browsers (Chrome etc.), `document.documentElement` can't be used to get or set
+ * the scrollTop property; instead we have to use `document.body`. Changing and testing the value
+ * lets us use 'body' or 'documentElement' based on what is working.
*
* https://code.google.com/p/chromium/issues/detail?id=303131
*
* @static
- * @param {HTMLElement} el Element to find scrollable parent for
- * @return {HTMLElement} Scrollable parent
+ * @param {HTMLElement} el Element to find root scrollable parent for
+ * @return {HTMLElement} Scrollable parent, `document.body` or `document.documentElement`
+ * depending on browser
*/
OO.ui.Element.static.getRootScrollableElement = function ( el ) {
var scrollTop, body;
/**
* Get closest scrollable container.
*
- * Traverses up until either a scrollable element or the root is reached, in which case the window
- * will be returned.
+ * Traverses up until either a scrollable element or the root is reached, in which case the root
+ * scrollable element will be returned (see #getRootScrollableElement).
*
* @static
* @param {HTMLElement} el Element to find scrollable container for
props = [ 'overflow-' + dimension ];
}
+ // Special case for the document root (which doesn't really have any scrollable container, since
+ // it is the ultimate scrollable container, but this is probably saner than null or exception)
+ if ( $( el ).is( 'html, body' ) ) {
+ return this.getRootScrollableElement( el );
+ }
+
while ( $parent.length ) {
if ( $parent[ 0 ] === this.getRootScrollableElement( el ) ) {
return $parent[ 0 ];
}
$parent = $parent.parent();
}
- return this.getDocument( el ).body;
+ // The element is unattached... return something mostly sane
+ return this.getRootScrollableElement( el );
};
/**
* [1]: https://www.mediawiki.org/wiki/OOjs_UI/Elements/Groups
*
* @abstract
+ * @mixins OO.EmitterList
* @class
*
* @constructor
// Configuration initialization
config = config || {};
+ // Mixin constructors
+ OO.EmitterList.call( this, config );
+
// Properties
this.$group = null;
- this.items = [];
- this.aggregateItemEvents = {};
// Initialization
this.setGroupElement( config.$group || $( '<div>' ) );
};
+/* Setup */
+
+OO.mixinClass( OO.ui.mixin.GroupElement, OO.EmitterList );
+
/* Events */
/**
}
};
-/**
- * Check if a group contains no items.
- *
- * @return {boolean} Group is empty
- */
-OO.ui.mixin.GroupElement.prototype.isEmpty = function () {
- return !this.items.length;
-};
-
-/**
- * Get all items in the group.
- *
- * The method returns an array of item references (e.g., [button1, button2, button3]) and is useful
- * when synchronizing groups of items, or whenever the references are required (e.g., when removing items
- * from a group).
- *
- * @return {OO.ui.Element[]} An array of items.
- */
-OO.ui.mixin.GroupElement.prototype.getItems = function () {
- return this.items.slice( 0 );
-};
-
/**
* Get an item by its data.
*
return items;
};
-/**
- * Aggregate the events emitted by the group.
- *
- * When events are aggregated, the group will listen to all contained items for the event,
- * and then emit the event under a new name. The new event will contain an additional leading
- * parameter containing the item that emitted the original event. Other arguments emitted from
- * the original event are passed through.
- *
- * @param {Object.<string,string|null>} events An object keyed by the name of the event that should be
- * aggregated (e.g., ‘click’) and the value of the new name to use (e.g., ‘groupClick’).
- * A `null` value will remove aggregated events.
-
- * @throws {Error} An error is thrown if aggregation already exists.
- */
-OO.ui.mixin.GroupElement.prototype.aggregate = function ( events ) {
- var i, len, item, add, remove, itemEvent, groupEvent;
-
- for ( itemEvent in events ) {
- groupEvent = events[ itemEvent ];
-
- // Remove existing aggregated event
- if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
- // Don't allow duplicate aggregations
- if ( groupEvent ) {
- throw new Error( 'Duplicate item event aggregation for ' + itemEvent );
- }
- // Remove event aggregation from existing items
- for ( i = 0, len = this.items.length; i < len; i++ ) {
- item = this.items[ i ];
- if ( item.connect && item.disconnect ) {
- remove = {};
- remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
- item.disconnect( this, remove );
- }
- }
- // Prevent future items from aggregating event
- delete this.aggregateItemEvents[ itemEvent ];
- }
-
- // Add new aggregate event
- if ( groupEvent ) {
- // Make future items aggregate event
- this.aggregateItemEvents[ itemEvent ] = groupEvent;
- // Add event aggregation to existing items
- for ( i = 0, len = this.items.length; i < len; i++ ) {
- item = this.items[ i ];
- if ( item.connect && item.disconnect ) {
- add = {};
- add[ itemEvent ] = [ 'emit', groupEvent, item ];
- item.connect( this, add );
- }
- }
- }
- }
-};
-
/**
* Add items to the group.
*
* @chainable
*/
OO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {
- var i, len, item, itemEvent, events, currentIndex,
- itemElements = [];
+ // Mixin method
+ OO.EmitterList.prototype.addItems.call( this, items, index );
- for ( i = 0, len = items.length; i < len; i++ ) {
- item = items[ i ];
+ this.emit( 'change', this.getItems() );
+ return this;
+};
- // Check if item exists then remove it first, effectively "moving" it
- currentIndex = this.items.indexOf( item );
- if ( currentIndex >= 0 ) {
- this.removeItems( [ item ] );
- // Adjust index to compensate for removal
- if ( currentIndex < index ) {
- index--;
- }
- }
- // Add the item
- if ( item.connect && item.disconnect && !$.isEmptyObject( this.aggregateItemEvents ) ) {
- events = {};
- for ( itemEvent in this.aggregateItemEvents ) {
- events[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
- }
- item.connect( this, events );
- }
- item.setElementGroup( this );
- itemElements.push( item.$element.get( 0 ) );
- }
+/**
+ * @inheritdoc
+ */
+OO.ui.mixin.GroupElement.prototype.moveItem = function ( items, newIndex ) {
+ // insertItemElements expects this.items to not have been modified yet, so call before the mixin
+ this.insertItemElements( items, newIndex );
+
+ // Mixin method
+ newIndex = OO.EmitterList.prototype.moveItem.call( this, items, newIndex );
+
+ return newIndex;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.mixin.GroupElement.prototype.insertItem = function ( item, index ) {
+ item.setElementGroup( this );
+ this.insertItemElements( item, index );
+ // Mixin method
+ index = OO.EmitterList.prototype.insertItem.call( this, item, index );
+
+ return index;
+};
+
+/**
+ * Insert elements into the group
+ *
+ * @private
+ * @param {OO.ui.Element} itemWidget Item to insert
+ * @param {number} index Insertion index
+ */
+OO.ui.mixin.GroupElement.prototype.insertItemElements = function ( itemWidget, index ) {
if ( index === undefined || index < 0 || index >= this.items.length ) {
- this.$group.append( itemElements );
- this.items.push.apply( this.items, items );
+ this.$group.append( itemWidget.$element );
} else if ( index === 0 ) {
- this.$group.prepend( itemElements );
- this.items.unshift.apply( this.items, items );
+ this.$group.prepend( itemWidget.$element );
} else {
- this.items[ index ].$element.before( itemElements );
- this.items.splice.apply( this.items, [ index, 0 ].concat( items ) );
+ this.items[ index ].$element.before( itemWidget.$element );
}
-
- this.emit( 'change', this.getItems() );
- return this;
};
/**
* @chainable
*/
OO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {
- var i, len, item, index, events, itemEvent;
+ var i, len, item, index;
- // Remove specific items
+ // Remove specific items elements
for ( i = 0, len = items.length; i < len; i++ ) {
item = items[ i ];
index = this.items.indexOf( item );
if ( index !== -1 ) {
- if ( item.connect && item.disconnect && !$.isEmptyObject( this.aggregateItemEvents ) ) {
- events = {};
- for ( itemEvent in this.aggregateItemEvents ) {
- events[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
- }
- item.disconnect( this, events );
- }
item.setElementGroup( null );
- this.items.splice( index, 1 );
item.$element.detach();
}
}
+ // Mixin method
+ OO.EmitterList.prototype.removeItems.call( this, items );
+
this.emit( 'change', this.getItems() );
return this;
};
* @chainable
*/
OO.ui.mixin.GroupElement.prototype.clearItems = function () {
- var i, len, item, remove, itemEvent;
+ var i, len;
- // Remove all items
+ // Remove all item elements
for ( i = 0, len = this.items.length; i < len; i++ ) {
- item = this.items[ i ];
- if (
- item.connect && item.disconnect &&
- !$.isEmptyObject( this.aggregateItemEvents )
- ) {
- remove = {};
- if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
- remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
- }
- item.disconnect( this, remove );
- }
- item.setElementGroup( null );
- item.$element.detach();
+ this.items[ i ].setElementGroup( null );
+ this.items[ i ].$element.detach();
}
+ // Mixin method
+ OO.EmitterList.prototype.clearItems.call( this );
+
this.emit( 'change', this.getItems() );
- this.items = [];
return this;
};
return this;
}
+ if ( !(
+ // To continue, some things need to be true:
+ // The element must actually be in the DOM
+ this.isElementAttached() && (
+ // The closest scrollable is the current window
+ this.$floatableClosestScrollable[ 0 ] === this.getElementWindow() ||
+ // OR is an element in the element's DOM
+ $.contains( this.getElementDocument(), this.$floatableClosestScrollable[ 0 ] )
+ )
+ ) ) {
+ // Abort early if important parts of the widget are no longer attached to the DOM
+ return this;
+ }
+
if ( this.hideWhenOutOfView && !this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable ) ) {
this.$floatable.addClass( 'oo-ui-element-hidden' );
return this;
OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.ClippableElement );
OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.FloatableElement );
+/* Events */
+
+/**
+ * @event ready
+ *
+ * The popup is ready: it is visible and has been positioned and clipped.
+ */
+
/* Methods */
/**
* Side-effects may include broken interface and exceptions being thrown. This wasn't always
* strictly enforced, so currently it only generates a warning in the browser console.
*
+ * @fires ready
* @inheritdoc
*/
OO.ui.PopupWidget.prototype.toggle = function ( show ) {
}
this.updateDimensions();
this.toggleClipping( true );
+ this.emit( 'ready' );
} else {
this.toggleClipping( false );
if ( this.autoClose ) {
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
*/
( function ( OO ) {
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
*/
.oo-ui-popupTool .oo-ui-popupWidget-popup,
.oo-ui-popupTool .oo-ui-popupWidget-anchor {
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
*/
.oo-ui-tool.oo-ui-widget-enabled {
-webkit-transition: background-color 100ms;
height: 2.5em;
}
.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
- width: 0.9375em;
- height: 1.625em;
- margin: 0.78125em 0.5em;
top: 0;
right: 0;
+ width: 0.9375em;
+ height: 100%;
+ margin: 0 0.5em;
opacity: 0.3;
}
.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
*/
( function ( OO ) {
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
*/
-.oo-ui-draggableElement-handle,
-.oo-ui-draggableElement-handle.oo-ui-widget {
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ),
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
cursor: move;
cursor: url(images/grab.cur );
cursor: -webkit-grab;
cursor: -moz-grab;
cursor: grab;
}
-.oo-ui-draggableElement-handle:active {
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ):active {
cursor: url(images/grabbing.cur );
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
*/
-.oo-ui-draggableElement-handle,
-.oo-ui-draggableElement-handle.oo-ui-widget {
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ),
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
cursor: move;
cursor: url(images/grab.cur );
cursor: -webkit-grab;
cursor: -moz-grab;
cursor: grab;
}
-.oo-ui-draggableElement-handle:active {
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ):active {
cursor: url(images/grabbing.cur );
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
.oo-ui-buttonOptionWidget {
display: inline-block;
- padding: 0;
}
.oo-ui-buttonOptionWidget.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
cursor: default;
display: inline-block;
vertical-align: middle;
}
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
- background-color: transparent;
-}
.oo-ui-toggleButtonWidget {
margin-right: 0.5em;
}
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
*/
( function ( OO ) {
* @constructor
* @param {Object} [config] Configuration options
* @cfg {jQuery} [$handle] The part of the element which can be used for dragging, defaults to the whole element
+ * @cfg {boolean} [draggable] The items are draggable. This can change with #toggleDraggable
+ * but the draggable state should be called from the DraggableGroupElement, which updates
+ * the whole group
*/
OO.ui.mixin.DraggableElement = function OoUiMixinDraggableElement( config ) {
config = config || {};
this.index = null;
this.$handle = config.$handle || this.$element;
this.wasHandleUsed = null;
+ this.draggable = config.draggable === undefined ? true : !!config.draggable;
// Initialize and events
this.$element.addClass( 'oo-ui-draggableElement' )
/* Methods */
+/**
+ * Change the draggable state of this widget.
+ * This allows users to temporarily halt the dragging operations.
+ *
+ * @param {boolean} isDraggable Widget supports draggable operations
+ * @fires draggable
+ */
+OO.ui.mixin.DraggableElement.prototype.toggleDraggable = function ( isDraggable ) {
+ isDraggable = isDraggable !== undefined ? !!isDraggable : !this.draggable;
+
+ if ( this.draggable !== isDraggable ) {
+ this.draggable = isDraggable;
+
+ this.$element.toggleClass( 'oo-ui-draggableElement-undraggable', !this.draggable );
+ }
+};
+
+/**
+ * Check the draggable state of this widget
+ *
+ * @return {boolean} Widget supports draggable operations
+ */
+OO.ui.mixin.DraggableElement.prototype.isDraggable = function () {
+ return this.draggable;
+};
+
/**
* Respond to mousedown event.
*
* @param {jQuery.Event} e Drag event
*/
OO.ui.mixin.DraggableElement.prototype.onDragMouseDown = function ( e ) {
+ if ( !this.isDraggable() ) {
+ return;
+ }
+
this.wasHandleUsed =
// Optimization: if the handle is the whole element this is always true
this.$handle[ 0 ] === this.$element[ 0 ] ||
var element = this,
dataTransfer = e.originalEvent.dataTransfer;
- if ( !this.wasHandleUsed ) {
+ if ( !this.wasHandleUsed || !this.isDraggable() ) {
return false;
}
* should match the layout of the items. Items displayed in a single row
* or in several rows should use horizontal orientation. The vertical orientation should only be
* used when the items are displayed in a single column. Defaults to 'vertical'
+ * @cfg {boolean} [draggable] The items are draggable. This can change with #toggleDraggable
*/
OO.ui.mixin.DraggableGroupElement = function OoUiMixinDraggableGroupElement( config ) {
// Configuration initialization
this.itemKeys = {};
this.dir = null;
this.itemsOrder = null;
+ this.draggable = config.draggable === undefined ? true : !!config.draggable;
// Events
this.aggregate( {
*/
/**
- * And item has been dropped at a new position.
+ * An item has been dropped at a new position.
*
* @event reorder
* @param {OO.ui.mixin.DraggableElement} item Reordered item
* @param {number} [newIndex] New index for the item
*/
+/**
+ * Draggable state of this widget has changed.
+ *
+ * @event draggable
+ * @param {boolean} [draggable] Widget is draggable
+ */
+
/* Methods */
+/**
+ * Change the draggable state of this widget.
+ * This allows users to temporarily halt the dragging operations.
+ *
+ * @param {boolean} isDraggable Widget supports draggable operations
+ * @fires draggable
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.toggleDraggable = function ( isDraggable ) {
+ isDraggable = isDraggable !== undefined ? !!isDraggable : !this.draggable;
+
+ if ( this.draggable !== isDraggable ) {
+ this.draggable = isDraggable;
+
+ // Tell the items their draggable state changed
+ this.getItems().forEach( function ( item ) {
+ item.toggleDraggable( this.draggable );
+ }.bind( this ) );
+
+ // Emit event
+ this.emit( 'draggable', this.draggable );
+ }
+};
+
+/**
+ * Check the draggable state of this widget
+ *
+ * @return {boolean} Widget supports draggable operations
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.isDraggable = function () {
+ return this.draggable;
+};
+
/**
* Respond to item drag start event
*
* @param {OO.ui.mixin.DraggableElement} item Dragged item
*/
OO.ui.mixin.DraggableGroupElement.prototype.onItemDragStart = function ( item ) {
+ if ( !this.isDraggable() ) {
+ return;
+ }
// Make a shallow copy of this.items so we can re-order it during previews
// without affecting the original array.
this.itemsOrder = this.items.slice();
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
*/
.oo-ui-actionWidget.oo-ui-pendingElement-pending {
background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
*/
.oo-ui-window {
background: transparent;
/*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
*/
( function ( OO ) {
manager.toggleGlobalEvents( true );
manager.toggleAriaIsolation( true );
}
- manager.$returnFocusTo = data.$returnFocusTo || $( document.activeElement );
+ manager.$returnFocusTo = data.$returnFocusTo !== undefined ? data.$returnFocusTo : $( document.activeElement );
manager.currentWindow = win;
manager.opening = opening;
manager.preparingToOpen = null;
"prefix": "oo-ui-icon",
"intro": "@import '../../../../src/styles/common';",
"images": {
+ "alert": { "file": "images/icons/alert.svg" },
"bell": { "file": "images/icons/bell.svg" },
"bellOn": { "file": {
"ltr": "images/icons/bellOn-ltr.svg",
"rtl": "images/icons/bellOn-rtl.svg"
} },
+ "comment": { "file": "images/icons/comment.svg" },
"eye": { "file": "images/icons/eye.svg" },
"eyeClosed": { "file": "images/icons/eyeClosed.svg" },
"message": { "file": {
"ltr": "images/icons/message-ltr.svg",
"rtl": "images/icons/message-rtl.svg"
} },
+ "notice": { "file": "images/icons/notice.svg" },
"signature": { "file": {
"ltr": "images/icons/signature-ltr.svg",
"rtl": "images/icons/signature-rtl.svg"
"ltr": "images/icons/articleRedirect-ltr.svg",
"rtl": "images/icons/articleRedirect-rtl.svg"
} },
+ "history": { "file": "images/icons/history.svg" },
+ "info": { "file": "images/icons/info.svg" },
"journal": { "file": {
"ltr": "images/icons/journal-ltr.svg",
"rtl": "images/icons/journal-rtl.svg"
} },
+ "tag": { "file": "images/icons/tag.svg" },
"upload": { "file": {
"ltr": "images/icons/upload-ltr.svg",
"rtl": "images/icons/upload-rtl.svg"
- } }
+ } },
+ "window": { "file": "images/icons/window.svg" }
}
}
{
"prefix": "oo-ui-icon",
"intro": "@import '../../../../src/styles/common';",
- "variants": {
- "invert": {
- "color": "#FFFFFF",
- "global": true
- }
- },
"images": {
"add": { "file": "images/icons/add.svg" },
+ "advanced": { "file": "images/icons/advanced.svg" },
"bookmark": { "file": {
"ltr": "images/icons/bookmark-ltr.svg",
"rtl": "images/icons/bookmark-rtl.svg"
"ltr": "images/icons/browser-ltr.svg",
"rtl": "images/icons/browser-rtl.svg"
} },
+ "cancel": { "file": "images/icons/cancel.svg" },
+ "check": { "file": "images/icons/check.svg" },
"clear": { "file": "images/icons/clear.svg" },
"clock": { "file": "images/icons/clock.svg" },
+ "close": { "file": "images/icons/close.svg" },
+ "ellipsis": { "file": "images/icons/ellipsis.svg" },
"feedback": { "file": {
"ltr": "images/icons/feedback-ltr.svg",
"rtl": "images/icons/feedback-rtl.svg"
"rtl": "images/icons/funnel-rtl.svg"
} },
"heart": { "file": "images/icons/heart.svg" },
+ "help": { "file": {
+ "ltr": "images/icons/help-ltr.svg",
+ "rtl": "images/icons/help-rtl.svg",
+ "lang": {
+ "he,yi": "images/icons/help-ltr.svg"
+ }
+ } },
"key": { "file": {
"ltr": "images/icons/key-ltr.svg",
"rtl": "images/icons/key-rtl.svg"
"ltr": "images/icons/printer-ltr.svg",
"rtl": "images/icons/printer-rtl.svg"
} },
+ "search": { "file": {
+ "ltr": "images/icons/search-ltr.svg",
+ "rtl": "images/icons/search-rtl.svg"
+ }
+ },
+ "settings": { "file": "images/icons/settings.svg" },
"subtract": { "file": "images/icons/subtract.svg" },
"sun": { "file": {
"ltr": "images/icons/sun-ltr.svg",
--- /dev/null
+{
+ "prefix": "oo-ui-icon",
+ "intro": "@import '../../../../src/styles/common';",
+ "images": {
+ "menu": { "file": "images/icons/menu.svg" },
+ "stripeFlow": { "file": {
+ "ltr": "images/icons/stripeFlow-ltr.svg",
+ "rtl": "images/icons/stripeFlow-rtl.svg"
+ } },
+ "stripeSideMenu": { "file": "images/icons/stripeSideMenu.svg" },
+ "stripeSummary": { "file": {
+ "ltr": "images/icons/stripeSummary-ltr.svg",
+ "rtl": "images/icons/stripeSummary-rtl.svg"
+ } },
+ "stripeToC": { "file": {
+ "ltr": "images/icons/stripeToC-ltr.svg",
+ "rtl": "images/icons/stripeToC-rtl.svg"
+ } },
+ "viewCompact": { "file": "images/icons/viewCompact.svg" },
+ "viewDetails": { "file": {
+ "ltr": "images/icons/viewDetails-ltr.svg",
+ "rtl": "images/icons/viewDetails-rtl.svg"
+ } }
+ }
+}
} },
"caretDown": { "file": "images/icons/caretDown.svg" },
"caretUp": { "file": "images/icons/caretUp.svg" },
+ "collapse": { "file": "images/icons/collapse.svg" },
"downTriangle": { "file": "images/icons/downTriangle.svg" },
+ "expand": { "file": "images/icons/expand.svg" },
"move": { "file": "images/icons/move.svg" },
+ "next": { "file": {
+ "ltr": "images/icons/move-ltr.svg",
+ "rtl": "images/icons/move-rtl.svg"
+ }
+ },
+ "previous": { "file": {
+ "ltr": "images/icons/move-rtl.svg",
+ "rtl": "images/icons/move-ltr.svg"
+ }
+ },
"upTriangle": { "file": "images/icons/upTriangle.svg" }
}
}
"prefix": "oo-ui-icon",
"intro": "@import '../../../../src/styles/common';",
"images": {
- "add": { "file": "images/icons/add.svg", "deprecated": "Moved since v0.19.5, use from the 'interactive' pack instead." },
- "advanced": { "file": "images/icons/advanced.svg" },
- "alert": { "file": "images/icons/alert.svg" },
- "cancel": { "file": "images/icons/cancel.svg" },
- "check": { "file": "images/icons/check.svg" },
- "circle": { "file": "images/icons/circle.svg" },
- "close": { "file": "images/icons/close.svg" },
- "code": { "file": "images/icons/code.svg" },
- "collapse": { "file": "images/icons/collapse.svg" },
- "comment": { "file": "images/icons/comment.svg" },
- "ellipsis": { "file": "images/icons/ellipsis.svg" },
- "expand": { "file": "images/icons/expand.svg" },
+ "add": { "file": "images/icons/add.svg", "deprecated": "Moved since v0.19.5, use from the 'interactions' pack instead." },
+ "advanced": { "file": "images/icons/advanced.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "alert": { "file": "images/icons/alert.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
+ "cancel": { "file": "images/icons/cancel.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "check": { "file": "images/icons/check.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "circle": { "file": "images/icons/circle.svg", "deprecated": "Deprecated since v0.20.1, do not use." },
+ "close": { "file": "images/icons/close.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "code": { "file": "images/icons/code.svg", "deprecated": "Moved since v0.16.2, use from the 'editing-advanced' pack instead." },
+ "collapse": { "file": "images/icons/collapse.svg", "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead." },
+ "comment": { "file": "images/icons/comment.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
+ "ellipsis": { "file": "images/icons/ellipsis.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "expand": { "file": "images/icons/expand.svg", "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead." },
"help": { "file": {
"ltr": "images/icons/help-ltr.svg",
"rtl": "images/icons/help-rtl.svg",
"lang": {
"he,yi": "images/icons/help-ltr.svg"
- }
+ },
+ "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead."
} },
- "history": { "file": "images/icons/history.svg" },
- "info": { "file": "images/icons/info.svg" },
- "menu": { "file": "images/icons/menu.svg" },
+ "history": { "file": "images/icons/history.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
+ "info": { "file": "images/icons/info.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
+ "menu": { "file": "images/icons/menu.svg", "deprecated": "Moved since v0.20.1, use from the 'layout' pack instead." },
"next": { "file": {
"ltr": "images/icons/move-ltr.svg",
"rtl": "images/icons/move-rtl.svg"
- } },
- "notice": { "file": "images/icons/notice.svg" },
+ },
+ "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead."
+ },
+ "notice": { "file": "images/icons/notice.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
"previous": { "file": {
"ltr": "images/icons/move-rtl.svg",
"rtl": "images/icons/move-ltr.svg"
- } },
+ },
+ "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead."
+ },
"redo": { "file": {
"ltr": "images/icons/arched-arrow-ltr.svg",
"rtl": "images/icons/arched-arrow-rtl.svg"
- } },
- "remove": { "file": "images/icons/trash.svg" },
- "search": { "file": "images/icons/search.svg" },
- "settings": { "file": "images/icons/settings.svg" },
- "tag": { "file": "images/icons/tag.svg" },
+ },
+ "deprecated": "Moved since v0.16.2, use from the 'editing-core' pack instead."
+ },
+ "remove": { "file": "images/icons/trash.svg", "deprecated": "Replaced since v0.14.0, use 'trash' from the 'moderation' pack instead." },
+ "search": { "file": {
+ "ltr": "images/icons/search-ltr.svg",
+ "rtl": "images/icons/search-rtl.svg"
+ },
+ "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead."
+ },
+ "settings": { "file": "images/icons/settings.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "tag": { "file": "images/icons/tag.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
"undo": { "file": {
"ltr": "images/icons/arched-arrow-rtl.svg",
"rtl": "images/icons/arched-arrow-ltr.svg"
- } },
- "window": { "file": "images/icons/window.svg" }
+ },
+ "deprecated": "Moved since v0.16.2, use from the 'editing-core' pack instead."
+ },
+ "window": { "file": "images/icons/window.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." }
}
}
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <g id="add">
- <path id="plus" d="M13 6h-2v5H6v2h5v5h2v-5h5v-2h-5z"/>
- </g>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M15 5H8c-1.1 0-2 .9-2 2v3h3v11l4-3 4 3V7c0-1.1-.9-2-2-2zM9 9H7V7c0-.6.4-1 1-1h1v3z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M8 5h7c1.1 0 2 .9 2 2v3h-3v11l-4-3-4 3V7c0-1.1.9-2 2-2zm6 4h2V7c0-.6-.4-1-1-1h-1v3z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M3 6v11c0 1.7 1.3 3 3 3h15V6H3zm2.5 1C6.3 7 7 7.7 7 8.5S6.3 10 5.5 10 4 9.3 4 8.5 4.7 7 5.5 7zM20 19H6c-1.1 0-2-.9-2-2v-6h16v8z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M21 6v11c0 1.7-1.3 3-3 3H3V6h18zm-2.5 1c-.8 0-1.5.7-1.5 1.5s.7 1.5 1.5 1.5S20 9.3 20 8.5 19.3 7 18.5 7zM4 19h14c1.1 0 2-.9 2-2v-6H4v8z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <g id="clear">
- <path id="circle-with-cross" d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm4 11l-1 1-3-3-3 3-1-1 3-3-3-3 1-1 3 3 3-3 1 1-3 3 3 3z"/>
- </g>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <g id="clock">
- <path id="circle" d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm0 1.25a5.75 5.75 0 0 1 0 11.5 5.75 5.75 0 0 1 0-11.5z"/>
- <path id="hands" d="M15.605 14.08s-1.674-1.36-2.81-2.15c.504-1.683 1.194-4.605 1.194-4.605s-3.057 3.765-3.427 4.703c-.325.82 1.024 1.55 1.647 1.178 1.335.387 3.394.873 3.394.873z"/>
- </g>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M8.202 15.834l.568 2.101c.198.765 1.06 1.22 1.8 1.016.698-.193 1.125-.983.926-1.747l-.38-1.37H20L17.229 5 4.155 12.652c-.427.762.088 2.748.823 3.182h3.224z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M15.798 15.834l-.568 2.101c-.198.765-1.06 1.22-1.8 1.016-.698-.193-1.125-.983-.926-1.747l.38-1.37H4L6.771 5l13.074 7.652c.427.762-.088 2.748-.823 3.182h-3.224z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M11 13L5 6h15l-6 7v7c-1.7 0-3-1.3-3-3v-4z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M14 13l6-7H5l6 7v7c1.7 0 3-1.3 3-3v-4z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M15 7c-2 0-3 2-3 2s-1-2-3-2c-2.5 0-4 2-4 4 0 4 5 5 7 8 2-3 7-4 7-8 0-2-1.5-4-4-4z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M14.5 4C11.5 4 9 6.5 9 9.5c0 1 .3 1.9.7 2.8L4 18v2h4v-2h2v-2h2l1.2-1.2c.4.1.9.2 1.3.2 3 0 5.5-2.5 5.5-5.5S17.5 4 14.5 4zM16 9c-.8 0-1.5-.7-1.5-1.5S15.2 6 16 6s1.5.7 1.5 1.5S16.8 9 16 9z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M9.5 4c3 0 5.5 2.5 5.5 5.5 0 1-.3 1.9-.7 2.8L20 18v2h-4v-2h-2v-2h-2l-1.2-1.2c-.4.1-.9.2-1.3.2-3 0-5.5-2.5-5.5-5.5S6.5 4 9.5 4zM8 9c.8 0 1.5-.7 1.5-1.5S8.8 6 8 6s-1.5.7-1.5 1.5S7.2 9 8 9z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M3 7v9c0 1.7 1.3 3 3 3h15V7H3zm8 2h2v2h-2V9zm0 3h2v2h-2v-2zM8 9h2v2H8V9zm0 3h2v2H8v-2zm-1 5H6c-.6 0-1-.4-1-1v-1h2v2zm0-3H5v-2h2v2zm0-3H5V9h2v2zm9 6H8v-2h8v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2zm3 6h-2v-2h2v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M21 7v9c0 1.7-1.3 3-3 3H3V7h18zm-8 2h-2v2h2V9zm0 3h-2v2h2v-2zm3-3h-2v2h2V9zm0 3h-2v2h2v-2zm1 5h1c.6 0 1-.4 1-1v-1h-2v2zm0-3h2v-2h-2v2zm0-3h2V9h-2v2zm-9 6h8v-2H8v2zm0-3h2v-2H8v2zm0-3h2V9H8v2zm-3 6h2v-2H5v2zm0-3h2v-2H5v2zm0-3h2V9H5v2z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M15 14v3l5-4.5L15 8v3H8c0 1.7 1.3 3 3 3h4zm-1-9H4v15h10v-2H6V7h8V5z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M9 14v3l-5-4.5L9 8v3h7c0 1.7-1.3 3-3 3H9zm1-9h10v15H10v-2h8V7h-8V5z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M12 5l2.5 2.5L11 11c-1.2 1.2-1.2 2.8 0 4l5.5-5.5L19 12V5h-7zm5 12H8c-.6 0-1-.4-1-1V7h3L8 5H5v11c0 1.7 1.3 3 3 3h11v-3l-2-2v3z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M12 5L9.5 7.5 13 11c1.2 1.2 1.2 2.8 0 4L7.5 9.5 5 12V5h7zM7 17h9c.6 0 1-.4 1-1V7h-3l2-2h3v11c0 1.7-1.3 3-3 3H5v-3l2-2v3z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M18 8h-1V4H7v4H3v6c0 1.7 1.3 3 3 3h1v3h10v-3h4v-6c0-1.7-1.3-3-3-3zM8 5h8v3H8V5zm8 14H8v-6h8v6z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M6 8h1V4h10v4h4v6c0 1.7-1.3 3-3 3h-1v3H7v-3H3v-6c0-1.7 1.3-3 3-3zm10-3H8v3h8V5zM8 19h8v-6H8v6z"/>
-</g></svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <g id="search">
+ <path id="magnifying-glass" d="M10.5 4a6.5 6.5 0 1 0 2.844 12.344L16 19c1.4 1.4 2.5 1.5 4 0l-4.438-4.438A6.426 6.426 0 0 0 17 10.5 6.5 6.5 0 0 0 10.5 4zm0 2a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9z"/>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <g id="search">
+ <path id="magnifying-glass" d="M13.5 4a6.5 6.5 0 1 1-2.844 12.344L8 19c-1.4 1.4-2.5 1.5-4 0l4.438-4.438A6.426 6.426 0 0 1 7 10.5 6.5 6.5 0 0 1 13.5 4zm0 2a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z"/>
+ </g>
+</svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <g id="search">
- <path id="magnifying-glass" d="M18.87 18.375l-3.987-3.99-.286-.17a5.774 5.774 0 0 0 1.082-3.372C15.67 7.616 13.06 5 9.84 5A5.843 5.843 0 0 0 4 10.844a5.84 5.84 0 0 0 5.842 5.842c1.26 0 2.423-.403 3.377-1.08l.16.286 3.99 3.987c.32.31.91.24 1.33-.18.41-.42.49-1.01.17-1.33zM9.837 14.56a3.72 3.72 0 0 1-3.718-3.717c0-2.05 1.67-3.72 3.72-3.72s3.72 1.668 3.72 3.72a3.722 3.722 0 0 1-3.72 3.718z"/>
- </g>
-</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M4 9h12v2H4V9zm0 3h8v2H4v-2zm0-7h16v3H4V5zm16 14H4v-3h16v3z"/>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M20 9H8v2h12V9zm0 3h-8v2h8v-2zm0-7H4v3h16V5zM4 19h16v-3H4v3z"/>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M20 19H4v-2h16v2zM20 15H4v-2h16v2zM20 11H4V9h16v2z"/>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M20 11H4V9h16v2zM4 12h8v2H4v-2z"/>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M4 11h16V9H4v2zm16 1h-8v2h8v-2z"/>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M17 13H4v-3h13v3zm-5 6H4v-3h8v3zM4 7V4h16v3H4z"/>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M7 13h13v-3H7v3zm5 6h8v-3h-8v3zm8-12V4H4v3h16z"/>
+</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M18 13H6v-2h12"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M18.1 5.1c0 .3-.1.6-.3.9l-1.4 1.4-.9-.8 2.2-2.2c.3.1.4.4.4.7zm-.5 5.3h3.2c0 .3-.1.6-.4.9s-.5.4-.8.4h-2v-1.3zm-6.2-5V2.2c.3 0 .6.1.9.4s.4.5.4.8v2h-1.3zm6.4 11.7c-.3 0-.6-.1-.8-.3l-1.4-1.4.8-.8 2.2 2.2c-.2.2-.5.3-.8.3zM6.2 4.9c.3 0 .6.1.8.3l1.4 1.4-.8.9-2.2-2.3c.2-.2.5-.3.8-.3zm5.2 11.7h1.2v3.2c-.3 0-.6-.1-.9-.4s-.4-.5-.4-.8l.1-2zm-7-6.2h2v1.2H3.2c0-.3.1-.6.4-.9s.5-.3.8-.3zM6.2 16l1.4-1.4.8.8-2.2 2.2c-.2-.2-.3-.5-.3-.8s.1-.6.3-.8z"/>
- <circle cx="12" cy="11" r="4"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M5.9 5.1c0 .3.1.6.3.9l1.4 1.4.9-.8-2.2-2.2c-.3.1-.4.4-.4.7zm.5 5.3H3.2c0 .3.1.6.4.9.3.3.5.4.8.4h2v-1.3zm6.2-5V2.2c-.3 0-.6.1-.9.4-.3.3-.4.5-.4.8v2h1.3zM6.2 17.1c.3 0 .6-.1.8-.3l1.4-1.4-.8-.8-2.2 2.2c.2.2.5.3.8.3zM17.8 4.9c-.3 0-.6.1-.8.3l-1.4 1.4.8.9 2.2-2.3c-.2-.2-.5-.3-.8-.3zm-5.2 11.7h-1.2v3.2c.3 0 .6-.1.9-.4.3-.3.4-.5.4-.8l-.1-2zm7-6.2h-2v1.2h3.2c0-.3-.1-.6-.4-.9-.3-.3-.5-.3-.8-.3zM17.8 16l-1.4-1.4-.8.8 2.2 2.2c.2-.2.3-.5.3-.8 0-.3-.1-.6-.3-.8z"/>
- <circle cx="12" cy="11" r="4" transform="matrix(-1 0 0 1 24 0)"/>
-</g></svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <g id="viewCompact">
+ <circle cx="6" cy="6" r="2"/>
+ <circle cx="12" cy="6" r="2"/>
+ <circle cx="18" cy="6" r="2"/>
+ <circle cx="6" cy="12" r="2"/>
+ <circle cx="12" cy="12" r="2"/>
+ <circle cx="18" cy="12" r="2"/>
+ <circle cx="6" cy="18" r="2"/>
+ <circle cx="12" cy="18" r="2"/>
+ <circle cx="18" cy="18" r="2"/>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <g id="viewDetails">
+ <circle cx="5.5" cy="8.5" r="2.5"/>
+ <path d="M10 6h12v1H10zm0 2h9v1h-9zm0 2h4v1h-4z"/>
+ <circle cx="5.5" cy="16.5" r="2.5"/>
+ <path d="M10 14h12v1H10zm0 2h9v1h-9zm0 2h4v1h-4z"/>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <g id="viewDetails">
+ <circle cx="18.5" cy="8.5" r="2.5"/>
+ <path d="M14 6H2v1h12zm0 2H5v1h9zm0 2h-4v1h4z"/>
+ <circle cx="18.5" cy="16.5" r="2.5"/>
+ <path d="M14 14H2v1h12zm0 2H5v1h9zm0 2h-4v1h4z"/>
+ </g>
+</svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M13 14h5v1h-5v-1zm0 3h5v-1h-5v1zm0 1h5v1h-5v-1zm-1-5v3l-5 3 1-6-4-3 6-1 2-5s1.9 5 2 5l6 1-4 3h-4z"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
- <path d="M11 14H6v1h5v-1zm0 3H6v-1h5v1zm0 1H6v1h5v-1zm1-5v3l5 3-1-6 4-3-6-1-2-5s-1.9 5-2 5l-6 1 4 3h4z"/>
-</g></svg>
}
},
"images": {
+ "alert": { "file": "images/icons/alert.svg", "variants": [ "warning" ] },
"bell": { "file": "images/icons/bell.svg" },
"bellOn": { "file": {
"ltr": "images/icons/bellOn-ltr.svg",
"rtl": "images/icons/bellOn-rtl.svg"
} },
+ "comment": { "file": "images/icons/comment.svg" },
"eye": { "file": "images/icons/eye.svg" },
"eyeClosed": { "file": "images/icons/eyeClosed.svg" },
"message": { "file": {
"ltr": "images/icons/message-ltr.svg",
"rtl": "images/icons/message-rtl.svg"
} },
+ "notice": { "file": "images/icons/notice.svg" },
"signature": { "file": {
"ltr": "images/icons/signature-ltr.svg",
"rtl": "images/icons/signature-rtl.svg"
"ltr": "images/icons/folderPlaceholder-ltr.svg",
"rtl": "images/icons/folderPlaceholder-rtl.svg"
} },
+ "history": { "file": "images/icons/history.svg" },
+ "info": { "file": "images/icons/info.svg" },
"journal": { "file": {
"ltr": "images/icons/journal-ltr.svg",
"rtl": "images/icons/journal-rtl.svg"
"ltr": "images/icons/newspaper-ltr.svg",
"rtl": "images/icons/newspaper-rtl.svg"
} },
+ "tag": { "file": "images/icons/tag.svg", "variants": [ "destructive", "warning", "constructive" ] },
"upload": { "file": {
"ltr": "images/icons/upload-ltr.svg",
"rtl": "images/icons/upload-rtl.svg"
- } }
+ } },
+ "window": { "file": "images/icons/window.svg" }
}
}
},
"images": {
"add": { "file": "images/icons/add.svg", "variants": [ "constructive", "progressive" ] },
+ "advanced": { "file": "images/icons/advanced.svg" },
"bookmark": { "file": {
"ltr": "images/icons/bookmark-ltr.svg",
"rtl": "images/icons/bookmark-rtl.svg"
"ltr": "images/icons/browser-ltr.svg",
"rtl": "images/icons/browser-rtl.svg"
} },
+ "cancel": { "file": "images/icons/cancel.svg", "variants": [ "destructive" ] },
+ "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive", "destructive" ] },
"clear": { "file": "images/icons/clear.svg" },
"clock": { "file": "images/icons/clock.svg" },
+ "close": { "file": "images/icons/close.svg" },
+ "ellipsis": { "file": "images/icons/ellipsis.svg" },
"feedback": {
"file": {
"ltr": "images/icons/feedback-ltr.svg",
"rtl": "images/icons/funnel-rtl.svg"
} },
"heart": { "file": "images/icons/heart.svg" },
+ "help": { "file": {
+ "ltr": "images/icons/help-ltr.svg",
+ "rtl": "images/icons/help-rtl.svg",
+ "lang": {
+ "he,yi": "images/icons/help-ltr.svg"
+ }
+ } },
"key": { "file": {
"ltr": "images/icons/key-ltr.svg",
"rtl": "images/icons/key-rtl.svg"
"ltr": "images/icons/printer-ltr.svg",
"rtl": "images/icons/printer-rtl.svg"
} },
+ "search": { "file": {
+ "ltr": "images/icons/search-ltr.svg",
+ "rtl": "images/icons/search-rtl.svg"
+ }
+ },
+ "settings": { "file": "images/icons/settings.svg" },
"subtract": { "file": "images/icons/subtract.svg" },
"sun": { "file": {
"ltr": "images/icons/sun-ltr.svg",
}
},
"images": {
+ "menu": { "file": "images/icons/menu.svg" },
"stripeFlow": { "file": {
"ltr": "images/icons/stripeFlow-ltr.svg",
"rtl": "images/icons/stripeFlow-rtl.svg"
"ltr": "images/icons/mapPinAdd-ltr.svg",
"rtl": "images/icons/mapPinAdd-rtl.svg"
} },
+ "mapTrail": { "file": {
+ "ltr": "images/icons/mapTrail-ltr.svg",
+ "rtl": "images/icons/mapTrail-rtl.svg"
+ } },
"wikitrail": { "file": {
- "ltr": "images/icons/wikitrail-ltr.svg",
- "rtl": "images/icons/wikitrail-rtl.svg"
- } }
+ "ltr": "images/icons/mapTrail-ltr.svg",
+ "rtl": "images/icons/mapTrail-rtl.svg"
+ }, "deprecated": "Renamed to 'mapTrail' since v0.20.1."
+ }
}
}
} },
"caretDown": { "file": "images/icons/caretDown.svg" },
"caretUp": { "file": "images/icons/caretUp.svg" },
+ "collapse": { "file": "images/icons/collapse.svg" },
"downTriangle": { "file": "images/icons/downTriangle.svg" },
+ "expand": { "file": "images/icons/expand.svg" },
"move": { "file": "images/icons/move.svg" },
+ "next": { "file": {
+ "ltr": "images/icons/move-ltr.svg",
+ "rtl": "images/icons/move-rtl.svg"
+ }
+ },
+ "previous": { "file": {
+ "ltr": "images/icons/move-rtl.svg",
+ "rtl": "images/icons/move-ltr.svg"
+ }
+ },
"upTriangle": { "file": "images/icons/upTriangle.svg" }
}
}
}
},
"images": {
- "add": { "file": "images/icons/add.svg", "variants": [ "constructive", "progressive" ], "deprecated": "Moved since v0.19.5, use from the 'interactive' pack instead." },
- "advanced": { "file": "images/icons/advanced.svg" },
- "alert": { "file": "images/icons/alert.svg", "variants": [ "warning" ] },
- "cancel": { "file": "images/icons/cancel.svg", "variants": [ "destructive" ] },
- "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive", "destructive" ] },
- "circle": { "file": "images/icons/circle.svg", "variants": [ "constructive", "progressive" ] },
- "close": { "file": "images/icons/close.svg" },
- "code": { "file": "images/icons/code.svg" },
- "collapse": { "file": "images/icons/collapse.svg" },
- "comment": { "file": "images/icons/comment.svg" },
- "ellipsis": { "file": "images/icons/ellipsis.svg" },
- "expand": { "file": "images/icons/expand.svg" },
+ "add": { "file": "images/icons/add.svg", "variants": [ "constructive", "progressive" ], "deprecated": "Moved since v0.19.5, use from the 'interactions' pack instead." },
+ "advanced": { "file": "images/icons/advanced.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "alert": { "file": "images/icons/alert.svg", "variants": [ "warning" ], "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
+ "cancel": { "file": "images/icons/cancel.svg", "variants": [ "destructive" ], "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive", "destructive" ], "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "circle": { "file": "images/icons/circle.svg", "variants": [ "constructive", "progressive" ], "deprecated": "Deprecated since v0.20.1, do not use." },
+ "close": { "file": "images/icons/close.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "code": { "file": "images/icons/code.svg", "deprecated": "Moved since v0.16.2, use from the 'editing-advanced' pack instead." },
+ "collapse": { "file": "images/icons/collapse.svg", "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead." },
+ "comment": { "file": "images/icons/comment.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
+ "ellipsis": { "file": "images/icons/ellipsis.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "expand": { "file": "images/icons/expand.svg", "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead." },
"help": { "file": {
"ltr": "images/icons/help-ltr.svg",
"rtl": "images/icons/help-rtl.svg",
"lang": {
"he,yi": "images/icons/help-ltr.svg"
- }
+ },
+ "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead."
} },
- "history": { "file": "images/icons/history.svg" },
- "info": { "file": "images/icons/info.svg" },
- "menu": { "file": "images/icons/menu.svg" },
+ "history": { "file": "images/icons/history.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
+ "info": { "file": "images/icons/info.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
+ "menu": { "file": "images/icons/menu.svg", "deprecated": "Moved since v0.20.1, use from the 'layout' pack instead." },
"next": { "file": {
"ltr": "images/icons/move-ltr.svg",
"rtl": "images/icons/move-rtl.svg"
- } },
- "notice": { "file": "images/icons/notice.svg" },
+ },
+ "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead."
+ },
+ "notice": { "file": "images/icons/notice.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
"previous": { "file": {
"ltr": "images/icons/move-rtl.svg",
"rtl": "images/icons/move-ltr.svg"
- } },
+ },
+ "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead."
+ },
"redo": { "file": {
"ltr": "images/icons/arched-arrow-ltr.svg",
"rtl": "images/icons/arched-arrow-rtl.svg"
- } },
- "remove": { "file": "images/icons/trash.svg", "variants": [ "destructive" ] },
+ },
+ "deprecated": "Moved since v0.16.2, use from the 'editing-core' pack instead."
+ },
+ "remove": { "file": "images/icons/trash.svg", "variants": [ "destructive" ], "deprecated": "Replaced since v0.14.0, use 'trash' from the 'moderation' pack instead." },
"search": { "file": {
"ltr": "images/icons/search-ltr.svg",
"rtl": "images/icons/search-rtl.svg"
- } },
- "settings": { "file": "images/icons/settings.svg" },
- "tag": { "file": "images/icons/tag.svg", "variants": [ "destructive", "warning", "constructive" ] },
+ },
+ "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead."
+ },
+ "settings": { "file": "images/icons/settings.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+ "tag": { "file": "images/icons/tag.svg", "variants": [ "destructive", "warning", "constructive" ], "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
"undo": { "file": {
"ltr": "images/icons/arched-arrow-rtl.svg",
"rtl": "images/icons/arched-arrow-ltr.svg"
- } },
- "window": { "file": "images/icons/window.svg" }
+ },
+ "deprecated": "Moved since v0.16.2, use from the 'editing-core' pack instead."
+ },
+ "window": { "file": "images/icons/window.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." }
}
}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
+ <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
+ <circle cx="8" cy="5" r="2"/>
+</g></svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
+ <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
+ <circle cx="8" cy="5" r="2"/>
+</g></svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
+ <circle cx="8" cy="5" r="2"/>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
+ <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
+ <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
+</g></svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
+ <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
+ <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
+</g></svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
+ <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
+</svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
- <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
- <circle cx="8" cy="5" r="2"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
- <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
- <circle cx="8" cy="5" r="2"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
- <circle cx="8" cy="5" r="2"/>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
- <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
- <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
- <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
- <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
-</g></svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
- <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
-</svg>
display: block;
}
-/* RTL specific CSS ends here **/
+/** RTL specific CSS ends here **/
color: #ba0000;
}
+/* self links */
+a.mw-selflink {
+ color: inherit;
+ font-weight: bold;
+ text-decoration: inherit;
+}
+a.mw-selflink:hover {
+ cursor: inherit;
+ text-decoration: inherit;
+}
+a.mw-selflink:active,
+a.mw-selflink:visited {
+ color: inherit;
+}
+
/* Plainlinks - this can be used to switch
* off special external link styling */
.plainlinks a.external {
left: 0;
text-align: center;
color: #fff;
- text-shadow: 0 0 10px rgba( 0, 0, 0, 0.4 ); /* improves legibility on white background*/
+ text-shadow: 0 0 10px rgba( 0, 0, 0, 0.4 ); /* improves legibility on white background */
font-size: 0.8em;
padding: 5px;
background-color: rgba( 0, 0, 0, 0.5 );
#mw-interwiki-results {
width: 30%;
- display: inline-block; /* used to align iw sidebar with the top of the main search results*/
+ display: inline-block; /* used to align iw sidebar with the top of the main search results */
margin-left: 10%;
}
.searchresults .mw-search-createlink,
font-size: 0.8em;
}
-/* Put some space under template's header, which may contain CAPTCHA HTML.*/
+/* Put some space under template's header, which may contain CAPTCHA HTML. */
section.mw-form-header {
margin-bottom: 10px;
}
--- /dev/null
+/*!
+ * MediaWiki Widgets - CategoryMultiselectWidget class.
+ *
+ * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+( function ( $, mw ) {
+ var NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category;
+
+ /**
+ * Category selector widget. Displays an OO.ui.CapsuleMultiselectWidget
+ * and autocompletes with available categories.
+ *
+ * mw.loader.using( 'mediawiki.widgets.CategoryMultiselectWidget', function () {
+ * var selector = new mw.widgets.CategoryMultiselectWidget( {
+ * searchTypes: [
+ * mw.widgets.CategoryMultiselectWidget.SearchType.OpenSearch,
+ * mw.widgets.CategoryMultiselectWidget.SearchType.InternalSearch
+ * ]
+ * } );
+ *
+ * $( 'body' ).append( selector.$element );
+ *
+ * selector.setSearchTypes( [ mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories ] );
+ * } );
+ *
+ * @class mw.widgets.CategoryMultiselectWidget
+ * @uses mw.Api
+ * @extends OO.ui.CapsuleMultiselectWidget
+ * @mixins OO.ui.mixin.PendingElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {mw.Api} [api] Instance of mw.Api (or subclass thereof) to use for queries
+ * @cfg {number} [limit=10] Maximum number of results to load
+ * @cfg {mw.widgets.CategoryMultiselectWidget.SearchType[]} [searchTypes=[mw.widgets.CategoryMultiselectWidget.SearchType.OpenSearch]]
+ * Default search API to use when searching.
+ */
+ mw.widgets.CategoryMultiselectWidget = function MWCategoryMultiselectWidget( config ) {
+ // Config initialization
+ config = $.extend( {
+ limit: 10,
+ searchTypes: [ mw.widgets.CategoryMultiselectWidget.SearchType.OpenSearch ]
+ }, config );
+ this.limit = config.limit;
+ this.searchTypes = config.searchTypes;
+ this.validateSearchTypes();
+
+ // Parent constructor
+ mw.widgets.CategoryMultiselectWidget.parent.call( this, $.extend( true, {}, config, {
+ menu: {
+ filterFromInput: false
+ },
+ placeholder: mw.msg( 'mw-widgets-categoryselector-add-category-placeholder' ),
+ // This allows the user to both select non-existent categories, and prevents the selector from
+ // being wiped from #onMenuItemsChange when we change the available options in the dropdown
+ allowArbitrary: true
+ } ) );
+
+ // Mixin constructors
+ OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$handle } ) );
+
+ // Event handler to call the autocomplete methods
+ this.$input.on( 'change input cut paste', OO.ui.debounce( this.updateMenuItems.bind( this ), 100 ) );
+
+ // Initialize
+ this.api = config.api || new mw.Api();
+ this.searchCache = {};
+ };
+
+ /* Setup */
+
+ OO.inheritClass( mw.widgets.CategoryMultiselectWidget, OO.ui.CapsuleMultiselectWidget );
+ OO.mixinClass( mw.widgets.CategoryMultiselectWidget, OO.ui.mixin.PendingElement );
+
+ /* Methods */
+
+ /**
+ * Gets new items based on the input by calling
+ * {@link #getNewMenuItems getNewItems} and updates the menu
+ * after removing duplicates based on the data value.
+ *
+ * @private
+ * @method
+ */
+ mw.widgets.CategoryMultiselectWidget.prototype.updateMenuItems = function () {
+ this.getMenu().clearItems();
+ this.getNewMenuItems( this.$input.val() ).then( function ( items ) {
+ var existingItems, filteredItems,
+ menu = this.getMenu();
+
+ // Never show the menu if the input lost focus in the meantime
+ if ( !this.$input.is( ':focus' ) ) {
+ return;
+ }
+
+ // Array of strings of the data of OO.ui.MenuOptionsWidgets
+ existingItems = menu.getItems().map( function ( item ) {
+ return item.data;
+ } );
+
+ // Remove if items' data already exists
+ filteredItems = items.filter( function ( item ) {
+ return existingItems.indexOf( item ) === -1;
+ } );
+
+ // Map to an array of OO.ui.MenuOptionWidgets
+ filteredItems = filteredItems.map( function ( item ) {
+ return new OO.ui.MenuOptionWidget( {
+ data: item,
+ label: item
+ } );
+ } );
+
+ menu.addItems( filteredItems ).toggle( true );
+ }.bind( this ) );
+ };
+
+ /**
+ * @inheritdoc
+ */
+ mw.widgets.CategoryMultiselectWidget.prototype.clearInput = function () {
+ mw.widgets.CategoryMultiselectWidget.parent.prototype.clearInput.call( this );
+ // Abort all pending requests, we won't need their results
+ this.api.abort();
+ };
+
+ /**
+ * Searches for categories based on the input.
+ *
+ * @private
+ * @method
+ * @param {string} input The input used to prefix search categories
+ * @return {jQuery.Promise} Resolves with an array of categories
+ */
+ mw.widgets.CategoryMultiselectWidget.prototype.getNewMenuItems = function ( input ) {
+ var i,
+ promises = [],
+ deferred = $.Deferred();
+
+ if ( $.trim( input ) === '' ) {
+ deferred.resolve( [] );
+ return deferred.promise();
+ }
+
+ // Abort all pending requests, we won't need their results
+ this.api.abort();
+ for ( i = 0; i < this.searchTypes.length; i++ ) {
+ promises.push( this.searchCategories( input, this.searchTypes[ i ] ) );
+ }
+
+ this.pushPending();
+
+ $.when.apply( $, promises ).done( function () {
+ var categoryNames,
+ allData = [],
+ dataSets = Array.prototype.slice.apply( arguments );
+
+ // Collect values from all results
+ allData = allData.concat.apply( allData, dataSets );
+
+ categoryNames = allData
+ // Remove duplicates
+ .filter( function ( value, index, self ) {
+ return self.indexOf( value ) === index;
+ } )
+ // Get Title objects
+ .map( function ( name ) {
+ return mw.Title.newFromText( name );
+ } )
+ // Keep only titles from 'Category' namespace
+ .filter( function ( title ) {
+ return title && title.getNamespaceId() === NS_CATEGORY;
+ } )
+ // Convert back to strings, strip 'Category:' prefix
+ .map( function ( title ) {
+ return title.getMainText();
+ } );
+
+ deferred.resolve( categoryNames );
+
+ } ).always( this.popPending.bind( this ) );
+
+ return deferred.promise();
+ };
+
+ /**
+ * @inheritdoc
+ */
+ mw.widgets.CategoryMultiselectWidget.prototype.createItemWidget = function ( data ) {
+ var title = mw.Title.makeTitle( NS_CATEGORY, data );
+ if ( !title ) {
+ return null;
+ }
+ return new mw.widgets.CategoryCapsuleItemWidget( {
+ apiUrl: this.api.apiUrl || undefined,
+ title: title
+ } );
+ };
+
+ /**
+ * @inheritdoc
+ */
+ mw.widgets.CategoryMultiselectWidget.prototype.getItemFromData = function ( data ) {
+ // This is a bit of a hack... We have to canonicalize the data in the same way that
+ // #createItemWidget and CategoryCapsuleItemWidget will do, otherwise we won't find duplicates.
+ var title = mw.Title.makeTitle( NS_CATEGORY, data );
+ if ( !title ) {
+ return null;
+ }
+ return OO.ui.mixin.GroupElement.prototype.getItemFromData.call( this, title.getMainText() );
+ };
+
+ /**
+ * Validates the values in `this.searchType`.
+ *
+ * @private
+ * @return {boolean}
+ */
+ mw.widgets.CategoryMultiselectWidget.prototype.validateSearchTypes = function () {
+ var validSearchTypes = false,
+ searchTypeEnumCount = Object.keys( mw.widgets.CategoryMultiselectWidget.SearchType ).length;
+
+ // Check if all values are in the SearchType enum
+ validSearchTypes = this.searchTypes.every( function ( searchType ) {
+ return searchType > -1 && searchType < searchTypeEnumCount;
+ } );
+
+ if ( validSearchTypes === false ) {
+ throw new Error( 'Unknown searchType in searchTypes' );
+ }
+
+ // If the searchTypes has mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories
+ // it can be the only search type.
+ if ( this.searchTypes.indexOf( mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories ) > -1 &&
+ this.searchTypes.length > 1
+ ) {
+ throw new Error( 'Can\'t have additional search types with mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories' );
+ }
+
+ // If the searchTypes has mw.widgets.CategoryMultiselectWidget.SearchType.ParentCategories
+ // it can be the only search type.
+ if ( this.searchTypes.indexOf( mw.widgets.CategoryMultiselectWidget.SearchType.ParentCategories ) > -1 &&
+ this.searchTypes.length > 1
+ ) {
+ throw new Error( 'Can\'t have additional search types with mw.widgets.CategoryMultiselectWidget.SearchType.ParentCategories' );
+ }
+
+ return true;
+ };
+
+ /**
+ * Sets and validates the value of `this.searchType`.
+ *
+ * @param {mw.widgets.CategoryMultiselectWidget.SearchType[]} searchTypes
+ */
+ mw.widgets.CategoryMultiselectWidget.prototype.setSearchTypes = function ( searchTypes ) {
+ this.searchTypes = searchTypes;
+ this.validateSearchTypes();
+ };
+
+ /**
+ * Searches categories based on input and searchType.
+ *
+ * @private
+ * @method
+ * @param {string} input The input used to prefix search categories
+ * @param {mw.widgets.CategoryMultiselectWidget.SearchType} searchType
+ * @return {jQuery.Promise} Resolves with an array of categories
+ */
+ mw.widgets.CategoryMultiselectWidget.prototype.searchCategories = function ( input, searchType ) {
+ var deferred = $.Deferred(),
+ cacheKey = input + searchType.toString();
+
+ // Check cache
+ if ( this.searchCache[ cacheKey ] !== undefined ) {
+ return this.searchCache[ cacheKey ];
+ }
+
+ switch ( searchType ) {
+ case mw.widgets.CategoryMultiselectWidget.SearchType.OpenSearch:
+ this.api.get( {
+ formatversion: 2,
+ action: 'opensearch',
+ namespace: NS_CATEGORY,
+ limit: this.limit,
+ search: input
+ } ).done( function ( res ) {
+ var categories = res[ 1 ];
+ deferred.resolve( categories );
+ } ).fail( deferred.reject.bind( deferred ) );
+ break;
+
+ case mw.widgets.CategoryMultiselectWidget.SearchType.InternalSearch:
+ this.api.get( {
+ formatversion: 2,
+ action: 'query',
+ list: 'allpages',
+ apnamespace: NS_CATEGORY,
+ aplimit: this.limit,
+ apfrom: input,
+ apprefix: input
+ } ).done( function ( res ) {
+ var categories = res.query.allpages.map( function ( page ) {
+ return page.title;
+ } );
+ deferred.resolve( categories );
+ } ).fail( deferred.reject.bind( deferred ) );
+ break;
+
+ case mw.widgets.CategoryMultiselectWidget.SearchType.Exists:
+ if ( input.indexOf( '|' ) > -1 ) {
+ deferred.resolve( [] );
+ break;
+ }
+
+ this.api.get( {
+ formatversion: 2,
+ action: 'query',
+ prop: 'info',
+ titles: 'Category:' + input
+ } ).done( function ( res ) {
+ var categories = [];
+
+ $.each( res.query.pages, function ( index, page ) {
+ if ( !page.missing ) {
+ categories.push( page.title );
+ }
+ } );
+
+ deferred.resolve( categories );
+ } ).fail( deferred.reject.bind( deferred ) );
+ break;
+
+ case mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories:
+ if ( input.indexOf( '|' ) > -1 ) {
+ deferred.resolve( [] );
+ break;
+ }
+
+ this.api.get( {
+ formatversion: 2,
+ action: 'query',
+ list: 'categorymembers',
+ cmtype: 'subcat',
+ cmlimit: this.limit,
+ cmtitle: 'Category:' + input
+ } ).done( function ( res ) {
+ var categories = res.query.categorymembers.map( function ( category ) {
+ return category.title;
+ } );
+ deferred.resolve( categories );
+ } ).fail( deferred.reject.bind( deferred ) );
+ break;
+
+ case mw.widgets.CategoryMultiselectWidget.SearchType.ParentCategories:
+ if ( input.indexOf( '|' ) > -1 ) {
+ deferred.resolve( [] );
+ break;
+ }
+
+ this.api.get( {
+ formatversion: 2,
+ action: 'query',
+ prop: 'categories',
+ cllimit: this.limit,
+ titles: 'Category:' + input
+ } ).done( function ( res ) {
+ var categories = [];
+
+ $.each( res.query.pages, function ( index, page ) {
+ if ( !page.missing && $.isArray( page.categories ) ) {
+ categories.push.apply( categories, page.categories.map( function ( category ) {
+ return category.title;
+ } ) );
+ }
+ } );
+
+ deferred.resolve( categories );
+ } ).fail( deferred.reject.bind( deferred ) );
+ break;
+
+ default:
+ throw new Error( 'Unknown searchType' );
+ }
+
+ // Cache the result
+ this.searchCache[ cacheKey ] = deferred.promise();
+
+ return deferred.promise();
+ };
+
+ /**
+ * @enum mw.widgets.CategoryMultiselectWidget.SearchType
+ * Types of search available.
+ */
+ mw.widgets.CategoryMultiselectWidget.SearchType = {
+ /** Search using action=opensearch */
+ OpenSearch: 0,
+
+ /** Search using action=query */
+ InternalSearch: 1,
+
+ /** Search for existing categories with the exact title */
+ Exists: 2,
+
+ /** Search only subcategories */
+ SubCategories: 3,
+
+ /** Search only parent categories */
+ ParentCategories: 4
+ };
+
+ // For backwards compatibility. See T161285.
+ mw.widgets.CategorySelector = mw.widgets.CategoryMultiselectWidget;
+}( jQuery, mediaWiki ) );
+++ /dev/null
-/*!
- * MediaWiki Widgets - CategorySelector class.
- *
- * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
- */
-( function ( $, mw ) {
- var CSP,
- NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category;
-
- /**
- * Category selector widget. Displays an OO.ui.CapsuleMultiselectWidget
- * and autocompletes with available categories.
- *
- * mw.loader.using( 'mediawiki.widgets.CategorySelector', function () {
- * var selector = new mw.widgets.CategorySelector( {
- * searchTypes: [
- * mw.widgets.CategorySelector.SearchType.OpenSearch,
- * mw.widgets.CategorySelector.SearchType.InternalSearch
- * ]
- * } );
- *
- * $( 'body' ).append( selector.$element );
- *
- * selector.setSearchTypes( [ mw.widgets.CategorySelector.SearchType.SubCategories ] );
- * } );
- *
- * @class mw.widgets.CategorySelector
- * @uses mw.Api
- * @extends OO.ui.CapsuleMultiselectWidget
- * @mixins OO.ui.mixin.PendingElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {mw.Api} [api] Instance of mw.Api (or subclass thereof) to use for queries
- * @cfg {number} [limit=10] Maximum number of results to load
- * @cfg {mw.widgets.CategorySelector.SearchType[]} [searchTypes=[mw.widgets.CategorySelector.SearchType.OpenSearch]]
- * Default search API to use when searching.
- */
- function CategorySelector( config ) {
- // Config initialization
- config = $.extend( {
- limit: 10,
- searchTypes: [ CategorySelector.SearchType.OpenSearch ]
- }, config );
- this.limit = config.limit;
- this.searchTypes = config.searchTypes;
- this.validateSearchTypes();
-
- // Parent constructor
- mw.widgets.CategorySelector.parent.call( this, $.extend( true, {}, config, {
- menu: {
- filterFromInput: false
- },
- placeholder: mw.msg( 'mw-widgets-categoryselector-add-category-placeholder' ),
- // This allows the user to both select non-existent categories, and prevents the selector from
- // being wiped from #onMenuItemsChange when we change the available options in the dropdown
- allowArbitrary: true
- } ) );
-
- // Mixin constructors
- OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$handle } ) );
-
- // Event handler to call the autocomplete methods
- this.$input.on( 'change input cut paste', OO.ui.debounce( this.updateMenuItems.bind( this ), 100 ) );
-
- // Initialize
- this.api = config.api || new mw.Api();
- this.searchCache = {};
- }
-
- /* Setup */
-
- OO.inheritClass( CategorySelector, OO.ui.CapsuleMultiselectWidget );
- OO.mixinClass( CategorySelector, OO.ui.mixin.PendingElement );
- CSP = CategorySelector.prototype;
-
- /* Methods */
-
- /**
- * Gets new items based on the input by calling
- * {@link #getNewMenuItems getNewItems} and updates the menu
- * after removing duplicates based on the data value.
- *
- * @private
- * @method
- */
- CSP.updateMenuItems = function () {
- this.getMenu().clearItems();
- this.getNewMenuItems( this.$input.val() ).then( function ( items ) {
- var existingItems, filteredItems,
- menu = this.getMenu();
-
- // Never show the menu if the input lost focus in the meantime
- if ( !this.$input.is( ':focus' ) ) {
- return;
- }
-
- // Array of strings of the data of OO.ui.MenuOptionsWidgets
- existingItems = menu.getItems().map( function ( item ) {
- return item.data;
- } );
-
- // Remove if items' data already exists
- filteredItems = items.filter( function ( item ) {
- return existingItems.indexOf( item ) === -1;
- } );
-
- // Map to an array of OO.ui.MenuOptionWidgets
- filteredItems = filteredItems.map( function ( item ) {
- return new OO.ui.MenuOptionWidget( {
- data: item,
- label: item
- } );
- } );
-
- menu.addItems( filteredItems ).toggle( true );
- }.bind( this ) );
- };
-
- /**
- * @inheritdoc
- */
- CSP.clearInput = function () {
- CategorySelector.parent.prototype.clearInput.call( this );
- // Abort all pending requests, we won't need their results
- this.api.abort();
- };
-
- /**
- * Searches for categories based on the input.
- *
- * @private
- * @method
- * @param {string} input The input used to prefix search categories
- * @return {jQuery.Promise} Resolves with an array of categories
- */
- CSP.getNewMenuItems = function ( input ) {
- var i,
- promises = [],
- deferred = $.Deferred();
-
- if ( $.trim( input ) === '' ) {
- deferred.resolve( [] );
- return deferred.promise();
- }
-
- // Abort all pending requests, we won't need their results
- this.api.abort();
- for ( i = 0; i < this.searchTypes.length; i++ ) {
- promises.push( this.searchCategories( input, this.searchTypes[ i ] ) );
- }
-
- this.pushPending();
-
- $.when.apply( $, promises ).done( function () {
- var categoryNames,
- allData = [],
- dataSets = Array.prototype.slice.apply( arguments );
-
- // Collect values from all results
- allData = allData.concat.apply( allData, dataSets );
-
- categoryNames = allData
- // Remove duplicates
- .filter( function ( value, index, self ) {
- return self.indexOf( value ) === index;
- } )
- // Get Title objects
- .map( function ( name ) {
- return mw.Title.newFromText( name );
- } )
- // Keep only titles from 'Category' namespace
- .filter( function ( title ) {
- return title && title.getNamespaceId() === NS_CATEGORY;
- } )
- // Convert back to strings, strip 'Category:' prefix
- .map( function ( title ) {
- return title.getMainText();
- } );
-
- deferred.resolve( categoryNames );
-
- } ).always( this.popPending.bind( this ) );
-
- return deferred.promise();
- };
-
- /**
- * @inheritdoc
- */
- CSP.createItemWidget = function ( data ) {
- var title = mw.Title.makeTitle( NS_CATEGORY, data );
- if ( !title ) {
- return null;
- }
- return new mw.widgets.CategoryCapsuleItemWidget( {
- apiUrl: this.api.apiUrl || undefined,
- title: title
- } );
- };
-
- /**
- * @inheritdoc
- */
- CSP.getItemFromData = function ( data ) {
- // This is a bit of a hack... We have to canonicalize the data in the same way that
- // #createItemWidget and CategoryCapsuleItemWidget will do, otherwise we won't find duplicates.
- var title = mw.Title.makeTitle( NS_CATEGORY, data );
- if ( !title ) {
- return null;
- }
- return OO.ui.mixin.GroupElement.prototype.getItemFromData.call( this, title.getMainText() );
- };
-
- /**
- * Validates the values in `this.searchType`.
- *
- * @private
- * @return {boolean}
- */
- CSP.validateSearchTypes = function () {
- var validSearchTypes = false,
- searchTypeEnumCount = Object.keys( CategorySelector.SearchType ).length;
-
- // Check if all values are in the SearchType enum
- validSearchTypes = this.searchTypes.every( function ( searchType ) {
- return searchType > -1 && searchType < searchTypeEnumCount;
- } );
-
- if ( validSearchTypes === false ) {
- throw new Error( 'Unknown searchType in searchTypes' );
- }
-
- // If the searchTypes has CategorySelector.SearchType.SubCategories
- // it can be the only search type.
- if ( this.searchTypes.indexOf( CategorySelector.SearchType.SubCategories ) > -1 &&
- this.searchTypes.length > 1
- ) {
- throw new Error( 'Can\'t have additional search types with CategorySelector.SearchType.SubCategories' );
- }
-
- // If the searchTypes has CategorySelector.SearchType.ParentCategories
- // it can be the only search type.
- if ( this.searchTypes.indexOf( CategorySelector.SearchType.ParentCategories ) > -1 &&
- this.searchTypes.length > 1
- ) {
- throw new Error( 'Can\'t have additional search types with CategorySelector.SearchType.ParentCategories' );
- }
-
- return true;
- };
-
- /**
- * Sets and validates the value of `this.searchType`.
- *
- * @param {mw.widgets.CategorySelector.SearchType[]} searchTypes
- */
- CSP.setSearchTypes = function ( searchTypes ) {
- this.searchTypes = searchTypes;
- this.validateSearchTypes();
- };
-
- /**
- * Searches categories based on input and searchType.
- *
- * @private
- * @method
- * @param {string} input The input used to prefix search categories
- * @param {mw.widgets.CategorySelector.SearchType} searchType
- * @return {jQuery.Promise} Resolves with an array of categories
- */
- CSP.searchCategories = function ( input, searchType ) {
- var deferred = $.Deferred(),
- cacheKey = input + searchType.toString();
-
- // Check cache
- if ( this.searchCache[ cacheKey ] !== undefined ) {
- return this.searchCache[ cacheKey ];
- }
-
- switch ( searchType ) {
- case CategorySelector.SearchType.OpenSearch:
- this.api.get( {
- formatversion: 2,
- action: 'opensearch',
- namespace: NS_CATEGORY,
- limit: this.limit,
- search: input
- } ).done( function ( res ) {
- var categories = res[ 1 ];
- deferred.resolve( categories );
- } ).fail( deferred.reject.bind( deferred ) );
- break;
-
- case CategorySelector.SearchType.InternalSearch:
- this.api.get( {
- formatversion: 2,
- action: 'query',
- list: 'allpages',
- apnamespace: NS_CATEGORY,
- aplimit: this.limit,
- apfrom: input,
- apprefix: input
- } ).done( function ( res ) {
- var categories = res.query.allpages.map( function ( page ) {
- return page.title;
- } );
- deferred.resolve( categories );
- } ).fail( deferred.reject.bind( deferred ) );
- break;
-
- case CategorySelector.SearchType.Exists:
- if ( input.indexOf( '|' ) > -1 ) {
- deferred.resolve( [] );
- break;
- }
-
- this.api.get( {
- formatversion: 2,
- action: 'query',
- prop: 'info',
- titles: 'Category:' + input
- } ).done( function ( res ) {
- var categories = [];
-
- $.each( res.query.pages, function ( index, page ) {
- if ( !page.missing ) {
- categories.push( page.title );
- }
- } );
-
- deferred.resolve( categories );
- } ).fail( deferred.reject.bind( deferred ) );
- break;
-
- case CategorySelector.SearchType.SubCategories:
- if ( input.indexOf( '|' ) > -1 ) {
- deferred.resolve( [] );
- break;
- }
-
- this.api.get( {
- formatversion: 2,
- action: 'query',
- list: 'categorymembers',
- cmtype: 'subcat',
- cmlimit: this.limit,
- cmtitle: 'Category:' + input
- } ).done( function ( res ) {
- var categories = res.query.categorymembers.map( function ( category ) {
- return category.title;
- } );
- deferred.resolve( categories );
- } ).fail( deferred.reject.bind( deferred ) );
- break;
-
- case CategorySelector.SearchType.ParentCategories:
- if ( input.indexOf( '|' ) > -1 ) {
- deferred.resolve( [] );
- break;
- }
-
- this.api.get( {
- formatversion: 2,
- action: 'query',
- prop: 'categories',
- cllimit: this.limit,
- titles: 'Category:' + input
- } ).done( function ( res ) {
- var categories = [];
-
- $.each( res.query.pages, function ( index, page ) {
- if ( !page.missing && $.isArray( page.categories ) ) {
- categories.push.apply( categories, page.categories.map( function ( category ) {
- return category.title;
- } ) );
- }
- } );
-
- deferred.resolve( categories );
- } ).fail( deferred.reject.bind( deferred ) );
- break;
-
- default:
- throw new Error( 'Unknown searchType' );
- }
-
- // Cache the result
- this.searchCache[ cacheKey ] = deferred.promise();
-
- return deferred.promise();
- };
-
- /**
- * @enum mw.widgets.CategorySelector.SearchType
- * Types of search available.
- */
- CategorySelector.SearchType = {
- /** Search using action=opensearch */
- OpenSearch: 0,
-
- /** Search using action=query */
- InternalSearch: 1,
-
- /** Search for existing categories with the exact title */
- Exists: 2,
-
- /** Search only subcategories */
- SubCategories: 3,
-
- /** Search only parent categories */
- ParentCategories: 4
- };
-
- mw.widgets.CategorySelector = CategorySelector;
-}( jQuery, mediaWiki ) );
}
};
+ /**
+ * @inheritdoc
+ */
+ mw.widgets.ComplexNamespaceInputWidget.prototype.setDisabled = function ( disabled ) {
+ mw.widgets.ComplexNamespaceInputWidget.parent.prototype.setDisabled.call( this, disabled );
+ this.namespace.setDisabled( disabled );
+
+ if ( this.invert ) {
+ this.invert.setDisabled( disabled );
+ }
+
+ if ( this.associated ) {
+ this.associated.setDisabled( disabled );
+ }
+ };
+
}( jQuery, mediaWiki ) );
this.title.restorePreInfuseState( state.title );
};
+ /**
+ * @inheritdoc
+ */
+ mw.widgets.ComplexTitleInputWidget.prototype.setDisabled = function ( disabled ) {
+ mw.widgets.ComplexTitleInputWidget.parent.prototype.setDisabled.call( this, disabled );
+ this.namespace.setDisabled( disabled );
+ this.title.setDisabled( disabled );
+ };
+
}( jQuery, mediaWiki ) );
return mw.ForeignStructuredUpload.BookletLayout.parent.prototype.initialize.call( this ).then(
function () {
return $.when(
- // Point the CategorySelector to the right wiki
+ // Point the CategoryMultiselectWidget to the right wiki
booklet.upload.getApi().then( function ( api ) {
// If this is a ForeignApi, it will have a apiUrl, otherwise we don't need to do anything
if ( api.apiUrl ) {
- // Can't reuse the same object, CategorySelector calls #abort on its mw.Api instance
+ // Can't reuse the same object, CategoryMultiselectWidget calls #abort on its mw.Api instance
booklet.categoriesWidget.api = new mw.ForeignApi( api.apiUrl );
}
return $.Deferred().resolve();
multiline: true,
autosize: true
} );
- this.categoriesWidget = new mw.widgets.CategorySelector( {
+ this.categoriesWidget = new mw.widgets.CategoryMultiselectWidget( {
// Can't be done here because we don't know the target wiki yet... done in #initialize.
// api: new mw.ForeignApi( ... ),
$overlay: this.$overlay
-/* global moment*/
+/* global moment */
( function ( $, mw, moment ) {
/**
* This function returns the styleSheet object for convience (due to cross-browsers
* difference as to where it is located).
*
- * var sheet = mw.util.addCSS( '.foobar { display: none; }' );
+ * var sheet = util.addCSS( '.foobar { display: none; }' );
* $( foo ).click( function () {
* // Toggle the sheet on and off
* sheet.disabled = !sheet.disabled;
* (e.g. `document.getElementById( 'foobar' )`) or a jQuery-selector
* (e.g. `'#foobar'`) for that item.
*
- * mw.util.addPortletLink(
+ * util.addPortletLink(
* 'p-tb', 'https://www.mediawiki.org/',
* 'mediawiki.org', 't-mworg', 'Go to mediawiki.org', 'm', '#t-print'
* );
*
- * var node = mw.util.addPortletLink(
+ * var node = util.addPortletLink(
* 'p-tb',
* new mw.Title( 'Special:Example' ).getUrl(),
* 'Example'
}, 'Use mw.notify instead.' );
mw.util = util;
+ module.exports = util;
}( mediaWiki, jQuery ) );
-/* global moment, mw */
+/* global mediaWiki, moment */
-// HACK: Overwrite moment's i18n with MediaWiki's for the current language so that
-// wgTranslateNumerals is respected.
-moment.updateLocale( moment.locale(), {
- preparse: function ( s ) {
- var i,
- table = mw.language.getDigitTransformTable();
- if ( mw.config.get( 'wgTranslateNumerals' ) ) {
- for ( i = 0; i < 10; i++ ) {
- if ( table[ i ] !== undefined ) {
- s = s.replace( new RegExp( mw.RegExp.escape( table[ i ] ), 'g' ), i );
+( function ( mw ) {
+ // HACK: Overwrite moment's i18n with MediaWiki's for the current language so that
+ // wgTranslateNumerals is respected.
+ moment.updateLocale( moment.locale(), {
+ preparse: function ( s ) {
+ var i,
+ table = mw.language.getDigitTransformTable();
+ if ( mw.config.get( 'wgTranslateNumerals' ) ) {
+ for ( i = 0; i < 10; i++ ) {
+ if ( table[ i ] !== undefined ) {
+ s = s.replace( new RegExp( mw.RegExp.escape( table[ i ] ), 'g' ), i );
+ }
}
}
- }
- // HACK: momentjs replaces commas in some languages, which is the only other use of preparse
- // aside from digit transformation. We can only override preparse, not extend it, so we
- // have to replicate the comma replacement functionality here.
- if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
- s = s.replace( /،/g, ',' );
- }
- return s;
- },
- postformat: function ( s ) {
- var i,
- table = mw.language.getDigitTransformTable();
- if ( mw.config.get( 'wgTranslateNumerals' ) ) {
- for ( i = 0; i < 10; i++ ) {
- if ( table[ i ] !== undefined ) {
- s = s.replace( new RegExp( i, 'g' ), table[ i ] );
+ // HACK: momentjs replaces commas in some languages, which is the only other use of preparse
+ // aside from digit transformation. We can only override preparse, not extend it, so we
+ // have to replicate the comma replacement functionality here.
+ if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
+ s = s.replace( /،/g, ',' );
+ }
+ return s;
+ },
+ postformat: function ( s ) {
+ var i,
+ table = mw.language.getDigitTransformTable();
+ if ( mw.config.get( 'wgTranslateNumerals' ) ) {
+ for ( i = 0; i < 10; i++ ) {
+ if ( table[ i ] !== undefined ) {
+ s = s.replace( new RegExp( i, 'g' ), table[ i ] );
+ }
}
}
+ // HACK: momentjs replaces commas in some languages, which is the only other use of postformat
+ // aside from digit transformation. We can only override postformat, not extend it, so we
+ // have to replicate the comma replacement functionality here.
+ if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
+ s = s.replace( /,/g, '،' );
+ }
+ return s;
}
- // HACK: momentjs replaces commas in some languages, which is the only other use of postformat
- // aside from digit transformation. We can only override postformat, not extend it, so we
- // have to replicate the comma replacement functionality here.
- if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
- s = s.replace( /,/g, '،' );
- }
- return s;
- }
-} );
+ } );
+}( mediaWiki ) );
$before = 'n';
} elseif ( $prevResults[$test] == 1 ) {
$before = 'p';
- } else /* if ( $prevResults[$test] == 0 )*/ {
+ } else /* if ( $prevResults[$test] == 0 ) */ {
$before = 'f';
}
$after = 'n';
} elseif ( $this->results[$test] == 1 ) {
$after = 'p';
- } else /*if ( $this->results[$test] == 0 ) */ {
+ } else /* if ( $this->results[$test] == 0 ) */ {
$after = 'f';
}
* @ingroup Testing
*/
+use Wikimedia\Rdbms\IMaintainableDatabase;
+
class DbTestRecorder extends TestRecorder {
public $version;
+ /** @var Database */
private $db;
- public function __construct( IDatabase $db ) {
+ public function __construct( IMaintainableDatabase $db ) {
$this->db = $db;
}
* @file
* @ingroup Testing
*/
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\MediaWikiServices;
use Wikimedia\ScopedCallback;
!! wikitext
[[Bug462]] [[Bug462]]
!! html/php
-<p><strong class="selflink">Bug462</strong> <strong class="selflink">Bug462</strong>
+<p><a class="mw-selflink selflink">Bug462</a> <a class="mw-selflink selflink">Bug462</a>
</p>
!! html/php+tidy
-<p><strong class="selflink">Bug462</strong> <strong class="selflink">Bug462</strong></p>
+<p><a class="mw-selflink selflink">Bug462</a> <a class="mw-selflink selflink">Bug462</a></p>
!! html/parsoid
<p><a rel="mw:WikiLink" href="./Bug462" title="Bug462">Bug462</a> <a rel="mw:WikiLink" href="./Bug462" title="Bug462">Bug462</a></p>
!! end
!! wikitext
[[0]]
!! html
-<p><strong class="selflink">0</strong>
+<p><a class="mw-selflink selflink">0</a>
</p>
!!end
!! wikitext
[[local:Main Page]]
!! html/php
-<p><strong class="selflink">local:Main Page</strong>
+<p><a class="mw-selflink selflink">local:Main Page</a>
</p>
!! html/parsoid
<p><a rel="mw:WikiLink" href="./Main_Page" title="Main Page">local:Main Page</a></p>
Magic Word: {{FULLPAGENAME}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{FULLPAGENAME}}
-!! html
+!! html/*
<p>User:Ævar Arnfjörð Bjarmason
</p>
!! end
Magic Word: {{FULLPAGENAMEE}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{FULLPAGENAMEE}}
-!! html
+!! html/*
<p>User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
</p>
!! end
Magic Word: {{TALKSPACE}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{TALKSPACE}}
-!! html
+!! html/*
<p>User talk
</p>
!! end
Magic Word: {{TALKSPACE}}, same namespace
!! options
title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{TALKSPACE}}
-!! html
+!! html/*
<p>User talk
</p>
!! end
Magic Word: {{TALKSPACE}}, main namespace
!! options
title=[[Parser Test]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{TALKSPACE}}
-!! html
+!! html/*
<p>Talk
</p>
!! end
Magic Word: {{TALKSPACEE}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{TALKSPACEE}}
-!! html
+!! html/*
<p>User_talk
</p>
!! end
Magic Word: {{SUBJECTSPACE}}
!! options
title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SUBJECTSPACE}}
-!! html
+!! html/*
<p>User
</p>
!! end
Magic Word: {{SUBJECTSPACE}}, same namespace
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SUBJECTSPACE}}
-!! html
+!! html/*
<p>User
</p>
!! end
Magic Word: {{SUBJECTSPACE}}, main namespace
!! options
title=[[Parser Test]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SUBJECTSPACE}}
-!! html
+!! html/*
!! end
Magic Word: {{SUBJECTSPACEE}}
!! options
title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SUBJECTSPACEE}}
-!! html
+!! html/*
<p>User
</p>
!! end
Magic Word: {{NAMESPACE}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{NAMESPACE}}
-!! html
+!! html/*
<p>User
</p>
!! end
Magic Word: {{NAMESPACEE}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{NAMESPACEE}}
-!! html
+!! html/*
<p>User
</p>
!! end
Magic Word: {{NAMESPACENUMBER}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{NAMESPACENUMBER}}
-!! html
+!! html/*
<p>2
</p>
!! end
Magic Word: {{SUBPAGENAME}}
!! options
title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SUBPAGENAME}}
-!! html
+!! html/*
<p>sub ö
</p>
!! end
Magic Word: {{SUBPAGENAMEE}}
!! options
title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SUBPAGENAMEE}}
-!! html
+!! html/*
<p>sub_%C3%B6
</p>
!! end
Magic Word: {{ROOTPAGENAME}}
!! options
title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{ROOTPAGENAME}}
-!! html
+!! html/*
<p>Ævar Arnfjörð Bjarmason
</p>
!! end
Magic Word: {{ROOTPAGENAMEE}}
!! options
title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{ROOTPAGENAMEE}}
-!! html
+!! html/*
<p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
</p>
!! end
Magic Word: {{BASEPAGENAME}}
!! options
title=[[Ævar Arnfjörð Bjarmason/sub]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{BASEPAGENAME}}
-!! html
+!! html/*
<p>Ævar Arnfjörð Bjarmason
</p>
!! end
Magic Word: {{BASEPAGENAMEE}}
!! options
title=[[Ævar Arnfjörð Bjarmason/sub]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{BASEPAGENAMEE}}
-!! html
+!! html/*
<p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
</p>
!! end
Magic Word: {{TALKPAGENAME}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{TALKPAGENAME}}
-!! html
+!! html/*
<p>User talk:Ævar Arnfjörð Bjarmason
</p>
!! end
Magic Word: {{TALKPAGENAMEE}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{TALKPAGENAMEE}}
-!! html
+!! html/*
<p>User_talk:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
</p>
!! end
Magic Word: {{SUBJECTPAGENAME}}
!! options
title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SUBJECTPAGENAME}}
-!! html
+!! html/*
<p>User:Ævar Arnfjörð Bjarmason
</p>
!! end
Magic Word: {{SUBJECTPAGENAMEE}}
!! options
title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SUBJECTPAGENAMEE}}
-!! html
+!! html/*
<p>User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
</p>
!! end
!! test
Magic Word: {{NUMBEROFFILES}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{NUMBEROFFILES}}
-!! html
+!! html/*
<p>7
</p>
!! end
Magic Word: {{PAGENAME}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{PAGENAME}}
-!! html
+!! html/*
<p>Ævar Arnfjörð Bjarmason
</p>
!! end
Magic Word: {{PAGENAME}} with metacharacters
!! options
title=[['foo & bar = baz']]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
''{{PAGENAME}}''
!! html/php
Magic Word: {{PAGENAME}} with metacharacters (T28781)
!! options
title=[[*RFC 1234 http://example.com/]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{PAGENAME}}
!! html/php
Magic Word: {{PAGENAMEE}}
!! options
title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{PAGENAMEE}}
-!! html
+!! html/*
<p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
</p>
!! end
Magic Word: {{PAGENAMEE}} with metacharacters (T28781)
!! options
title=[[*RFC 1234 http://example.com/]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{PAGENAMEE}}
!! html/php
!! test
Magic Word: {{REVISIONID}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{REVISIONID}}
-!! html
+!! html/*
<p>1337
</p>
!! end
!! test
Magic Word: {{SCRIPTPATH}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SCRIPTPATH}}
-!! html
+!! html/*
!! end
!! test
Magic Word: {{STYLEPATH}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{STYLEPATH}}
-!! html
+!! html/*
<p>/skins
</p>
!! end
!! test
Magic Word: {{SERVER}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SERVER}}
-!! html
+!! html/*
<p><a rel="nofollow" class="external free" href="http://example.org">http://example.org</a>
</p>
!! end
!! test
Magic Word: {{SERVERNAME}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SERVERNAME}}
-!! html
+!! html/*
<p>example.org
</p>
!! end
!! test
Magic Word: {{SITENAME}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{SITENAME}}
-!! html
+!! html/*
<p>MediaWiki
</p>
!! end
Magic Word: {{PAGELANGUAGE}}
!! options
language=fr
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{PAGELANGUAGE}}
-!! html
+!! html/*
<p>fr
</p>
!! end
!! test
Magic Word: {{PAGELANGUAGE}} on a page with no explicitly set language
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
!! wikitext
{{PAGELANGUAGE}}
-!! html
+!! html/*
<p>en
</p>
!! end
!! options
thumbsize=220
!! wikitext
-[[File:Foobar.jpg|thumb=Thumb.png|Title]]
+[[File:Foobar.jpg|thumbnail=Thumb.png|Title]]
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Foobar.jpg"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
</gallery>
!! end
+!! test
+Gallery with class attribute
+!! options
+parsoid={
+ "nativeGallery": true
+}
+!! wikitext
+<gallery class="center">
+File:Foobar.jpg
+</gallery>
+!! html/php
+<ul class="gallery mw-gallery-traditional center">
+ <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+ <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+ <div class="gallerytext">
+ </div>
+ </div></li>
+</ul>
+
+!! html/parsoid
+<ul class="gallery mw-gallery-traditional center" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"class":"center"},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><span style="display: inline-block; height: 100%; vertical-align: middle;"></span><span typeof="mw:Image" style="vertical-align: middle; display: inline-block;"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></span></div><div class="gallerytext"></div></li>
+</ul>
+!! end
+
!! test
HTML Hex character encoding (spells the word "JavaScript")
!! options
!! wikitext
Both [[Dunav]] and [[Дунав]] are names for this river.
!! html
-<p>Both <strong class="selflink">Dunav</strong> and <strong class="selflink">Дунав</strong> are names for this river.
+<p>Both <a class="mw-selflink selflink">Dunav</a> and <a class="mw-selflink selflink">Дунав</a> are names for this river.
</p>
!!end
!! wikitext
[[Дуна]] is not a self-link while [[Duna]] and [[Dуна]] are still self-links.
!! html
-<p><a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Дуна</a> is not a self-link while <strong class="selflink">Duna</strong> and <strong class="selflink">Dуна</strong> are still self-links.
+<p><a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Дуна</a> is not a self-link while <a class="mw-selflink selflink">Duna</a> and <a class="mw-selflink selflink">Dуна</a> are still self-links.
</p>
!! end
!! wikitext
[[Dуна]] is a self-link while [[Dunа#Foo]] and [[Dуна#Foo]] are not self-links.
!! html
-<p><strong class="selflink">Dуна</strong> is a self-link while <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dunа#Foo</a> and <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dуна#Foo</a> are not self-links.
+<p><a class="mw-selflink selflink">Dуна</a> is a self-link while <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dunа#Foo</a> and <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dуна#Foo</a> are not self-links.
</p>
!! end
!! wikitext
<indicator name=" "></indicator>
<indicator></indicator>
-!! html
+!! html/php
<p><span class="error"><strong>Error:</strong> Page status indicators' <code>name</code> attribute must not be empty.</span>
<span class="error"><strong>Error:</strong> Page status indicators' <code>name</code> attribute must not be empty.</span>
</p>
!! wikitext
<indicator name="empty" />
<indicator name="name"></indicator>
-!! html
+!! html/php
empty=
name=
<p><br />
<indicator name="10">Two
paragraphs</indicator>
-!! html
+!! html/php
01=hello world
02=<a href="/wiki/Main_Page" title="Main Page">Main Page</a>
03=<img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/25px-Foobar.jpg" width="25" height="3" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/38px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg 2x" />
## recognized as an extension tag w/o a native handler.
!! test
LST Sections: Newfangled approach
-!! options
-parsoid={ "suppressErrors": true }
!! wikitext
<section begin="2011-05-16" />
<section end="2014-04-10 (MW 1.23wmf22)" />
!! html/parsoid
-<p><span typeof="mw:Extension/section" about="#mwt1" data-parsoid='{"stx":"html","selfClose":true,"src":"<section begin=\"2011-05-16\" />","tagWidths":[30,0]}'><section begin="2011-05-16" /></span>
-<span typeof="mw:Extension/section" about="#mwt2" data-parsoid='{"stx":"html","selfClose":true,"src":"<section end=\"2014-04-10 (MW 1.23wmf22)\" />","tagWidths":[43,0]}'><section end="2014-04-10 (MW 1.23wmf22)" /></span></p>
+<p><span typeof="mw:Error mw:Extension/section" about="#mwt1" data-mw='{"name":"section","attrs":{"begin":"2011-05-16"},"body":null,"errors":[{"key":"mw-api-extexpand-error","message":"Could not expand extension source."}]}'><section begin="2011-05-16" /></span>
+<span typeof="mw:Error mw:Extension/section" about="#mwt2" data-mw='{"name":"section","attrs":{"end":"2014-04-10 (MW 1.23wmf22)"},"body":null,"errors":[{"key":"mw-api-extexpand-error","message":"Could not expand extension source."}]}'><section end="2014-04-10 (MW 1.23wmf22)" /></span></p>
!! end
#--------- Test stripping of empty nodes in template content ----------
parsoid=html2wt
!! html/parsoid
<p><a rel="mw:ExtLink" href="http://google.com">[google]</a>
-<a rel="mw:ExtLink" href="http://google.com">google]</a></p>
+<a rel="mw:ExtLink" href="http://google.com">google]</a>
+<a rel="mw:ExtLink" href="http://google.com">goog] le</a></p>
<p>[http://google.com]</p>
<p>[http://google.com google]</p>
<p>[<a rel="mw:ExtLink" href="http://google.com">http://google.com</a>]</p>
!! wikitext
[http://google.com <nowiki>[google]</nowiki>]
[http://google.com <nowiki>google]</nowiki>]
+[http://google.com <nowiki>goog] le</nowiki>]
<nowiki>[http://google.com]</nowiki>
!! html/php
<p><a rel="nofollow" class="external text" href="http://google.com">[google]</a>
<a rel="nofollow" class="external text" href="http://google.com">google]</a>
+<a rel="nofollow" class="external text" href="http://google.com">goog] le</a>
</p><p>[http://google.com]
</p><p>[http://google.com google]
</p><p>[<a rel="nofollow" class="external free" href="http://google.com">http://google.com</a>]
!! test
4. No escaping needed
!! options
-options=html2wt
+parsoid=html2wt
!! html/parsoid
<p>'<span><i>bar</i></span>'
'<span><b>bar</b></span>'
!! test
4. Leading whitespace in indent-pre suppressing contexts should not be escaped
!! options
-options=html2wt
+parsoid=html2wt
!! html/parsoid
<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
!! wikitext
# Tests spec'ing wikitext serialization norms |
# --------------------------------------------
+!! test
+Serialize multi-line indent-pre starting with wikitext syntax
+!! options
+parsoid=html2wt
+!! html/parsoid
+<pre>* 1
+** 2
+* 3</pre>
+!! wikitext
+ * 1
+ ** 2
+ * 3
+!! end
+
!! test
1. Categories should always be serialized on their own line
!! options
}
public function provideAuthentication() {
- $user = \User::newFromName( 'UTSysop' );
- $id = $user->getId();
- $name = $user->getName();
-
$rememberReq = new RememberMeAuthenticationRequest;
$rememberReq->action = AuthManager::ACTION_LOGIN;
$restartResponse2->createRequest->action = AuthManager::ACTION_LOGIN;
$restartResponse2->neededRequests = [ $rememberReq, $restartResponse2->createRequest ];
+ $userName = 'UTSysop';
+
return [
'Failure in pre-auth' => [
StatusValue::newFatal( 'fail-from-pre' ),
'Secondary fail' => [
StatusValue::newGood(),
[
- AuthenticationResponse::newPass( $name ),
+ AuthenticationResponse::newPass( $userName ),
],
$tmp = [
AuthenticationResponse::newFail( $this->message( 'fail-in-secondary' ) ),
'Secondary UI, then abstain' => [
StatusValue::newGood(),
[
- AuthenticationResponse::newPass( $name ),
+ AuthenticationResponse::newPass( $userName ),
],
[
$tmp = AuthenticationResponse::newUI( [ $req ], $this->message( '...' ) ),
],
[
$tmp,
- AuthenticationResponse::newPass( $name ),
+ AuthenticationResponse::newPass( $userName ),
]
],
'Secondary pass' => [
StatusValue::newGood(),
[
- AuthenticationResponse::newPass( $name ),
+ AuthenticationResponse::newPass( $userName ),
],
[
AuthenticationResponse::newPass()
],
[
- AuthenticationResponse::newPass( $name ),
+ AuthenticationResponse::newPass( $userName ),
]
],
];
<?php
+use Wikimedia\Rdbms\IDatabase;
+
/**
* @group Database
* @group Database
* @covers Http::getProxy
*/
public function testGetProxy() {
+ $this->setMwGlobals( 'wgHTTPProxy', false );
+ $this->assertEquals(
+ '',
+ Http::getProxy(),
+ 'default setting'
+ );
+
$this->setMwGlobals( 'wgHTTPProxy', 'proxy.domain.tld' );
$this->assertEquals(
'proxy.domain.tld',
];
}
+ public static function provideRelativeRedirects() {
+ return [
+ [
+ 'location' => [ 'http://newsite/file.ext', '/newfile.ext' ],
+ 'final' => 'http://newsite/newfile.ext',
+ 'Relative file path Location: interpreted as full URL'
+ ],
+ [
+ 'location' => [ 'https://oldsite/file.ext' ],
+ 'final' => 'https://oldsite/file.ext',
+ 'Location to the HTTPS version of the site'
+ ],
+ [
+ 'location' => [
+ '/anotherfile.ext',
+ 'http://anotherfile/hoster.ext',
+ 'https://anotherfile/hoster.ext'
+ ],
+ 'final' => 'https://anotherfile/hoster.ext',
+ 'Relative file path Location: should keep the latest host and scheme!'
+ ],
+ [
+ 'location' => [ '/anotherfile.ext' ],
+ 'final' => 'http://oldsite/anotherfile.ext',
+ 'Relative Location without domain '
+ ],
+ [
+ 'location' => null,
+ 'final' => 'http://oldsite/file.ext',
+ 'No Location (no redirect) '
+ ],
+ ];
+ }
+
/**
* Warning:
*
* These tests are for code that makes use of an artifact of how CURL
* handles header reporting on redirect pages, and will need to be
- * rewritten when T31232 is taken care of (high-level handling of
- * HTTP redirects).
+ * rewritten when T31232 is taken care of (high-level handling of HTTP redirects).
+ *
+ * @dataProvider provideRelativeRedirects
+ * @covers MWHttpRequest::getFinalUrl
*/
- public function testRelativeRedirections() {
+ public function testRelativeRedirections( $location, $final, $message = null ) {
$h = MWHttpRequestTester::factory( 'http://oldsite/file.ext', [], __METHOD__ );
-
- # Forge a Location header
- $h->setRespHeaders( 'location', [
- 'http://newsite/file.ext',
- '/newfile.ext',
- ]
- );
- # Verify we correctly fix the Location
- $this->assertEquals(
- 'http://newsite/newfile.ext',
- $h->getFinalUrl(),
- "Relative file path Location: interpreted as full URL"
- );
-
- $h->setRespHeaders( 'location', [
- 'https://oldsite/file.ext'
- ]
- );
- $this->assertEquals(
- 'https://oldsite/file.ext',
- $h->getFinalUrl(),
- "Location to the HTTPS version of the site"
- );
-
- $h->setRespHeaders( 'location', [
- '/anotherfile.ext',
- 'http://anotherfile/hoster.ext',
- 'https://anotherfile/hoster.ext'
- ]
- );
- $this->assertEquals(
- 'https://anotherfile/hoster.ext',
- $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!" )
- );
+ // Forge a Location header
+ $h->setRespHeaders( 'location', $location );
+ // Verify it correctly fixes the Location
+ $this->assertEquals( $final, $h->getFinalUrl(), $message );
}
/**
* Extension API: 20140829
*
* Commented out constants that were removed in PHP 5.6.0
- *
- * @covers CurlHttpRequest::execute
*/
public function provideCurlConstants() {
return [
/**
* Added this test based on an issue experienced with HHVM 3.3.0-dev
- * where it did not define a cURL constant.
+ * where it did not define a cURL constant. T72570
*
- * T72570
* @dataProvider provideCurlConstants
*/
public function testCurlConstants( $value ) {
<?php
use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
class ResourceLoaderWikiModuleTest extends ResourceLoaderTestCase {
return [
[
new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
- Title::newFromText( 'MainNamespaceArticle' )
+ 'MainNamespaceArticle'
],
[
new ForeignTitle( null, '', 'MainNamespaceArticle' ),
- Title::newFromText( 'MainNamespaceArticle' )
+ 'MainNamespaceArticle'
],
[
new ForeignTitle( 1, 'Discussion', 'Nice_talk' ),
- Title::newFromText( 'Talk:Nice_talk' )
+ 'Talk:Nice_talk'
],
[
new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
- Title::newFromText( 'Bogus:Nice_talk' )
+ 'Bogus:Nice_talk'
],
[
new ForeignTitle( 100, 'Bogus', 'Nice_talk' ),
- Title::newFromText( 'Bogus:Nice_talk' ) // not Portal:Nice_talk
+ 'Bogus:Nice_talk' // not Portal:Nice_talk
],
[
new ForeignTitle( 1, 'Bogus', 'Nice_talk' ),
- Title::newFromText( 'Talk:Nice_talk' ) // not Bogus:Nice_talk
+ 'Talk:Nice_talk' // not Bogus:Nice_talk
],
[
new ForeignTitle( 100, 'Portal', 'Nice_talk' ),
- Title::newFromText( 'Portal:Nice_talk' )
+ 'Portal:Nice_talk'
],
[
new ForeignTitle( 724, 'Portal', 'Nice_talk' ),
- Title::newFromText( 'Portal:Nice_talk' )
+ 'Portal:Nice_talk'
],
[
new ForeignTitle( 2, 'Portal', 'Nice_talk' ),
- Title::newFromText( 'User:Nice_talk' )
+ 'User:Nice_talk'
],
];
}
/**
* @dataProvider basicProvider
*/
- public function testBasic( ForeignTitle $foreignTitle, Title $title ) {
+ public function testBasic( ForeignTitle $foreignTitle, $titleText ) {
$factory = new NaiveImportTitleFactory();
$testTitle = $factory->createTitleFromForeignTitle( $foreignTitle );
+ $title = Title::newFromText( $titleText );
$this->assertTrue( $title->equals( $testTitle ) );
}
[
new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
0,
- Title::newFromText( 'MainNamespaceArticle' )
+ 'MainNamespaceArticle'
],
[
new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
2,
- Title::newFromText( 'User:MainNamespaceArticle' )
+ 'User:MainNamespaceArticle'
],
[
new ForeignTitle( 1, 'Discussion', 'Nice_talk' ),
0,
- Title::newFromText( 'Nice_talk' )
+ 'Nice_talk'
],
[
new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
0,
- Title::newFromText( 'Bogus:Nice_talk' )
+ 'Bogus:Nice_talk'
],
[
new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
2,
- Title::newFromText( 'User:Bogus:Nice_talk' )
+ 'User:Bogus:Nice_talk'
],
];
}
/**
* @dataProvider basicProvider
*/
- public function testBasic( ForeignTitle $foreignTitle, $ns, Title $title ) {
+ public function testBasic( ForeignTitle $foreignTitle, $ns, $titleText ) {
$factory = new NamespaceImportTitleFactory( $ns );
$testTitle = $factory->createTitleFromForeignTitle( $foreignTitle );
+ $title = Title::newFromText( $titleText );
$this->assertTrue( $title->equals( $testTitle ) );
}
( function ( mw, $ ) {
- var
+ var util = require( 'mediawiki.util' ),
// Based on IPTest.php > testisIPv4
IPV4_CASES = [
[ false, false, 'Boolean false is not an IP' ],
} ) );
QUnit.test( 'rawurlencode', function ( assert ) {
- assert.equal( mw.util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
+ assert.equal( util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
} );
QUnit.test( 'escapeId', function ( assert ) {
'Test:A & B/Here': 'Test:A_.26_B.2FHere',
'A&B&C&amp;D&amp;amp;E': 'A.26B.26amp.3BC.26amp.3Bamp.3BD.26amp.3Bamp.3Bamp.3BE'
}, function ( input, output ) {
- assert.equal( mw.util.escapeId( input ), output );
+ assert.equal( util.escapeId( input ), output );
} );
} );
QUnit.test( 'wikiUrlencode', function ( assert ) {
- assert.equal( mw.util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
+ assert.equal( util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
// See also wfUrlencodeTest.php#provideURLS
$.each( {
'+': '%2B',
'<>': '%3C%3E',
'\'': '%27'
}, function ( input, output ) {
- assert.equal( mw.util.wikiUrlencode( input ), output );
+ assert.equal( util.wikiUrlencode( input ), output );
} );
} );
wgPageName: 'Foobar'
} );
- href = mw.util.getUrl( 'Sandbox' );
+ href = util.getUrl( 'Sandbox' );
assert.equal( href, '/wiki/Sandbox', 'simple title' );
- href = mw.util.getUrl( 'Foo:Sandbox? 5+5=10! (test)/sub ' );
+ href = util.getUrl( 'Foo:Sandbox? 5+5=10! (test)/sub ' );
assert.equal( href, '/wiki/Foo:Sandbox%3F_5%2B5%3D10!_(test)/sub_', 'complex title' );
// T149767
- href = mw.util.getUrl( 'My$$test$$$$$title' );
+ href = util.getUrl( 'My$$test$$$$$title' );
assert.equal( href, '/wiki/My$$test$$$$$title', 'title with multiple consecutive dollar signs' );
- href = mw.util.getUrl();
+ href = util.getUrl();
assert.equal( href, '/wiki/Foobar', 'default title' );
- href = mw.util.getUrl( null, { action: 'edit' } );
+ href = util.getUrl( null, { action: 'edit' } );
assert.equal( href, '/w/index.php?title=Foobar&action=edit', 'default title with query string' );
- href = mw.util.getUrl( 'Sandbox', { action: 'edit' } );
+ href = util.getUrl( 'Sandbox', { action: 'edit' } );
assert.equal( href, '/w/index.php?title=Sandbox&action=edit', 'simple title with query string' );
// Test fragments
- href = mw.util.getUrl( 'Foo:Sandbox#Fragment', { action: 'edit' } );
+ href = util.getUrl( 'Foo:Sandbox#Fragment', { action: 'edit' } );
assert.equal( href, '/w/index.php?title=Foo:Sandbox&action=edit#Fragment', 'namespaced title with query string and fragment' );
- href = mw.util.getUrl( 'Sandbox#', { action: 'edit' } );
+ href = util.getUrl( 'Sandbox#', { action: 'edit' } );
assert.equal( href, '/w/index.php?title=Sandbox&action=edit', 'title with query string and empty fragment' );
- href = mw.util.getUrl( 'Sandbox', {} );
+ href = util.getUrl( 'Sandbox', {} );
assert.equal( href, '/wiki/Sandbox', 'title with empty query string' );
- href = mw.util.getUrl( '#Fragment' );
+ href = util.getUrl( '#Fragment' );
assert.equal( href, '/wiki/#Fragment', 'empty title with fragment' );
- href = mw.util.getUrl( '#Fragment', { action: 'edit' } );
+ href = util.getUrl( '#Fragment', { action: 'edit' } );
assert.equal( href, '/w/index.php?action=edit#Fragment', 'epmty title with query string and fragment' );
- href = mw.util.getUrl( 'Foo:Sandbox \xC4#Fragment \xC4', { action: 'edit' } );
+ href = util.getUrl( 'Foo:Sandbox \xC4#Fragment \xC4', { action: 'edit' } );
assert.equal( href, '/w/index.php?title=Foo:Sandbox_%C3%84&action=edit#Fragment_.C3.84', 'title with query string, fragment, and special characters' );
- href = mw.util.getUrl( 'Foo:%23#Fragment', { action: 'edit' } );
+ href = util.getUrl( 'Foo:%23#Fragment', { action: 'edit' } );
assert.equal( href, '/w/index.php?title=Foo:%2523&action=edit#Fragment', 'title containing %23 (#), fragment, and a query string' );
- href = mw.util.getUrl( '#+&=:;@$-_.!*/[]<>\'§', { action: 'edit' } );
+ href = util.getUrl( '#+&=:;@$-_.!*/[]<>\'§', { action: 'edit' } );
assert.equal( href, '/w/index.php?action=edit#.2B.26.3D:.3B.40.24-_..21.2A.2F.5B.5D.3C.3E.27.C2.A7', 'fragment with various characters' );
} );
wgScriptPath: '/w'
} );
- assert.equal( mw.util.wikiScript(), mw.config.get( 'wgScript' ),
+ assert.equal( util.wikiScript(), mw.config.get( 'wgScript' ),
'wikiScript() returns wgScript'
);
- assert.equal( mw.util.wikiScript( 'index' ), mw.config.get( 'wgScript' ),
+ assert.equal( util.wikiScript( 'index' ), mw.config.get( 'wgScript' ),
'wikiScript( index ) returns wgScript'
);
- assert.equal( mw.util.wikiScript( 'load' ), mw.config.get( 'wgLoadScript' ),
+ assert.equal( util.wikiScript( 'load' ), mw.config.get( 'wgLoadScript' ),
'wikiScript( load ) returns wgLoadScript'
);
- assert.equal( mw.util.wikiScript( 'api' ), '/w/api.php', 'API path' );
+ assert.equal( util.wikiScript( 'api' ), '/w/api.php', 'API path' );
} );
QUnit.test( 'addCSS', function ( assert ) {
var $el, style;
$el = $( '<div>' ).attr( 'id', 'mw-addcsstest' ).appendTo( '#qunit-fixture' );
- style = mw.util.addCSS( '#mw-addcsstest { visibility: hidden; }' );
+ style = util.addCSS( '#mw-addcsstest { visibility: hidden; }' );
assert.equal( typeof style, 'object', 'addCSS returned an object' );
assert.strictEqual( style.disabled, false, 'property "disabled" is available and set to false' );
var url;
url = 'http://example.org/?foo=wrong&foo=right#&foo=bad';
- assert.equal( mw.util.getParamValue( 'foo', url ), 'right', 'Use latest one, ignore hash' );
- assert.strictEqual( mw.util.getParamValue( 'bar', url ), null, 'Return null when not found' );
+ assert.equal( util.getParamValue( 'foo', url ), 'right', 'Use latest one, ignore hash' );
+ assert.strictEqual( util.getParamValue( 'bar', url ), null, 'Return null when not found' );
url = 'http://example.org/#&foo=bad';
- assert.strictEqual( mw.util.getParamValue( 'foo', url ), null, 'Ignore hash if param is not in querystring but in hash (T29427)' );
+ assert.strictEqual( util.getParamValue( 'foo', url ), null, 'Ignore hash if param is not in querystring but in hash (T29427)' );
url = 'example.org?' + $.param( { TEST: 'a b+c' } );
- assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c', 'T32441: getParamValue must understand "+" encoding of space' );
+ assert.strictEqual( util.getParamValue( 'TEST', url ), 'a b+c', 'T32441: getParamValue must understand "+" encoding of space' );
url = 'example.org?' + $.param( { TEST: 'a b+c d' } ); // check for sloppy code from r95332 :)
- assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c d', 'T32441: getParamValue must understand "+" encoding of space (multiple spaces)' );
+ assert.strictEqual( util.getParamValue( 'TEST', url ), 'a b+c d', 'T32441: getParamValue must understand "+" encoding of space (multiple spaces)' );
} );
QUnit.test( '$content', function ( assert ) {
- assert.ok( mw.util.$content instanceof jQuery, 'mw.util.$content instance of jQuery' );
- assert.strictEqual( mw.util.$content.length, 1, 'mw.util.$content must have length of 1' );
+ assert.ok( util.$content instanceof jQuery, 'mw.util.$content instance of jQuery' );
+ assert.strictEqual( util.$content.length, 1, 'mw.util.$content must have length of 1' );
} );
/**
$( '#qunit-fixture' ).append( pTestTb, pCustom, vectorTabs );
- tbRL = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/ResourceLoader',
+ tbRL = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/ResourceLoader',
'ResourceLoader', 't-rl', 'More info about ResourceLoader on MediaWiki.org ', 'l'
);
assert.ok( tbRL && tbRL.nodeType, 'addPortletLink returns a DOM Node' );
- tbMW = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/',
+ tbMW = util.addPortletLink( 'p-test-tb', '//mediawiki.org/',
'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org', 'm', tbRL );
$tbMW = $( tbMW );
assert.equal( $tbMW.closest( '.portlet' ).attr( 'id' ), 'p-test-tb', 'Link was inserted within correct portlet' );
assert.strictEqual( $tbMW.next()[ 0 ], tbRL, 'Link is in the correct position (nextnode as Node object)' );
- cuQuux = mw.util.addPortletLink( 'p-test-custom', '#', 'Quux', null, 'Example [shift-x]', 'q' );
+ cuQuux = util.addPortletLink( 'p-test-custom', '#', 'Quux', null, 'Example [shift-x]', 'q' );
$cuQuux = $( cuQuux );
assert.equal( $cuQuux.find( 'a' ).attr( 'title' ), 'Example [test-q]', 'Existing accesskey is stripped and updated' );
'addPortletLink did not add the item to all <ul> elements in the portlet (T37082)'
);
- tbRLDM = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
+ tbRLDM = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
'Default modules', 't-rldm', 'List of all default modules ', 'd', '#t-rl' );
assert.strictEqual( $( tbRLDM ).next()[ 0 ], tbRL, 'Link is in the correct position (CSS selector as nextnode)' );
- caFoo = mw.util.addPortletLink( 'p-test-views', '#', 'Foo' );
+ caFoo = util.addPortletLink( 'p-test-views', '#', 'Foo' );
assert.strictEqual( $tbMW.find( 'span' ).length, 0, 'No <span> element should be added for porlets without vectorTabs class.' );
assert.strictEqual( $( caFoo ).find( 'span' ).length, 1, 'A <span> element should be added for porlets with vectorTabs class.' );
- addedAfter = mw.util.addPortletLink( 'p-test-tb', '#', 'After foo', 'post-foo', 'After foo', null, $( tbRL ) );
+ addedAfter = util.addPortletLink( 'p-test-tb', '#', 'After foo', 'post-foo', 'After foo', null, $( tbRL ) );
assert.strictEqual( $( addedAfter ).next()[ 0 ], tbRL, 'Link is in the correct position (jQuery object as nextnode)' );
// test case - nonexistent id as next node
- tbRLDMnonexistentid = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
+ tbRLDMnonexistentid = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
'Default modules', 't-rldm-nonexistent', 'List of all default modules ', 'd', '#t-rl-nonexistent' );
assert.equal( tbRLDMnonexistentid, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode non-matching CSS selector)' );
// test case - empty jquery object as next node
- tbRLDMemptyjquery = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
+ tbRLDMemptyjquery = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
'Default modules', 't-rldm-empty-jquery', 'List of all default modules ', 'd', $( '#t-rl-nonexistent' ) );
assert.equal( tbRLDMemptyjquery, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode as empty jQuery object)' );
} );
QUnit.test( 'validateEmail', function ( assert ) {
- assert.strictEqual( mw.util.validateEmail( '' ), null, 'Should return null for empty string ' );
- assert.strictEqual( mw.util.validateEmail( 'user@localhost' ), true, 'Return true for a valid e-mail address' );
+ assert.strictEqual( util.validateEmail( '' ), null, 'Should return null for empty string ' );
+ assert.strictEqual( util.validateEmail( 'user@localhost' ), true, 'Return true for a valid e-mail address' );
// testEmailWithCommasAreInvalids
- assert.strictEqual( mw.util.validateEmail( 'user,foo@example.org' ), false, 'Emails with commas are invalid' );
- assert.strictEqual( mw.util.validateEmail( 'userfoo@ex,ample.org' ), false, 'Emails with commas are invalid' );
+ assert.strictEqual( util.validateEmail( 'user,foo@example.org' ), false, 'Emails with commas are invalid' );
+ assert.strictEqual( util.validateEmail( 'userfoo@ex,ample.org' ), false, 'Emails with commas are invalid' );
// testEmailWithHyphens
- assert.strictEqual( mw.util.validateEmail( 'user-foo@example.org' ), true, 'Emails may contain a hyphen' );
- assert.strictEqual( mw.util.validateEmail( 'userfoo@ex-ample.org' ), true, 'Emails may contain a hyphen' );
+ assert.strictEqual( util.validateEmail( 'user-foo@example.org' ), true, 'Emails may contain a hyphen' );
+ assert.strictEqual( util.validateEmail( 'userfoo@ex-ample.org' ), true, 'Emails may contain a hyphen' );
} );
QUnit.test( 'isIPv6Address', function ( assert ) {
$.each( IPV6_CASES, function ( i, ipCase ) {
- assert.strictEqual( mw.util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
+ assert.strictEqual( util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
} );
} );
QUnit.test( 'isIPv4Address', function ( assert ) {
$.each( IPV4_CASES, function ( i, ipCase ) {
- assert.strictEqual( mw.util.isIPv4Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
+ assert.strictEqual( util.isIPv4Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
} );
} );
QUnit.test( 'isIPAddress', function ( assert ) {
$.each( IPV4_CASES, function ( i, ipCase ) {
- assert.strictEqual( mw.util.isIPv4Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
+ assert.strictEqual( util.isIPv4Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
} );
$.each( IPV6_CASES, function ( i, ipCase ) {
- assert.strictEqual( mw.util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
+ assert.strictEqual( util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
} );
} );
}( mediaWiki, jQuery ) );
-/* eslint no-undef: "error"*/
-/* eslint-env node*/
+/* eslint no-undef: "error" */
+/* eslint-env node */
'use strict';
var merge = require( 'deepmerge' ),
wdioConf = require( './wdio.conf.js' );
/* eslint comma-dangle: 0 */
-/* eslint no-undef: "error"*/
+/* eslint no-undef: "error" */
/* eslint no-console: 0 */
-/* eslint-env node*/
+/* eslint-env node */
'use strict';
const path = require( 'path' );